Compiling a Lisp (2020)
bernsteinbear.com
bernsteinbear.com
Essentials of Compilation by Siek (Racket and Python versions available) are book-length treatments of that paper's topic.
By the way, for the Python folks with a Pi around, this one is also an interesting read to dive into what it means to write a compiler
"Writing Interpreters and Compilers for the Raspberry Pi Using Python"
https://www.amazon.com/Writing-Interpreters-Compilers-Raspbe...
Compiling a Lisp to x86_64 (2020) - https://news.ycombinator.com/item?id=26631308 - March 2021 (31 comments)
Compiling a Lisp to x86-64: Labelled procedure calls - https://news.ycombinator.com/item?id=24931577 - Oct 2020 (13 comments)
Compiling a Lisp: Instruction encoding interlude - https://news.ycombinator.com/item?id=24822534 - Oct 2020 (2 comments)
Compiling a Lisp to x86-64: Heap allocation - https://news.ycombinator.com/item?id=24746587 - Oct 2020 (3 comments)
Compiling a Lisp to x86-64: If expressions - https://news.ycombinator.com/item?id=24711072 - Oct 2020 (4 comments)
Compiling a Lisp to x86-64: Let expressions - https://news.ycombinator.com/item?id=24652842 - Oct 2020 (39 comments)
Compiling a Lisp: Reader - https://news.ycombinator.com/item?id=24580453 - Sept 2020 (27 comments)
Compiling a Lisp to x86-64: Primitive binary functions - https://news.ycombinator.com/item?id=24490108 - Sept 2020 (1 comment)
Compiling a Lisp to x86-64: primitive functions - https://news.ycombinator.com/item?id=24386826 - Sept 2020 (29 comments)
Over the years I've toyed with running uLisp running on microcontrollers. There has been some work to add macros, and the running of assembly...so of course the next step would be to write a small compiler that can output RISKV and Arm thumb assembler so that I can reproduce the Genera LISP machine on and esp32 or teensy 4.0 driven handheld computer. That's the dream at least.
Thanks for the tip about jank!
Unfortunately it's not a simple language, and has much historical baggage (the standard has mandated Roman literals in formating, really guys?..)
There is a sort of shape translation, like an affine transformation between lisp code and algol family stuff like c, etc. Once your brain sees the shapes of the paragraphs, and the function and class def shapes, you will not feel lisp is really different from the other languages except in form. ( excluding the macros. those are truly unique)
I wonder how far one might go introducing common lisp with parallel examples in javascript and python -- something like a Rosetta Stone approach, also likening ')' and '}' and <dedent>.
lisp for python devs, amd its just basic python shit on the left page, and the clisp version on the right page.
We do the same thing for human language books. Ive got a copy of the little prince where the left is in english and the right is in japanese. the bookstore is full of these.
The functions and symbols in the core packages (e.g. COMMON-LISP package) are considered fixed and immutable. For example, out of the box, the compiler can assume that things like '+' aren't going to be redefined behind its back. It's assumptions like that can lead to very efficient code. But, at the same time, the core lisp language is actually not very dynamic, its more like your typical, compiled language in that sense.
In contrast to say, Scheme, which has no presumptions. Out of the box, naive Scheme compilers can not make such assumptions. So, if you have something like:
(set! a (+ x (- y (+ z w))))
The compiler actually has to look up (dispatch) '+' twice! Did '-' change the definition of '+'? Maybe...you don't know. So you can't (again naively) inline anything (not even counting the issues with numeric tower and types of the variables). So, what would ideally be a couple of simple machine instructions turns in to a huge endeavor.Both Scheme and CL let's you completely shadow any symbol in a given compilation unit, however.
I'm also curious to know why I would want something that was so dynamic that + could be redefined on me.
(define scalar-sum +)
(define (+ . arguments)
(if (vectors? 'arguments)
(vector-sum 'arguments)
(apply scalar-sum arguments)))
vectors? and vector-sum not shown for clarity.
Edit: or maybe you want any sum in excess of (say) $5,000 to alert a manager. (define old-plus +)
(define (+ . args)
(let ((value (apply old-plus args)))
(if (> value 5000)
(begin
(alert-manager)
value)
value)))
The nice thing here is that this Just Works anywhere + appears in the code. You don't need to put the conditional and the call to alert-manager everywhere you're calculating a sum. Of course, in a real implementation you'd want to pass stuff to alert-manager like what module you're in, the transaction number, etc.Because it is undefined behavior to do so.
By the way, in case anyone is wondering what this is, it just means that you can use the FORMAT function to output Roman numbers.
(format t "~@r" 4)
;; => IV
You can also do: (format t "~r" 4)
;; => four
and just interpolating the number would use "d": (format t "The number is: ~d" 4)
;; => The number is: 4Come now, it's not _that_ old :)
It's just a bit of fun, not really historical baggage...