I must be missing something because I don't see how this is an advance over anything. You have a FREE function, so use-after-free at runtime is still possible. Why not just have malloc and free together then, and program in C but without any lexical scoping so that "Look ma no garbage"?
[edit]
I see why C without scoping would still produce garbage:
int* foo = malloc(sizeof(int));
foo = null;
Linear Lisp forces you to clean up memory. It doesn't allow complex data structures to be assigned to variables without moving the existing contents of those variables elsewhere where they can be disposed of later.
I don't know about Linear Lisp, but if you do linear types as in Wadler's "Linear Types Can Change the World"[0] then the absence of the call to free would be a compilation error.
1. When you call free matters - it does something after all!
2. You can build abstractions that call free for you. The common withX callback-style function can be better typed with linear types and call free for you, for instance.
The original situation (malloc gives you a linear variable) handles what you want. A function that takes the variable but does not return it effectively "takes ownership of it" and the type system will force a free.
There's a "Linear Constraints" paper draft out there that emulates ownership and borrowing with linear types, and uses the titular new language feature to greatly improve ergonomics.
Isn't that exactly why Rust needs lifetime annotation and Drop trait implementations? How could you achieve the same result without that, or without a garbage collector alternatively?
Well, sort of - it adds overhead, though in the form of an extra byte/object and an extra CPU cycle when objects are allocated/deallocated to check/update the reference counts, rather than the lag spikes tracing GCs are known for.
PUSH is just an alias for CONS, useful for emphasising that you're working with a stack.
The free list holds all the cons cells not in use. Note that in this machine, there is no way to create or destroy cons cells - that's the whole point! Rather, when you need to cons some values, you pull a cell off the free list and populate it (see the implementation of CONS), and when you want to throw a cons cell away, you put it back on the free list (see the implementations of POP and FREE).
The main difference, in Common Lisp at least, is that push modifies the list to add the new cell. Cons returns a new list with the cell added so the old list remains untouched.
Lively Linear Lisp – 'Look Ma, No Garbage' (1992) - https://news.ycombinator.com/item?id=20369522 - July 2019 (39 comments)
Lively Linear Lisp – 'Look Ma, No Garbage' (1991) - https://news.ycombinator.com/item?id=14248419 - May 2017 (18 comments)