# Lisp

*I don't know Lisp, but I'm going to write one anyways*

(this unit doesn't exist yet)

I read about Lisp this evening in a bit more details than my past attempts. I
think I have an idea of what this language is about. I'm going to add an
implementation in Dusk.

I took a look at the "Make a Lisp" project, but I don't like it. Their process
seem to want to nudge me in needless complexity.

Moreover, what I have in mind is more interesting than your run-of-the-mill
read-eval-print loop. My ideas so far:

* Functions are compiled through HAL
  * The means the resulting code will be very fast
  * I think it's also simpler than holding in memory all the information
    necessary to interpret the functions
  * "environments" don't need to be kept once the function is compiled
  * compiling run-time outer-but-not-global-scope bindings will be a challenge.
    But I think I'll be able to manage something good.
* There will be good interop with the Dusk system
  * Forth words can be called from Lisp. All arguments need to be atoms though.
  * Lisp words can be called from Forth normally, but this means that Lists will
    need to have a good Forth API so that Lisp functions can actually be useful.
  * I'm not sure what to do about "set" interop yet. Maybe no interop because
    lists are a problem.

## Lists and memory management

Theoretically, lists require garbage collection. But because the information we
manage aren't opaque blobs, but rather known structures, maybe we can devise
something simpler? Here's an idea:

* Lists all live in two big pools of static memory.
* One pool at a time is "active". There's a pointer pointing to the active pool.
* Lists are linked lists with one 4b data field. Each list element is thus 8b.
* References to lists live in special "values", which could be called "list".
* These "list" references are the "bag holder". Any LL link in the pool not
  ultimately referenced by one of the "list" can be cleared.
* There's a pointer to free memory that grows up as memory is needed.
* When that pointer reaches the end of the pool, we call "cleanlist".
* That word goes through all the "lists" holder, copy every of those lists from
  one pool to the other, the switch the "active pool".
* This effectively defragments memory and free unreferenced lists.
* If our pointer is still at the end of the pool after that, we're out of
  memory.
* To allow multi-head LL references to correctly copy themselves from pool to
  pool, we set the "next" field of links we copy to -1 as we progress, with the
  data field being set to a link in the new pool.

