
William Byrd on ”The Most Beautiful Program Ever Written” (2017) [video] - lelf
https://www.youtube.com/watch?v=OyfBQmvr2Hc
======
keithnz
Alan Kay said :-

    
    
      (SF) If nothing else, Lisp was carefully defined in terms of Lisp. 
    
      (AK) Yes, that was the big revelation to me when I was in 
      graduate school—when I finally understood that the half
      page of code on the bottom of page 13 of the Lisp 1.5 
      manual was Lisp in itself. These were “Maxwell’s 
      Equations of Software!” This is the whole world of 
      programming in a few lines that I can put my hand over.
    

[https://queue.acm.org/detail.cfm?id=1039523](https://queue.acm.org/detail.cfm?id=1039523)

~~~
WalterGR
Preformatted text on HN is really hard to read on mobile. Reformatted:

 _(SF) If nothing else, Lisp was carefully defined in terms of Lisp._

 _(AK) Yes, that was the big revelation to me when I was in graduate
school—when I finally understood that the half page of code on the bottom of
page 13 of the Lisp 1.5 manual was Lisp in itself. These were “Maxwell’s
Equations of Software!” This is the whole world of programming in a few lines
that I can put my hand over._

Page 13 of that manual is page 21 of this PDF:
[http://www.softwarepreservation.org/projects/LISP/book/LISP%...](http://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Programmers%20Manual.pdf)

------
ncmncm
At great risk of being downvoted to oblivion (before you pile on, check your
motives), this struck me on first encounter, 30 years ago, and ever more
strongly since, as the most self-indulgent of all programs. People impressed
by it invariably appear, primarily, pleased with themselves for the depth of
perception they demonstrate by being impressed with it.

Comparing it to Maxwell's equations sharpens this. The equations are deeply
illuminative of fundametal processes of reality, summarizing comprehensively
and precisely decades of exacting experimentation by the best physicists of
the age. The speed of light (in vacuum, and in any medium) is simply derived
from them. No detail of them could be deduced without abstraction from all the
experience of all who came before.

How much work went into this program? Would any two people, who just knew
Lisp, but no theory of computation, asked to write it, write it differently?
How long could it take? An hour, a week, a month? How much insight would it
take? How much lived experience does it represent?

Think it through: A Lisp interpreter in Lisp. It demonstrates that, if you are
handed a Lisp runtime, as we are today, it is easy to make it execute Lisp
programs. With small changes, it runs slightly different programs.

Should that impress us? Where did this Lisp runtime come from, and why would
one expect it to be tuned for anything but running Lisp programs? If it were
not good for running Lisp programs, what would it be good for?

The program relies, fundamentally, on all the science (and, frankly,
engineering) that came before, but illuminates none of it. It is a fleck of
foam that rides determinedly at the surface, belying the depths that support
it. It illuminates nothing beyond itself.

~~~
kazinator
> _Where did this Lisp runtime come from, and why would one expect it to be
> tuned for anything but running Lisp programs?_

In this case, it's running a program which very itself easily runs Lisp
programs given to it as a source code data structure. That we normally don't
expect. For instance, in C language run-time, though it of course supports
running compiled C programs, it doesn't provide a straightforward way for one
of these programs to itself process C programs. A C program that interprets a
decent subset of C is pretty complicated. It has to provide a number of data
structures, of course a parser (because C programs don't have a data
structural representation) and memory management for the parse time and run-
time and so on. The C-processing C program can't even ask for a function by
name so that it could resolve a function call out to the native run-time. This
is possible with some operating system extensions (dynamic symbols). That just
solves the name resolution problem: then there is the problem of dynamically
constructing the argument list for a function call and executing it. This
requires a library not supplied in the C language such as GNU ffcall, or
libffi. Think about it: a C interpreter for C needs to use a FFI mechanism
(first F == foreign!) to expose the C run time to the interpreted C, and that
FFI is far from a standard language feature. Lisp just resolves a symbol and
calls _apply_ and that's it; nothing is foreign: no visas have to be issued,
no passports are stamped.

~~~
ncmncm
C is an interesting contrast. There is no "C runtime". There is just the
target machine. A C interpreter in C has no advantage over one in any other
language, because every detail of the source language of the interpreter is
washed away in compilation, along with the compiler.

In Lisp, everything is still there. "Resolves a symbol" relies on the runtime.
"Calls apply" relies on the runtime. You don't need to write those, because
you inherited them.

~~~
kazinator
In fact, in a hosted conforming implementation of ISO C, there is a
considerable run-time, but it doesn't have anything useful in it for building
a low-effort C interpreter.

 _apply_ is just a function in Lisp. The host Lisp itself doesn't
(necessarily) use _apply_ for calling functions. When an expression like
_(cons a b)_ in the host Lisp is processed, it's quite likely compiled into
machine code or byte code that doesn't use _apply_.

The hosted interpreter uses _apply_ because it operates at the host Lisp's
run-time; with respect to that host, it's handling function calls by
dynamically constructing lists of evaluated arguments and then having to solve
the problem of applying a list of arguments to a function.

A C run-time could provide _apply_. Libraries exist for this like GNU ffcall,
and libffi. They are low-level, hard to use and error-prone compared to
_apply_.

A C run-time can provide a way to get the addresses of functions also; we can
do this in modern POSIX environments with dlsym, in Win32 with GetProcAddress
and such.

If we put together libffi and dlsym to call a function, and make the slightest
mistake, we have corruption or a crash on our hands. Whereas _apply_ is
robust; we get diagnostics about too many or too few arguments and so on.

If ISO C provided these features, then we could have ISO C "C-in-C" meta-
circular interpreters. They would contain a significant lines-of-code
expenditure compared to Lisp-in-Lisp.

------
kazinator
Lisp in Lisp interpreters actually have a marginal practical use. Suppose
you've boostrapped a Lisp in some other language (assembly, C or whatever).
You have an interpreter in that language, and have written a compiler for that
Lisp in itself (say for a VM in that other language). You can now write an
interpreter for that Lisp in itself. Once that interpreter behaves exactly
like the original one in the other language, you can throw that one away.
Bootstrapping can proceed by shipping the interpreter in compiled form. The
benefit is that there is less language-processing code written in the other
language.

You could just throw the interpreter away and have a compiler only
(bootstrapped with the compiled version of itself), but then it's useful to
have two models of execution for programs.

~~~
bitwize
This is how we got the first working Lisp implementations. John McCarthy
specified Lisp in itself, and a graduate student translated it into IBM 704
assembly.

------
getpost
...Namely, an interpreter for lisp written in lisp. William Byrd learned about
it from Daniel P. Friedman (The Little Lisper, The Little Schemer, ....)

