Racket recently got rewritten to be based off of Chez [3] and I have it from the maintainer of Racket himself that it’s paid off well: better performance and a smaller, more maintainable codebase.
1: https://github.com/cisco/ChezScheme (also, pronounced “Shay Scheme”)
2: https://ecraven.github.io/r7rs-benchmarks/
3: https://m.youtube.com/watch?v=s3Q3M2wZ7rI&pp=0gcJCRsBo7VqN5t...
(MIT Scheme also has a native code compiler for Intel CPUs, which seems to be what most users of MIT Scheme (an admittedly small community) actually use.)
I believe MIT-scheme took it a step further with gnu extensions which allowed you to take the address of a label like &&label, which allowed for function pointers: https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
https://www.gnu.org/software/mit-scheme/documentation/stable...
The release notes from long ago when that back end was released are here, and give some detail:
MIT Scheme was for a long period one of the leading Scheme implementations. It lacks support for Apple Silicon, so it is not as popular now, as it once was.
sudo chicken-install srfi-203
sudo chicken-install srfi-216
At ~/.csirc put: (import scheme)
(import (srfi 203))
(import (srfi 216))
Now you can do nearly all the execises.I was a happy use of VSCM by Matthias Blume, doing a bunch of my university assignments with it on my Linux PC in the early 90s.
A thought: I wonder if an LLM would be up to the job of writing the assembly code from this?
(sans LLMs -- I believe they have a Scheme (GNU Mes) that can be compiled from their 357 byte bootloader, and that Scheme can run a C compiler that can compile tinycc, and I think there's a path from tinycc to compiling gcc. I'm not sure how far it can get after that -- this blog post[1] implies that you still need a binary of guile to run Gash, which is a POSIX shell written in Scheme. I'm guessing the plan is to either simplify Gash or complexify Mes to be able to remove Guile as a dependency.
[1] https://guix.gnu.org/en/blog/2023/the-full-source-bootstrap-...
Before there were LLMs, there were about 65 years of other program-writing-programs to save labor.
LLMs do not replace program-writing-programs; they should be used to work with program-writing-programs, not as a replacement.
E.g. I wouldn't use an LLM to convert a grammar to LR parsing tables, but perhaps to get help with the grammar file.
gcc -S heap-lisp.c
Given that this was the path that one of Dr. Dybvig's post-doc acolytes, Dr. Michael Ashley, taught us in his Scheme-based compiler class, I must guess that this was also Kent's path and that that was the intent for this little interpreter. I suppose I should (finally) take the time to read his dissertation.
From what I've seen the LLM do it can definitely enhance these programs if you know what to ask, and it can explain how any piece this code works. It may even be able to add garbage collection to the evaluator since the root registers are explicit, and the evaluator only acts on static memory.
I could see a compiler doing that.
Why ask a cluster of GPU's to do something any single CPU from the last 30 years can accomplish?
I'm a little confused. How could it not have a top-level environment? There are environments which are extended on function application by consing lists of variables and their values onto the old environment.
void* extend(void* env, void* vars, void* vals) {
return cons(cons(vars, vals), env);
}
This implies a root environment whose cdr is nil. const char conti[] = "conti";
Then you can use pointer comparison instead of strcmp().You may be thinking about how `eq?` (reference equality) works in scheme. That's usually done by hashing the identifier string. Which is the more general solution to this equality problem.
It gives virtmach lisp and scheme different ontology, but I can't think of any practical reason why that would matter other than it makes things a little bit more complicated. But, then again if I'm thinking practically scheme should be using hashed identifiers, and then there's no reason for them to have different ontology and conceptually we're right back where we started with virtmach lisp and scheme using identifiers as objects.
next = compile(read(buffer), cons("halt", NULL));
C doesn't guarantee the order in which arguments to a function are processed. Since 'cons' relies on 'read' being called first, the result is undefined behavior. (In fact I had to fix that before it would even "run" on my system.)