_________________________________________________

           EARLY IDEAS: A MODERN LISP MACHINE FROM SCRATCH

                              Alchemist
                          [email protected]
          _________________________________________________


                             Sep 15, 2018





Introduction
============

 I am often fascinated by old tech.

 While I do not have the experience nor the expertise on the subject,
 in the last months, some very specific stuff has caught my eye, and
 those are the Lisp Machines.

 I've been using Common Lisp for about three years and a half and,
 though only now I began to make cool stuff using the language, the
 fact that it is not very used bothers me a lot. I mean, of course, it
 is not something as welcoming in terms of first impression. Lisp is
 known for its overwhelming parentheses, which often hide the true
 power of the language.

 But this bad first impression cloaks the possibilities of a mature
 language such as Common Lisp, of Lisps in general, and of specialized
 hardware and systems, built to ensure performance on Lisp execution.

 On this post, I try to present very early ideas in a project of a new,
 modern Lisp Machine of sorts; one which might have the potential to
 make true hackers feel at home with the idea of running a highly
 customizable, but also efficient Unix-like system built to run Lisp on
 specialized, modern hardware.


Lisp Machines
=============

 Lisp Machines were computers specially designed to run Lisp code
 efficiently.  This is justified by the way the language works: Lisp
 stands for "List Processor". Since Lisps stand over heavy usage of
 list data structures, it is only natural that someone would want
 fine-tuned hardware to deal with those, so these machines carefully
 reduced execution costs with specific hardware, CPU instructions, and
 specific memory management.

 The [Lisp Machines] rose inside the MIT AI labs, which gave birth to
 its first forms, only to pretty much die after the fall of Symbolics,
 the company bred from the same labs, which produced them commercially,
 leaving a legacy and orphaned lispers who are still waiting for Lisp
 Machines to rise once again.  The original Lisp Machines, as I was
 told, were built using processors with reduced instruction sets
 ([RISC]), and a very specific way to manage memory.

 This whole story bothered me to the point which I though I should try
 building one, from scratch, since RISC processors seem to be rising
 once again (a little more on that later in this post). It is old
 stuff, but it seems interesting, given that it pretty much operates
 different than the way modern computers do.  But it also needed to be
 something that I would be able to use, and enjoy using.  And it might
 even serve as base for next projects, which I will explain in the
 following paragraphs.

 However, this "Lisp Machine" I intend to build is not the first
 example of what a fully-functional computer running an OS built using
 Lisp in the present days could be.  [Lukas F. Hartmann already built
 something like this for the Raspberry Pi 2], pretty much in the model
 which I want to follow: the resulting experiment is a board, attached
 to a custom-made keyboard. Interim OS (as the operational system is
 called) is a full-fledged Lisp system, running its own dialect (do not
 confuse with the recent [Interim Lisp], which is a low-level Lisp with
 compile-time memory management, much like Rust language). This OS also
 has the interesting aspect of having been inspired by [Plan 9], the
 operational system which is the true spiritual successor to the
 original Unix.


[Lisp Machines] https://en.wikipedia.org/wiki/Lisp_machine

[RISC] https://en.wikipedia.org/wiki/Reduced_instruction_set_computer

[Lukas F. Hartmann already built something like this for the Raspberry
Pi 2]
https://hackaday.com/2015/09/23/old-lisp-languaged-used-for-new-raspberry-pi-os/

[Interim Lisp] https://github.com/eudoxia0/interim

[Plan 9] https://9p.io/plan9/

Hardware optimizations
~~~~~~~~~~~~~~~~~~~~~~

 My main concern is about the kind of hardware-level optimizations that
 such an operational system, built using Lisp, might
 require. Therefore, I have decided that I should go ahead and try
 building custom instructions atop a flexible architecture which would
 allow me to do so. And this is where the plain new RISC-V architecture
 comes in -- praised by media, open, hackable, exactly what I want. And
 this is what would set it apart: While Interim OS is an awesome
 project, it is built for ARM processors, therefore it is stuck to the
 ARM instruction set. With RISC-V, not only could those instructions be
 extended, but it would also be didatic enough so that hackers with
 sufficient knowledge could mess with.


System architecture
===================

 For the user experience, my intention is to create a Unix-like
 environment, though I do not intend to follow POSIX, not even
 remotely. The user would be presented with what seems to be a Unix
 environment, mimicking Plan 9 as best as possible -- this does not
 only mean good old Unix experience, but also possibly [9p
 integration], so that building clusters could also be possible with
 ease.

 The system, of course, would also have openness and simplicity in its
 code as fundaments. Files can be precompiled (though I still need to
 give it careful thinking, since I do not want to replicate the old MIT
 LispM's and [Mezzano]'s mistake of taking hours to boot for the first
 time -- the former one requiring such big time every day; this goal
 also implies simplicity on kernel development itself), though hacking
 them should be easy: if you want to change anything, just go ahead and
 change the source code, then recompile the file, or even only the
 form. This would allow not only the experience of live debugging while
 running the code (given that I also implement something as powerful as
 Common Lisp's conditions and [SBCL]'s debugger), but would also make
 possible to create a fun environment in which I may bootstrap the
 whole system while I'm running it! Just imagine developing a kernel
 atop itself.

 I was thinking about implementing these using some kind of layer. The
 very base of the system would be [implemented in Forth], which could
 be implemented directly using RISC-V assembly, with minimal extra
 words for its dictionary, which harness the power of the custom
 processor instructions that are required for the Lisp Machine. From
 Forth, we may then bootstrap a basic Lisp interpreter; and from the
 interpreter, we bootstrap the rest of the system.  I am not entirely
 sure what to make of the dialect which should be implemented itself,
 but I'm almost certain that it will be a subset of Common Lisp, which
 I believe is the descendant of the dialects used on old Lisp
 Machines. I am not naive enough to think that I will be able to
 implement Common Lisp on this system with so much to do already, but
 the intention is to leave the dialect itself somewhat open, so the
 features of Common Lisp may be slowly implemented as needed.

 I'm also thinking carefully on what to do about concurrency on this
 new system.  Some folks once told me that the problem with praised
 systems languages such as C and C++ is that they still make you
 pretend that you're programming on a machine which works like a
 [PDP-11], something that is not justifiable given the current state of
 industry. While I like C and C++, I cannot find a counter-argument,
 therefore it is probably important that I take it seriously from the
 beginning of system development, even though the first implementation
 might be built atop a 1-core RISC-V processor. For that reason, I am
 carefully looking into the topic of coroutines, and this might even
 imply a scheduler for the system to make those work, and possibly take
 advantage of the processor as much as it can, according to its number
 of cores.


[9p integration] https://en.wikipedia.org/wiki/9P_(protocol)

[Mezzano] https://github.com/froggey/Mezzano

[SBCL] http://www.sbcl.org/

[implemented in Forth]
https://en.wikipedia.org/wiki/Forth_(programming_language)

[PDP-11] https://en.wikipedia.org/wiki/PDP-11


Extensibility and hackability
=============================

 Another interesting thing which I'm giving a lot of thought is the
 ability to change dialects and paradigms in a per-app basis. Of course
 there would be a common interface for inter-application communication,
 but imagine a single directive which, when evaluated, changes the
 interpreter only for that application so you can write it in, say,
 Clojure, for example (minus all the Java bloat, of course!). This
 might even be a way to enforce functional principles such as
 immutability to enhance performance even more on certain situations.

 We would also need a basic text editor in order for all of this to
 happen.  For that, the intention is to implement a small variation of
 Emacs or Zmacs editors, so that coding is made simpler. Scripting
 language would need to be the system's own dialect, although maybe
 Emacs Lisp support could be implemented using the idea from the last
 paragraph.


Graphical interface
===================

 Finally, as for GUI applications, Common Lisp has the fantastic
 [CLIM], which is very underrated and has a lot of good
 principles. CLIM could be implemented using the system's dialect, and
 then GUI applications could be created using it, much like someone
 would do with Qt on any platform, for example.


[CLIM] https://en.wikipedia.org/wiki/Common_Lisp_Interface_Manager


Internet
========

 I've been discussing a lot with friends about the possibility of "web"
 pages built using S-expressions instead of HTML itself. This would
 probably be a huge break in the way a browser works, however this
 might be just perfect for a system running Lisp as its main language,
 since the page itself is already arranged as a tree. It would also be
 interesting to allow that same idea of changing dialects for a
 scripting language on those pages, however I would opt to sandbox Lisp
 web scripts like this so they cannot manipulate many things, while
 also using the system interpreter itself to optimize the execution of
 said scripts. With such a feature, the webpages are but lists of
 lists, and scripts could be external files written in Scheme, for
 example, or even lambdas attached directly into the document tree.

 Another interesting feature would be to support a dialect of
 WebAssembly of sorts which could compile to machine code directly,
 just like a Lisp file would. This way, the script's safety could be
 enforced before compilation, and then the page script could take full
 advantage of the system's native performance.


Conclusion
==========

 Those are ideas for something that has proven difficult to do,
 specially given the fact that I lack a lot of experience and knowledge
 in most of the things I have described above. Most of the difficult
 would be on actually learning the RISC-V low-level stuff to even begin
 building such a system; and then, implementing Forth using nothing but
 assembly, which will also be a pain; then finally, implementing Lisp
 atop Forth, which might also be a huge problem.  Plus, the whole
 system and kernel is another big effort that will take much more time,
 and having a minimal environment for me to have fun bootstrapping the
 system as suggested (which would be crucial so I don't get bored)
 would also require that Emacs/Zmacs clone to work well.

 This is a huge project comprised, right now, mostly of ideas I've been
 maturing on the last months, and discussing with friends over the
 internet. I'm already collecting books and articles on all of those
 subjects to read in my free time, but I know it is gonna take
 time. However, it would be really nice to see this stuff working,
 specially if the community could make good use of it.