So fun to see this — I worked on 3-Lisp for Brian at PARC back in the early 1980s.
A simple way to state the proposition is: in any language there are things you cannot write in the language itself: they have to be supplied by your interpreter (or the compiler generated code which is “interpreted” by the CPU). For example you can’t write OR because if the first case is true the second case is not evaluated — you can’t write that as a function.
But you know: if you know what your interpreter is written in, what if you could pass some code to it to execute on your behalf? You could write new kinds of control structures (beyond the standard IF, OR, etc).
It has a mathematical elegance and really makes you think about the semantics of programming language execution.
As an analogy, consider o/s systems that let you dynamically load modules into kernel space to do things that aren’t possible in user space (analogy only; don’t try this at home)
That being said, languages pretty much have the same set of control structures: there may really be a finite set of them (interesting philosophical question). Also metasyntactic macros (such as hygienic macros or even Common Lisp macros, C++’s incorrectly-named but powerful constexpr) let you get a lot of the way there. Continuation-passing (call/cc) allows you to implement throw without leaving “user space).
So while I found this work intellectually stimulating, at the end it didn’t seem to add significant expressive power.
show comments
nikita_d
A 3-lisp program is conceptually executed by an interpreter written in 3-lisp that is itself executed by an interpreter written in 3-lisp and so on ad infinitum. This forms an infinite tower of meta-circular interpreters, which can be implemented efficiently.
show comments
lisper
I honestly can't tell if this is intended to be a joke or not.
show comments
asplake
Does this point to improvements that could/should be made to other Lisps?
So fun to see this — I worked on 3-Lisp for Brian at PARC back in the early 1980s.
A simple way to state the proposition is: in any language there are things you cannot write in the language itself: they have to be supplied by your interpreter (or the compiler generated code which is “interpreted” by the CPU). For example you can’t write OR because if the first case is true the second case is not evaluated — you can’t write that as a function.
But you know: if you know what your interpreter is written in, what if you could pass some code to it to execute on your behalf? You could write new kinds of control structures (beyond the standard IF, OR, etc).
It has a mathematical elegance and really makes you think about the semantics of programming language execution.
As an analogy, consider o/s systems that let you dynamically load modules into kernel space to do things that aren’t possible in user space (analogy only; don’t try this at home)
That being said, languages pretty much have the same set of control structures: there may really be a finite set of them (interesting philosophical question). Also metasyntactic macros (such as hygienic macros or even Common Lisp macros, C++’s incorrectly-named but powerful constexpr) let you get a lot of the way there. Continuation-passing (call/cc) allows you to implement throw without leaving “user space).
So while I found this work intellectually stimulating, at the end it didn’t seem to add significant expressive power.
A 3-lisp program is conceptually executed by an interpreter written in 3-lisp that is itself executed by an interpreter written in 3-lisp and so on ad infinitum. This forms an infinite tower of meta-circular interpreters, which can be implemented efficiently.
I honestly can't tell if this is intended to be a joke or not.
Does this point to improvements that could/should be made to other Lisps?