16 comments

[ 2.9 ms ] story [ 37.3 ms ] thread
Amazing, and you could see how this could be translated into perhaps a couple of thousand lines of assembly code to boostrap Scheme almost from the bare metal, similar to the early IBM 709 LISP.

A thought: I wonder if an LLM would be up to the job of writing the assembly code from this?

If your Scheme were a native compiler rather than an interpreter (i.e. like Chez) and written in (a constrained subset of) Scheme, then you could use an itty-bitty Scheme interpreter written like this to bootstrap the core of your native Scheme compiler so that the interpreted version of it could compile itself to native binary.

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.

I believe MIT Scheme compiled directly to C by intermingling switch statements and gotos to emulate its call stack. Problem was, as programs grew, compile times weren't linear. I gave it a shot once, it was a somewhat spiritual experience:

https://github.com/glouw/switch

Instead of representing atoms as string literals, you can represent them as global variables, eg

    const char conti[] = "conti";
Then you can use pointer comparison instead of strcmp().
Kent Dybvig also wrote Chez Scheme [1] which on most benchmarks is far-and-away the fastest [2] Scheme implementation.

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...

Since these seems to be turning into an opportunity to shout out for other Scheme implementations...

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.

Shout out to Mr. Dybvig who taught our intro to CS course at IU Bloomington 20+ years ago! It was my first intro to recursion (of course the class was all scheme based) and gave me much more confidence in software development coming from a self taught background.
I took his Compilers class about 30 years ago. I really wish I still had those notes.
Have you tested this? Does it work?
Can someone give more info on the relevance of this particular code?
What an utterly delightful itty bitty scheme. <3
> note! repl implies there's a top-level but there isn't...

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.
No matter what I try, I always get:

heap-lisp: heap-lisp.c:99: cons: Assertion `istext(textptr)' failed.

I wonder if the ptr comparison in istext is actually UB?

If textptr is not an element of the text array, then it's undefined.