It's quite easy to see, there are interpeters for Lisp in like 20 lines or so.
Here's a good one:
(It has the full code in a link towards the bottom)
There's also this:
> I would guess it checks what `defun` is, which is a macro...then expands it, and the expansion should ultimately result in an s-expression, which is then parses? Is this right?
Yes, but macros (like special forms, but macros can be user implementable) have some "special" powers regarding controlling the evaluation of the code they produce.
Here's some more discussion with examples:
https://stackoverflow.com/questions/42470940/how-is-the-defu...
For me implementing a Lisp piece by piece helped me better understand its core ideas.
Especially where the guide explains how tail-call optimization works, my mind was blown.
https://github.com/kanaka/mal/blob/master/process/guide.md#s...
Studying the project changed the way I understand code. Since then I've created my own little Lisps in about three or four versions/languages. Next I'd like to write one in WebAssembly Text format, which is already in a Lisp-shaped syntax.
Go through the first half of Crafting Interpreters [0]. And then try to complete mal - Make a Lisp [1]. That's it. You'll only need these two.
P.S. People also say good things about Build Your Own Lisp [2], but I didn't finish it because I find spending quite some time writing C doesn't make me feel I'm enjoying something elegant.
[0]: https://craftinginterpreters.com/ [1]: https://github.com/kanaka/mal [2]: https://buildyourownlisp.com/
... at https://github.com/kanaka/mal
Fun fact: I got to work with Joel at a Clojure-based startup, LonoCloud (since acquired by ViaSat). Super sharp dude, and very helpful about MAL. Definitely recommend.
Jokes aside, I'm hoping the author continues to feel free to spend their time implementing whatever idea they come across that is interesting. Sure, it's not as advanced as implementing something in C/C++, but maybe the authors goal was just to understand their preferred lisp (Clojure) better, rather than trying to understand C/C++ better?
> Bonus points if you get to optimize tail recursion. (I didn't, but I didn't try to, so I don't consider it a failure.)
Is this as complicated as people put it? I've never implemented my own lisp, but MAL (https://github.com/kanaka/mal) makes it seem like a relatively easy step in the process.
My actual long-term goal is to build a VM in Rust and then use this to re-do the Make A Lisp project [0]. I completed this a couple of years ago using C# but felt vaguely uneasy that I was using C# to do the heavy lifting associated with garbage collection, etc.
Really give you ther idea of what is needed in build a programming language. Soemthing won't quite obvious. until you I down and write code. Example the ability to rewind, go back to a few earlier token.
Or maybe use that SoC with its FORTH as microcode to implement SECD on top of it.
Or look into https://github.com/kanaka/mal & https://en.wikipedia.org/wiki/POP-11 for matching and mixing.
Having tried my hand at following the Make a Lisp project ¹, implementing an interpreter in a couple of languages, it's fascinating to see the process of designing the language and compiler from the ground up, discussing various tradeoffs for simplicity, reasons for internal data structure, etc.
In fact, I think I'm learning more about C99 than Lisp - there's something about creating a language (or just following along like me), by necessity it leads to the foundations of computing/programming, the concepts that make up the basis of all languages. It's a perfect (meta)subject for an educational project.
It doesn't seem like that. I think this is because
* it has comprehensive background for newbies (e.g. the idea of setting breakpoints in a debugger)
* it is the accompaniment for a separate book
* it has some serious background assumptions (e.g. you know calculus)
* graphics programming is much, much harder than making a lisp.
[0] https://github.com/kanaka/mal
[Edit: formatting]
I think there are a couple things in play here. Folks working with text, semi-structured data, synthesizing from disparate sources, etc will be front end heavy. Tokenization, lexing, is important outside of more than compilers, like loading binary formats from network or disk into memory.
For backend work, being able to extend or modify existing backends is important for languages targeting different runtimes (Spark, Beam, Impala). This can be in targeting new architectures or for predicate pushdown into data processing pipelines. Lots of different applications to use those skills.
Compilers and Database systems are an incredible microcosm of many areas of CS.
Areas of self study I think are nice are
MAL - Make a Lisp https://github.com/kanaka/mal
Nand2Tetris, project 11 https://www.nand2tetris.org/project11 (one should start from zero and make your way here, it is journey not a destination)
An educational software system of a tiny self-compiling C compiler, a tiny self-executing RISC-V emulator, and a tiny self-hosting RISC-V hypervisor. http://selfie.cs.uni-salzburg.at
LLVM is a huge system, libFirm is a much smaller, simpler system that includes a c front end. From their site
> libFirm is a C library that provides a graph-based intermediate representation, optimizations, and assembly code generation suitable for use in compilers.
You can see the source code for a small Lisp interpreter in 81 different languages.
- Land of Lisp - http://landoflisp.com/ - watch the video, it's hilarious
- Build Your Own Lisp - http://www.buildyourownlisp.com/ - Learn C by creating a lisp in C
- In the spirit of making your own lisp, I would recommend https://github.com/kanaka/mal - learn any language, by making a lisp in that language
* Make a Lisp https://github.com/kanaka/mal — tutorial on how to make a lisp language interpreter.
* Make an 8 bit computer https://eater.net/8bit — tutorial on making a simple 8 bit computer out of a bunch of AND, OR, NAND chips. Really helps you understand how computers work, what microcode is, etc. Honestly, building it wasn't quite as much fun as I thought it would be, but just learning how to build one was very useful.
Basically, work through building a lisp interpreter in any given language (C, Java,...bash, vimscript) in 10 steps. Each step is backed by tests, and these tests help to guide you through the process. Very cool.
[0]http://kanaka.github.io/lambdaconf/
The guide [1] has been interesting to follow, and I appreciate the author’s approach to building a Lisp interpreter as a way to pick up a new language. For example, his interpreter, mal, has implementations in every thing from ada, nasm, and bash, to C, Ruby, rust, python and everything between.
Videos walking through the guide are available too [2], [3]
[0] https://github.com/kanaka/mal
[1] https://github.com/kanaka/mal/blob/master/process/guide.md
As for the "mental capacity" I felt the same about finally getting into Rust. Spending some time with Nim actually helped me bridge the gap from Python to Rust.
[1] https://github.com/kanaka/mal/ [2] https://github.com/kanaka/mal/tree/master/awk
Lots of examples across 72 languages.
(Have implementation in pascal!)
In particular, here's their R version:
I find it's better to write it yourself than just have it explained to you. It really doesn't take that long to do, and it's broken into nice chunks of discrete work.
https://en.wikipedia.org/wiki/Esoteric_programming_language
Personally I've been thinking of doing make-a-lisp in templeos. There's no point in doing make-a-lisp in qbasic or gnu awk or makefiles because its already been done. But make-a-lisp on templeos is, I believe, completely uncharted ground ... so in my infinite spare time ...
Personally I learned the appeal of lisp while following this tutorial on writing a scheme in Haskell: https://en.wikibooks.org/wiki/Write_Yourself_a_Scheme_in_48_.... There's a reason there'll never be a tutorial like that for a toy Haskell interpreter.
I find it to be a great tool for both learning about Lisp and the language you're writing your mal implementation in.
[0] : https://github.com/kanaka/miniMAL [1] : https://github.com/kanaka/mal/tree/master/miniMAL [2] : https://github.com/kanaka/mal
Make A Lisp (MAL)
Always when I read these I see, "get your Haskell compiler and..." and I'm like, if I knew Haskell well enough to do that I wouldn't be doing this tutorial in the first place.
Case in point, article says "particularly for programming pracitioners who didn’t learn it at school." -- Correct! I taught myself Basic, I taught myself a bit of x86 assembler, most importantly, I taught myself C. My working mental model of a computer is the C machine model. And even now, now that I know Ruby with its lambdas, I know that Ruby is written in C. And the Linux kernel. And Nginx (C++ maybe? Dunno). And on, and on.
Show me the tutorial where I can build, _in C_ a bare bones working (tail recursion) implementation of the lambda calculus with type inference and dependent (algebraic?) types and I'll shake your hand and call you a champion.
Closest I've seen is Make A Lisp - https://github.com/kanaka/mal but I don't think it has the sweet types and tail recursion and other good stuff. PS: bonus points if Regexen are native type :)
(Open to suggestions (I am))
Fully working lisp in 10 (easy to not so easy) steps.
This is more than a weekend's worth of work, but the work is incremental, so you will see benefits from point 0. This was a lot of fun for me, and it helped shine light on some of the darker corners of Go.
I'm still working on a version of it myself, using it to experiment with different coding styles, interfaces, and libraries. A lot of fun.