Zero Feet: a proposal for a systems-free Lisp
applied-langua.ge
applied-langua.ge
[1] https://dotat.at/@/2007-04-16-awash-in-a-c-of-objects.html
Scheme48 was based on itself as a bootstrap language, with the restriction that only those closures that could be stack allocated were allowed. This restricted Scheme the implementors called Prescheme and it was pretty readable.
Indeed ZF relies on stack allocation, but this is done "optimistically" and for all code.
I'm just wondering...with modern CPUs, isn't this just a version of subroutine threading [1] that doesn't take advantage of modern pipelined CPU hardware and also blows up instruction caches? Why not go for subroutine threading?
[1] https://en.wikipedia.org/wiki/Threaded_code#Subroutine_threa...
I would agree that CLISP bytecode would be heavier; this approach ("template compiler"?) has been used as a baseline JIT in e.g. Jalepeño for the JVM with some success, but being a baseline JIT it is not intended to be that fast either.
Putting aside the considerable differences between Pascal/Modula/Oberon era languages and those of today, the primary purpose of any compiler has not changed: it is to read a source language, analyze it and produce executable machine code.
There's no need to write things like this in the current decade. LuaJIT has been able to provide comparable performance to the implementation language, in important cases, since 2.0.
It achieves this with a very different philosophy to what's being proposed here, one which in fact requires considerable assembler for each instruction set.
It's certainly not the only way to get the job done, other comments have pointed to the various ways Scheme has tackled this problem.
What isn't the case is that implementing a runtime for an interpreted language in a 'systems language' requires that code written in the interpreted language be slower than comparable code in the systems language, let alone that a "very large difference in performance" is inherent to the approach.
Edit: perhaps this is about missing the word "primarily", that performance in such an implementation is bound by interpretation speed.
These are the two requirements of the sentence I quoted.
There's no need for the Zero Feet proposal to say something untrue to justify their approach. I'm not imputing malice because I see none, but moderating that sentence or just removing it would strengthen their case.
HotSpot also uses an interpreter, but its performance comes from the C2 compiler, for example. Quoth Cliff Click [1]:
> if you are spending any amount of time beyond e.g. 5% in the interpreter / stage-0 JIT you need to adjust your JIT'ing strategy. Not saying "no-gain" in a stage-0-only, but definitely should not be a super high payoff if there's a stage-1 following you.
[1] https://old.reddit.com/r/Compilers/comments/sae1iy/compiler_...
I don’t think the fact that jit compilers exist makes this sentence about interpreters untrue.
return args().skip(1).next().unwrap().length();
EDIT: a Lisp transpiling to Rust would have to figure out for every function call whether it's a standard function call or a method call. (-> (args)
(skip 1)
(next)
(unwrap)
(length))
I really do think that for long "Java-esque" chains like this, Clojure has the right idea, I think it's very readable.This isn't really related to the Lisp to Rust transpiling thing though.
And I agree with you that that S-expression notation is very readable, at least for us who are used to putting the parentheses in the correct spot.
You could use slightly different syntax, such as (foo x) versus (.foo x).