This seems like a good thread to recommend my favourite compiler book Lisp in Small Pieces by Christian Queinnec.
On the surface it's a book about Lisp, but Lisp is just the vehicle, for a book about implementing interpreters and compilers.
It starts with a very simple meta-interpreter for a dynamic primitive Lisp, similar to early Lisp. The final chapters are for an optimizing compiler. (All code is in Lisp.)
It loosely follows the history of programming language development. For example, the first lessons (if I remember right) are about why dynamic scoping is flawed. Another early lesson is about why it's a bad idea to use a linked list to represent environment (symbol . value) pairs in an interpreter or compiler. (Because runtime grows O(n) for n symbols in the program.)
If you ever wondered how to write a programming language, this is probably the best resource to get started (and then of course Crafting Interpreters).
I've always found MAL ("Make-A-Lisp" https://github.com/kanaka/mal) a bit more approachable, probably because I was out after creating my own programming language before I've written much Python. It's language agnostic, and really easy to follow along with most programming languages out there, explaining everything as you progress.
That it's language agnostic and somehow matters feels weird now a lot of time (and experience I suppose) afterwards, but back when I only knew 1-2 languages by heart, also having to face understanding Python at the same time from Norvigs guide/reference made it slightly more complicated for me.
I use this as a litmus test now when coming across new languages (implementing MAL in the new language), as it's such an easy approach to practically test large parts of the new language, and there is always host-language-specific tricks you can learn along the way.
My Lisp from 1975 was actually used in real world and highly lucrative. Gemini could read the source code, but it told that my code was piece of shit and cannot be implemented in 64-bit world without drastic changes, so it made an example. But that version was just too advanced and too complex as a study subject. There are already enuff good Lisps in the world, methinks.
There are two problems with Lisp parentheses in my opinion:
1) Humans are not that equipped to handle that level of nesting without some other aid, this is why Lisp code is usually indented.
2) Parentheses aren't just about grouping, and this is unintuitive. For example, x is not the same as (x). This is a bit like in set theory where x is not the same as {x}, but parentheses do not look like the kind of sign that would work like that.
@bananaflag, the x versus (x) distinction is also what makes this evaluator so small: the AST uses atom versus list as the dispatch boundary, so grouping and application deliberately share syntax. An infix parser moves that complexity into precedence and associativity rules; it does not eliminate it. Indentation is still essential, but that is a tooling and display issue rather than a grammar issue.
I changed my opinion about parens when I stopped formatting like C, and used indent rather than parens to denote blocks. That is, a large amount of them at the end is totally fine.
I actually perfected the Norvig Lisp at one time. It has compiler to python and just everything. Those very few here that can actually read code, understand why this project soon exploded into biggest piece of odorous excrement.
There are edge cases where this fails, but `def parse(s): return json.loads('['+re.sub('([")])\s*(["(])','\g<1>,\g<2>',re.sub('[^()\s]+','"\g<0>"',s)).replace('(','[').replace(')',']')+']')` is a surprisingly robust lisp parser.
> I don’t think a good learning resource gets worse[...]
Probably not, but they become irrelevant. The other day I found an old programming book at my parents’ and while it was still a terrific resource, I couldn’t image anyone learning a language from a book nowadays.
AI is doing the same thing but 100 times effectively than anything else.
Blog tutorials, guides, programming books and youtube tutorials. They are completely irrelevant in a time where you have a personal tutor willing to explain every single detail of a subject.
That's like saying your grandfather is irrelevant now that he's spawned children and grandchildren. Good luck to those personal tutors without this source material.
This seems like a good thread to recommend my favourite compiler book Lisp in Small Pieces by Christian Queinnec.
On the surface it's a book about Lisp, but Lisp is just the vehicle, for a book about implementing interpreters and compilers.
It starts with a very simple meta-interpreter for a dynamic primitive Lisp, similar to early Lisp. The final chapters are for an optimizing compiler. (All code is in Lisp.)
It loosely follows the history of programming language development. For example, the first lessons (if I remember right) are about why dynamic scoping is flawed. Another early lesson is about why it's a bad idea to use a linked list to represent environment (symbol . value) pairs in an interpreter or compiler. (Because runtime grows O(n) for n symbols in the program.)
https://christian.queinnec.org/WWW/LiSP.html
Is it classics day or something? (Fine with us!)
Related:
(How to Write a (Lisp) Interpreter (In Python)) (2010) - https://news.ycombinator.com/item?id=39665939 - March 2024 (91 comments)
(How to Write a (Lisp) Interpreter (In Python)) (2010) - https://news.ycombinator.com/item?id=30443949 - Feb 2022 (9 comments)
(How to Write a (Lisp) Interpreter (In Python)) - https://news.ycombinator.com/item?id=30327437 - Feb 2022 (3 comments)
(How to Write a (Lisp) Interpreter (In Python)) - https://news.ycombinator.com/item?id=26036431 - Feb 2021 (1 comment)
How to Write a Lisp Interpreter In Python (2010) - https://news.ycombinator.com/item?id=20590439 - Aug 2019 (29 comments)
How to Write a Lisp Interpreter in Python (2010) - https://news.ycombinator.com/item?id=12777852 - Oct 2016 (28 comments)
How to Write a Lisp Interpreter in Python (2010) - https://news.ycombinator.com/item?id=7825054 - May 2014 (41 comments)
(How to Write a ((Better) Lisp) Interpreter (in Python)) - https://news.ycombinator.com/item?id=1746916 - Oct 2010 (10 comments)
(How to Write a (Lisp) Interpreter (in Python)) - https://news.ycombinator.com/item?id=1745322 - Sept 2010 (39 comments)
I feel like we need a vibe coded guide in this modern day and age.
Depressing to think that AI will be doing most of this in the future. Sharing it freely in the internet, basically ensures AI can copy it well.
If you ever wondered how to write a programming language, this is probably the best resource to get started (and then of course Crafting Interpreters).
See also part 2 https://norvig.com/lispy2.html
I've always found MAL ("Make-A-Lisp" https://github.com/kanaka/mal) a bit more approachable, probably because I was out after creating my own programming language before I've written much Python. It's language agnostic, and really easy to follow along with most programming languages out there, explaining everything as you progress.
That it's language agnostic and somehow matters feels weird now a lot of time (and experience I suppose) afterwards, but back when I only knew 1-2 languages by heart, also having to face understanding Python at the same time from Norvigs guide/reference made it slightly more complicated for me.
I use this as a litmus test now when coming across new languages (implementing MAL in the new language), as it's such an easy approach to practically test large parts of the new language, and there is always host-language-specific tricks you can learn along the way.
(how-to in-python (write (interpreter lisp)))
Yes, but to be fair, you only have a couple minutes to fight the HN title regex.
My Lisp from 1975 was actually used in real world and highly lucrative. Gemini could read the source code, but it told that my code was piece of shit and cannot be implemented in 64-bit world without drastic changes, so it made an example. But that version was just too advanced and too complex as a study subject. There are already enuff good Lisps in the world, methinks.
https://github.com/timonoko/nokolisp
Writing a Lisp is one of my favorite projects. I try to do it every year or two, taking a different approach each time.
The one where you replaced parentheses with the crying laughing emojis was definitely the worst.
I can't recommend highly enough to implement a simple lisp (or a forth).
Illuminating experience and it will also help you see (among many other things) the parentheses in a different light.
First day of paradigms course in the 2000s and prof says "if your opinion of Scheme is too many parentheses, then you're an idiot."
Needless to say that was my opinion and every day I think, more and more, how right he was.
(later I did make some gui apps that included scripting and chose s-expr syntax because of how simple it is to implement it)
There are two problems with Lisp parentheses in my opinion:
1) Humans are not that equipped to handle that level of nesting without some other aid, this is why Lisp code is usually indented.
2) Parentheses aren't just about grouping, and this is unintuitive. For example, x is not the same as (x). This is a bit like in set theory where x is not the same as {x}, but parentheses do not look like the kind of sign that would work like that.
@bananaflag, the x versus (x) distinction is also what makes this evaluator so small: the AST uses atom versus list as the dispatch boundary, so grouping and application deliberately share syntax. An infix parser moves that complexity into precedence and associativity rules; it does not eliminate it. Indentation is still essential, but that is a tooling and display issue rather than a grammar issue.
main problem isn't brackets themselves - it's that they're too on the right
had brackets been displayed as curly braces in C - everything would look much more manageable
so, instead of
you'd prefer is that right?(aar (bar1 1 2 3) (bar2 1 2 3) (bar3 (car1 2 3)(car2)(car3)))
Emacs vs vim, go!
I changed my opinion about parens when I stopped formatting like C, and used indent rather than parens to denote blocks. That is, a large amount of them at the end is totally fine.
I actually perfected the Norvig Lisp at one time. It has compiler to python and just everything. Those very few here that can actually read code, understand why this project soon exploded into biggest piece of odorous excrement.
https://github.com/timonoko/nokolis.py
or you could just use Raku and its “surprisingly good lisp impression”:
https://www.codesections.com/blog/raku-lisp-impression/
Appreciated the title xD
There are edge cases where this fails, but `def parse(s): return json.loads('['+re.sub('([")])\s*(["(])','\g<1>,\g<2>',re.sub('[^()\s]+','"\g<0>"',s)).replace('(','[').replace(')',']')+']')` is a surprisingly robust lisp parser.
(2010)?
?
Why did you replace your very similar comment with "--" just to post essentially the same thing again?
Man these kind of resources have aged really bad in the age of AI.
Why would AI make these age worse than, say, libraries or languages becoming obsolete?
I don't think a good learning resource gets worse just because there's a newer alternative.
> I don’t think a good learning resource gets worse[...]
Probably not, but they become irrelevant. The other day I found an old programming book at my parents’ and while it was still a terrific resource, I couldn’t image anyone learning a language from a book nowadays.
AI is doing the same thing but 100 times effectively than anything else.
How do you mean “these kind”?
Blog tutorials, guides, programming books and youtube tutorials. They are completely irrelevant in a time where you have a personal tutor willing to explain every single detail of a subject.
That's like saying your grandfather is irrelevant now that he's spawned children and grandchildren. Good luck to those personal tutors without this source material.
How so?