Repl speed


#1

Today I read about the ammonite shell:

http://lihaoyi.github.io/Ammonite/#Ammonite-Shell

it’s a Scala-based replacement for bash. The big problem: interactive response. Even after the JVM warms up you get a 200-300msec delay on every command.

I know the Kotlin compiler is much faster than the Scala compiler. I wonder, how much faster for this specific use case?

Does anyone know of a Kotlin REPL, any experiments with that, or how fast it might be to compile a single line of code?

By the way, I know there’s a REPL-like thing in the debugger, if I recall correctly it’s actually a Kotlin interpreter (!) because otherwise you can’t do things like access private members. I wonder how complete it is, or how easy to reuse.


#2

Kotlin has a REPL: http://kotlinlang.org/docs/tutorials/command-line.html#running-the-repl

We haven’t compared its performace with other REPLs yet, but you are welcome to try.

> By the way, I know there’s a REPL-like thing in the debugger, if I recall correctly it’s actually a Kotlin interpreter (!) because otherwise you can’t do things like access private members.
No, it is not a Kotlin interpreter, it is a bytecode interpreter (initial isolated version is available here: https://github.com/abreslav/eval4j, it has been significantly improved and merged into the Kotlin repository: https://github.com/JetBrains/kotlin/tree/master/eval4j)


#3

Huh, you're right! How did I miss that?!

Performance seems very good after the first few commands. Easily usable for an interactive shell. I experimented a bit with a little shell.kt bit of code to define ls, pwd etc.

The main issue is that I really want to be able to define global properties like “pwd” but you can’t do that. You can only have inner classes/objects and inner functions. I guess this is due to wrapping the code inside a function in order to compile and execute it.


#4

Ah, I forgot  to mention (guess you know it already though). The Valhalla guys are writing a bytecode interpreter in Java too. They call it the metacircular interpreter. It is capable of handling invokedynamic and other things. Perhaps at some point you could switch to using their work or join forces in some way.

It uses lambdas so it’s Java 8 only though. So, perhaps not, at least not until IntelliJ switches to Java8+ internally.


#5

I'm working on a project that would greatly benefit from being able to run top level instructions, like a Kotlin interpreter would do. Right now, you need to trick Kotlin into running this code at compile time with various tricks, e.g. assigning a val to it:

val p = foo()

which is hacky since we don’t really care about that value p (there are other ways to hack around that but none pretty), while I’d really like it if I could just write

foo()

and have the compiler run it at compile time (e.g. kotlinc -interpret).