Functional Programming in Kotlin, Manning book: Arrow code needs update - kotlin

Though this book was just finalized in August, they appear to be using some deprecated Arrow library code in their code examples.
Here's an example from Chapter 6:
Listing 6.18. State propagation using a for-comprehension.
val ns2: State<RNG, List<Int>> =
State.fx(Id.monad()) {
val x: Int = int.bind()
val y: Int = int.bind()
val xs: List<Int> = ints(x).bind()
xs.map { it % y }
}
Using latest Arrow libs, the above snippet fails syntax checker in Idea. 'Id' is not recognized, and Arrow docs say it was slated for deprecation.
Wondering if anyone can help refactor this to current Arrow version, or recommend previous version this will work with?

I was able to contact the authors on this issue.
Currently, there are no updated code examples for the latest Arrow libs, but they may release that in the future.
In the meantime, there is a git repository of the code (Idea project) that works with the older libs. It can be found here: Functional Programming in Kotlin
I've been recreating the exercise files within the project to avoid seeing the answers before I complete the exercises, and it works.

Related

Is there a Kotlin "eval"

I have a bunch of strings like these in my already existing and quit big template file:
Hello $World I say hello to $User, too
I was thinking I could somehow let kotlin parse/search&replace this file as a kotlin string, and I'd just have to set the variables World and User to get an evaluated string... How is this possible?
This is not a kotlin source file, but a file that's beeing read by my kotlin program.
Why I want to do this? I used bash's envsubst before, and had to move away from this, since things were getting too complicated. But now I have no easy way to replace strings in a file anymore...
Thanks
What you want is called a template engine.
You don't really need an eval (which would allow running a full Kotlin application from a String) in this case.
For example, FreeMarker templates use a syntax that's similar to Kotlin template Strings, so a template may look like this:
<h1>Welcome ${user}!</h1>
Then, from Kotlin, you can evaluate the template with a Map holding the template bindings (variables the template can use) like this:
val user = "joe"
val bindings = mapOf("user" to user)
val cfg = new Configuration(Configuration.VERSION_2_3_29)
cfg.directoryForTemplateLoading = File("/where/you/store/templates")
val template = cfg.getTemplate("test.ftlh")
// write the resolved template to stdout
val out = OutputStreamWriter(System.out)
template.process(bindings, out)
See a Java example here: https://freemarker.apache.org/docs/pgui_quickstart_all.html
There are many other template engines, and the KTor site lists a few:
https://ktor.io/docs/working-with-views.html
If you're using KTor, BTW, it makes it much easier to use template engines... your framework may even have similar.
Warning: Please see my other answer first: you probably don't want to run a full Kotlin script just to parse some text file with variables... use a template engine for that.
It's possible to execute Kotlin scripts, i.e. eval Kotlin code, but it requires that you basically ship the Kotlin compiler with your application.
This GitHub project, KtsRunner, for example, does that, so you can do this:
val scriptContent = "5 + 10"
val fromScript: Int = KtsObjectLoader().load<Int>(scriptContent))
println(fromScript)
// >> 15
It requires some hacking though, is very slow and it uses a bunch of Kotlin "internal" APIs to work.
See the full list of libraries this project uses here:
https://github.com/s1monw1/KtsRunner/blob/master/lib/build.gradle.kts#L21
A "proper" KEEP proposal (discussion here) exists to add first-class support for this in Kotlin, but it's not finalized yet.
Currently, it looks something like this:
fun evalFile(scriptFile: File): ResultWithDiagnostics<EvaluationResult> {
val compilationConfiguration = createJvmCompilationConfigurationFromTemplate<MainKtsScript>()
val evaluationConfiguration = createJvmEvaluationConfigurationFromTemplate<MainKtsScript>()
return BasicJvmScriptingHost().eval(scriptFile.toScriptSource(), compilationConfiguration, evaluationConfiguration)
}
But it'll probably change before being released.

Unexpected tokens I'm following a tutorial and we do really the same code but the video was published on 2018

Log.d(tag:"MainActivity", msg:"Email is: " + email)
Log.d(tag:"MainActivity", msg:"Password: $password")
Log.d("MainActivity", "Email is: $email");
Log.d("MainActivity", "Password: $password")
The problem is, that you copied the so-called "Parameter Hints" by IntelliJ.
The parts of your code that end with a double-colon (tag: and msg:) aren't really part of the Kotlin code. Instead, the IDE that the creator of the tutorial was using showed hints for the names of the parameters.
Example
The function
fun add(a: Int, b: Int): Int {
return a + b
}
has two parameters, the first called a and the second called b.
This means when calling this code from IntelliJ, the IDE will show the following hints to the user so that he knows what parameters he is entering:
You can identify these hints by looking at them accurately. They have a different font, are boxed, and have a different background-color. Please note that these hints are not part of the Kotlin code and cannot be written in Kotlin, that's where your Syntax Error comes from.
Have fun learning Kotlin! 👍

Does the kotlin REPL have code completion?

I just opened kotlinc (which apparently defaults to kotlin-jvm ?) and dropped in some hello-world type code:
data class Person(val name: String, val age: Int) {
val isAdult get() = age >= 20
}
Let's create an instance :
val p = Person("ab", 10)
Hopefully the repl will offer us the properties via tab key .. ?
p.<tab>
The repl beeps on each tab instead of offering the properties of that Person instance. "Just in case" I :quit and opened kotlinc-jvm explicitly - and got the same behavior. Is it to be believed that there were no code completion available? Am I missing some option to starting kotlinc ?
Update: JetBrains has now released ki, which supports auto completion (and more).
The kotlin repl currently does not support tab completion. See the official bug tracker for more details:
https://youtrack.jetbrains.com/issue/KT-14177,
https://youtrack.jetbrains.com/issue/KT-23036
If you use IntelliJ, you may want to try out scratch files. They work well for small bits of code and support code completion.
Intellij Kotlin-REPL does have code completion. It makes a ton of sense to use the IDE coming from the creators of the language JetBrains.

Why Can't Kotlin Infer The Type For Comparator

Reading the Java interop document about SAM Conversions, I expected the Kotlin function
Collections.sortWith(comparator: kotlin.Comparator<in T> /* = java.util.Comparator<in T> */)
to be able to take a lambda function without needing to explicitly specify the parameter is a Comparator. However the following code gives type inference failed:
val someNumbers = arrayListOf(1, 5, 2)
someNumbers.sortWith({ x, y -> 1 })
whereas:
val someNumbers = arrayListOf(1, 5, 2)
someNumbers.sortWith(Comparator { x, y -> 1 })
compiles and runs correctly
After reading the comments from the Kotlin issue 'SAM for Kotlin classes' I learned a lot regarding the SAM conversion and why typealias was introduced, but not yet why this specific behaviour wasn't solved yet... and I am not the only one as the issue and its comments show.
Summarizing, the SAM conversion was only considered for Java interfaces (compare also this comment). Jetbrains did work on (or still needs to do) a bigger refactoring and tries to solve that issue so that SAMs are also available for Kotlin functions themselves (compare also this comment). They are trying to support SAM conversion for kotlin functions in a separate issue, which could come with 1.3. As I am currently testing 1.3: I did not see anything regarding this yet. So maybe, if you like the SAM conversion as I do, you may want to upvote either SAM for Kotlin classes or SAM conversion for kotlin function or both.
By the way: a very similar example was also used by Ilya Gorbunov using arrayOf().sort.

Compile and run C code using clang API

I would like to use the clang/llvm APIs to compile a c-function, defined in a string and immediately execute it.
Something like:
void main() {
std::string codestr = "int foo(int bar) { return bar * 2; }"
clang::??? *code = clang::???.compile(codestr);
int result = code->call("foo", 5);
}
I am looking for tutorials, but what I found so far does not quite match my goal or does not work, because it refers to an outdated version of LLVM.
Currently, I am using LLVM 3.5.
Does anyone have a good tutorial at hand?
I followed this blog post with good results. The clang API has changed, so you may have to make adjustments. With LLVM 3.6.1, I got good results with the following code:
llvm::Module* compile(const char* filename) {
clang::CompilerInstance compiler;
clang::CompilerInvocation* invocation = new clang::CompilerInvocation();
llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagID(new clang::DiagnosticIDs());
auto diagOptions = new clang::DiagnosticOptions();
clang::DiagnosticsEngine Diags(DiagID, diagOptions,
new clang::TextDiagnosticPrinter(llvm::errs(), diagOptions));
std::vector<const char *> arguments = {filename};
clang::CompilerInvocation::CreateFromArgs(*invocation,
&*arguments.begin(), &*arguments.end(),
Diags);
compiler.setInvocation(invocation);
compiler.setDiagnostics(new clang::DiagnosticsEngine(DiagID, diagOptions,
new clang::TextDiagnosticPrinter(llvm::errs(), diagOptions)));
std::unique_ptr<clang::CodeGenAction> action(new clang::EmitLLVMOnlyAction());
compiler.ExecuteAction(*action);
std::unique_ptr<llvm::Module> result = action->takeModule();
llvm::errs() << *result;
return result.release();
}
I was very careless with the pointers, so its very possible there's a memory leak or a double free (although it didn't crash).
I couldn't figure out how to take the source from a memory buffer, so I dumped it in a temporary file using mkstemp.
I didn't get around to executing the result, but I think you can follow #michael-haidi's response, or check out the LLVM Kaleidoscope tutorial (This is the JIT chapter).
I recommend using MCJIT because the old JIT infrastructure will be removed in a further release.
I can't point you to a full tutorial and cannot promise that the API hasn't changed since the blog post but here you'll find a guide how to use MCJIT with the Kaleidoscope example from LLVM and thats it. Examples and tutorials are hard to find for LLVM/Clang. However, I suggest trying it and maybe you can document your journey with a short example.
The Julia project also uses MCJIT for jit compilation of C++ code inside of the Julia lang. Maybe you can peek at the code and find out how the use MCJIT.
Good luck ;)