That's a good question. I didn't make an effort to compare them, but it seems like it would be Racket because writing DSLs seems to be Racket's specialty, plus it's already a lisp.
The problem with that command is that it also counts the Makefile, Dockerfile and other supporting files. It also counts every implementation step (so lots of repeats in the LOC). However, each implementation does have a "stats" rule. So the following command at the top-level can be used to a get a nice summary:
for i in $(make print-IMPLS); do \
s=$(make stats^$i | grep total); \
printf "%-9s %s\n" "$i" "$s"; \
done | sort -n -k2
Note that this should obviously be taken with a grain of salt: the implementations were created by many different people each with their own style and differing experience levels with the target language. That being said, from my own experience, I think the concision (size) of the implementation often reflects how "Lispy" a language is. Most of the Lisps are in the top half of the list (fewest LOCs). Ruby is often described as very Lisp-like. Factor is one that stands out for me (second after mal itself). Factor also happens to be one of the fastest implementations (for certain microbenchmarks).
Here, https://www.metalevel.at/lisprolog/ Prolog is a difficult language for most, it really does break brains. That profound enlightenment that's found in programming, I found in Prolog not in lisp.
IIRC I got bogged down early with the regular expression for parsing, but I definitely want to try again. Really enjoyed the MAL talk at Midwest.io: https://youtu.be/lgyOAiRtZGw
I immediately thought of Shen which is also ported to a large number of languages. Shen relies on a "micro-Lisp" substrate called K-Lambda which consists of just 43 easily ported instructions.
Indeed. I built a Lisp in bash. I used a different approach to reading and consing than the FA uses. Basically what I wrote uses the idea from the IOCCC '89 "xlisp" which is that the s-expression is represented by a string instead of by a graph of cons cells. That means that the car operation must only be done on parenthesized strings. One obtains the car by searching for the first atom after the left paren. Similarly the cdr is the rest of the atoms within the parentheses. I didn't consider other encodings of s-expressions.
Of course if you have computing to do in a bash script, bash already supports that so there is no real point. A colleague implemented a BASIC inside TECO which may have also been pointless.
I was talking specifically about the projects that get posted on HN acting as if they're the next big thing in the Lisp world. They inevitably go nowhere and make little impact.
Building a Lisp is a great exercise, but I don't need to know every time somebody does it. We might as well have posts about everybody's fizzbuzz...
I have this page on my "TODO" list. What is your opinion about it? I see already that you are recommending it but maybe you can give some more details. Thanks in advance.
Skimming through it and seeing stuff like this doesn't leave much headroom for a high opinion, at least from a hard-line Lisp and C expert point of view:
/* excerpt from builtin_op function */
while (a->count > 0) {
/* Pop the next element */
lval* y = lval_pop(a, 0);
if (strcmp(op, "+") == 0) { x->num += y->num; }
if (strcmp(op, "-") == 0) { x->num -= y->num; }
if (strcmp(op, "*") == 0) { x->num *= y->num; }
if (strcmp(op, "/") == 0) {
if (y->num == 0) {
lval_del(x); lval_del(y);
x = lval_err("Division By Zero!"); break;
}
x->num /= y->num;
}
lval_del(y);
}
For people who are newbies to programming and newbies to C, this sort of book can provide stimulating activities and motivation. Ultimately they will probably be unsatisfied with their results (but then nobody is ever satisfied with their results no matter what, if they are newbies in programming and C, struggling to make something).
I worked through the book while I was in school as a way to prepare myself for a C-programming heavy course (OS) that I was scheduled to take later in the semester. I liked the book - its quite intense but you do end up learning quite a bit. I also picked up interesting tidbits on Lisp so that's quite welcoming.
One thing that you might be interested in knowing about is that this book uses a few libraries which means you don't end up writing everything from scratch. For example, in the chapter on parsing, the grammar is implemented using a library called MPC (https://github.com/orangeduck/mpc) written by the author himself.
I didn't quite reach till the very end so didn't have a chance to implement Macros (the author does mention them in Chapter 16), so if that's something you can very keen on implementing then you might have to look someplace else.
It starts you from scratch and I'd say it's well done, maybe even be overdone for Lisp. But you get a good introduction to the essentials of language implementation for more complicated languages.
Shameless self-promotion: I wrote a Lisp interpreter in a single assembly file for Raspberry Pi. It also starts from scratch at an even lower level, to the point of ignoring standard libraries.
Great work on this! I've not touched ASM in nearly 20 years (I first learnt C and then a bit of ASM to crack software using Softice!)
This really makes me want to blow the dust off the RaspberryPi (we all bought one and never used it: admit it) and get this up and running, just to see it working.
This repos should be on developer code to read. I used it as a way to see how people implement a LISP. Having a reference for all languages allow me to know strong/weak point of each of them.
33 comments
[ 3.2 ms ] story [ 85.3 ms ] threadhttps://en.wikipedia.org/wiki/Brainfuck
https://github.com/shinh/bflisp
Edit2: for formatting
Haskell, Ruby, Kotlin, Lua, Go, Rust, C, Swift.
Note that this should obviously be taken with a grain of salt: the implementations were created by many different people each with their own style and differing experience levels with the target language. That being said, from my own experience, I think the concision (size) of the implementation often reflects how "Lispy" a language is. Most of the Lisps are in the top half of the list (fewest LOCs). Ruby is often described as very Lisp-like. Factor is one that stands out for me (second after mal itself). Factor also happens to be one of the fastest implementations (for certain microbenchmarks).
http://www.shenlanguage.org/
Common Lisp, Racket, Clojure, Scheme, etc. are all great choices with decent compilers, interpreters, library ecosystems, editor support, etc.
Seems there's a new pet project Lisp released once a month or so, and none of them add anything interesting over the existing options.
Of course if you have computing to do in a bash script, bash already supports that so there is no real point. A colleague implemented a BASIC inside TECO which may have also been pointless.
Building a Lisp is a great exercise, but I don't need to know every time somebody does it. We might as well have posts about everybody's fizzbuzz...
One thing that you might be interested in knowing about is that this book uses a few libraries which means you don't end up writing everything from scratch. For example, in the chapter on parsing, the grammar is implemented using a library called MPC (https://github.com/orangeduck/mpc) written by the author himself.
I didn't quite reach till the very end so didn't have a chance to implement Macros (the author does mention them in Chapter 16), so if that's something you can very keen on implementing then you might have to look someplace else.
Shameless self-promotion: I wrote a Lisp interpreter in a single assembly file for Raspberry Pi. It also starts from scratch at an even lower level, to the point of ignoring standard libraries.
https://github.com/marcpaq/arpilisp
I was inspired by jonesforth, which, if you haven't read it, is a beautiful piece of work.
This really makes me want to blow the dust off the RaspberryPi (we all bought one and never used it: admit it) and get this up and running, just to see it working.