It is good to see languages like Crystal and Julia having both a compiler and an interpreter.
I would really like to see a hybrid approach, where an interpreter is used for the outer loop and a compiler for the inner loop. I believe Guile takes this approach by automatically compiling frequently called functions.
What's a good starting point for someone to study that? Specifically going from an interpreter to a compiler automatically. Are there any special considerations before implementing the interpreter? I'm vaguely familiar with RPython which I think delivers on that.
For context: I'm just a hobbyist interested in PLs and want to learn more about JITs, I found Crafting Interpreters super helpful for a lot of foundational knowledge.
I found the source code to be quite readable too, last time I delved into it. Also its command line tool ("ch"), when compiled in debug mode, has loads of options available to show what it's doing internally when it executes a JavaScript program.
Important to note that this is a modality, not the primary way to execute crystal code in production, which remains building a binary executable.
This saves compilation time while developing at the expense of performance.
The runtime performance of crystal executables are great, of course, comparable with C or C++ in the given web development domain, of course, where the Boehm GC isn’t a problem, given the request response cycle and the standard lib http and socket objects, etc
It's close but you do pay a performance cost for garbage collection (with Go, Java, and Crystal all being garbage collected). There are some benchmarks at the following link, but note that many of the examples are hyper-optimized so you should look at the implementations to make sure the results aren't misleading. As an example though if you don't want to click, the nbody benchmark clocks the slowest C++ program at 387ms compared to Crystal at 580ms
old lisp implementations allowed you to freely intermix compiled and interpreted code. it wasn't compiled on demand, each function could independently be compiled AOT. and dynamically replaced with an interpreted or compiled version
sorry - its me thats past tense. didn't want to presume that things are still done that way. fwiw i don't why more environments don't have the same flexibility.
it's had an IRB-like REPL for years. It just wasn't built into the language. Admittedly it was limited compared to IRB but it was more than enough to test out quick ideas.
ICR basically doesn't work the way you would expect it too. Every time you add a line, it re-runs all previous lines, making it quite hard to do REPL-like stuff when some of those lines do something external like DB commands, especially if they are destructive.
meh. I never put db commands in it. i just used it for testing out crystal code ideas. the rerun everything from the beginning wasn't really a problem.
Right but one of the main benefits of a REPL productivity wise is being able to do stuff with your active record models in rails, so this was always a barrier in crystal.
It's not in the official binary releases yet. You'll have to compile your own Crystal via `make interpreter=1` to use it. Instructions here: https://crystal-lang.org/install/from_sources/
Sadly no, the interpreter seems to not be available yet in the official binaries. You may use "crystal eval" for one-off commands (and can use this to, for example, require a local .cr file and call a particular method), but that's certainly not the same as an interpreter. :P
I would really like to see a hybrid approach, where an interpreter is used for the outer loop and a compiler for the inner loop. I believe Guile takes this approach by automatically compiling frequently called functions.