Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Crystal's Interpreter (2021) (crystal-lang.org)
93 points by philonoist on June 26, 2022 | hide | past | favorite | 24 comments


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.


> where an interpreter is used for the outer loop and a compiler for the inner loop

That's just a standard JIT isn't it?

Also - note there are multiple ways to automatically make a compiler from an interpreter, so really you just need the interpreter.


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.


Yeah RPython and Truffle/Graal are the two major implementations of this idea today.

https://www3.hhu.de/stups/downloads/pdf/BoCuFiRi09_246.pdf

https://chrisseaton.com/truffleruby/pldi17-truffle/pldi17-tr...


ChakraCore, the former JavaScript engine of Microsoft's Edge browser, has in its repo a decent high-level description of how its JIT compilation is integrated: https://github.com/chakra-core/ChakraCore/wiki/Architecture-...

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.


Some jits have a very cheap baseline compiler. This is nice vs the interpreter because you don't need to worry about abi.


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


> The runtime performance of crystal executables are great, of course, comparable with C or C++ in the given web development domain

I don't think that's true. Crystal seems to be more in the ballpark of Go or Java:https://www.techempower.com/benchmarks/


Isn't that the same ballpark?


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

https://programming-language-benchmarks.vercel.app/crystal-v...


That's an incredible achievement for Crystal given how high-level that language is. But you're right technically of course.


You mean a JIT? Or are you talking about something else, like some sort of hybrid interpreter/AOT compilation?


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


Why the past tense? That capability is very much still present in modern implementations.


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.


This is pretty great, and provides the biggest thing I miss in Crystal's functionality compared to Ruby. (that is, a IRB-like REPL).


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.

It's called ICR: Interactive Crystal

https://github.com/crystal-community/icr

the first release was back in 2017


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.


A REPL is definitely *not* allowed to silently rerun the previous commands in any circumstances.


I couldn't easily find any info about the interpreter being available from the binary releases? Since this is from 2021, is it already available?


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

    docker run --rm -it crystallang/crystal:1.4.1-alpine 
    
    / # crystal i
    Crystal was compiled without interpreter support
    
    / # crystal eval '3.times { |i| puts "Hello #{i}" }'
    Hello 0
    Hello 1
    Hello 2
    
    / # crystal eval 'require "http/client"; puts HTTP::Client.get("https://news.ycombinator.com/").body.split("\n").first'
    <html lang="en" op="news"><head><meta name="referrer" content="origin"><meta name="viewport" content="width=device-width, initial-scale=1.0"><link rel="stylesheet" type="text/css" href="news.css?E6T8vRgACsBJvJjCXAU8">
I tried the non-alpine package as well. No dice.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: