I feel part of the perceived misalignment in discussion here comes from the topic itself being two-pronged. The first is staged compilation à la Racket (or LMS in Scala, etc), which is very cool (thanks for linking the PADL talk, I wonder if there are any parallels to Julia’s abstract interpreter model). The second is about how to separate “fortran-style code” and “lisp/python-style code”, ideally lexically. Though it feels like both concerns are tied together quite nicely, I think it’s valuable to separate out the second one because Julia provides some ways to handle it.
So what does Julia provide? As mentioned above, it’s possible to have fast and slow components of the same codebase by using module-level compiler directives. Implications of --compile=min and --optimize=0, for dummies does a way better job of explaining these than I can, so I’ll just add that most of the options have now been centralized under Base.Experimental.@compiler_options
. Is this as elegant/composable as first-class staged programming? I’d assume not, and the module-level granularity is certainly a limitation. Does it help with the stated end goal of not paying the cost of compilation for very dynamic, not hot code? I think it’s a start, and also ties in with the discussion on JuliaInterpreter because there’s been on-and-off talk about replacing the built-in interpreter with a pure Julia implementation.