Live data from Hacker News

Lisp in fewer than 200 lines of C

carld.github.io

51–60 of 108 posts

Re: Lisp in fewer than 200 lines of C

#51
post #33

Writing your own Lisp-ette is a brilliant evening or weekend project, regardless of the language. It's some of the simplest non-toy parsing you can attempt, a bit of light data structure work, and understanding eval/apply is 80% of the work in implementing it. I would highly recommend anyone to have a go, and try not to follow existing code too closely: figure out the problems in your language of choice. The post ide…

> Writing your own Lisp-ette is a brilliant evening or weekend project, regardless of the language.

Just be careful about scope creep. I started one as a weekend project five years ago and I'm still not finished ;)

Re: Lisp in fewer than 200 lines of C

#52
post #50

Earlier quoted context omitted.

I think you are mistaken. There is much to learn from implementations such as this, and the techniques used form the basis of much more complex systems. The technology remains very relevant. FWIW, I didn't downvote you, as I don't downvote someone simply because I believe they're wrong, or because I disagree with them.

While I agree that it's not just historical interest - there's still much that can be learned from Lisp - this implementation is certainly not the place to learn it. There's no garbage collection, which is really the biggest concern of a proper lisp implementation in a language like C. Without GC, it's a gimmick implementation. There's no practical use for it.

There is much to be learned from incomplete, toy implementations. Not least, the interested reader can see if they can extend the existing implementation to include the missing features.

Insisting that learners/students should only ever read and study complete, perfect implementations is, I think, a mistake. I've learned a great deal from studying, and subsequently improving and extending, implementations that are imperfect and incomplete.

Re: Lisp in fewer than 200 lines of C

#53
post #33

Writing your own Lisp-ette is a brilliant evening or weekend project, regardless of the language. It's some of the simplest non-toy parsing you can attempt, a bit of light data structure work, and understanding eval/apply is 80% of the work in implementing it. I would highly recommend anyone to have a go, and try not to follow existing code too closely: figure out the problems in your language of choice. The post ide…

If you go with (hygenic) fexprs instead of macros, they're both easier to implement and more expressive, at the expense of performance. Check out John Shutt's thesis for more information on hygenic fexprs: https://web.wpi.edu/Pubs/ETD/Available/etd-090110-124904/unr...

Here's a small implementation of Kernel in around 700 lines of Haskell [https://github.com/vito/hummus/tree/master/src/Hummus]. Note that it's not Kernel proper, as it uses delimited continuations instead of the guarded undelimited continuations in the Kernel report, plus there's a few other differences and some bugs.

Anyone looking for a more complete implementation, check out klisp [http://klisp.org]. It's not 100%, but has some stuff not included in the Kernel report, some of it lifted from R6RS. The main thing it's missing which it desperately needs is an FFI.

Re: Lisp in fewer than 200 lines of C

#54
For everyone interested in learning about these types of things, check out Make-A-Lisp project [0]. There's more lines of code, but also more features. The guide is awesome and split into several self-contained steps.

[0] https://github.com/kanaka/mal/blob/master/process/guide.md

Re: Lisp in fewer than 200 lines of C

#56
In the eval the dynamic intern("if") ... for all interned symbols should be moved to compile-time global storage of those interns. Otherwise it looks good. In reality one would use more tag bits, no just one. Typically 3.

Re: Lisp in fewer than 200 lines of C

#57
post #33

Writing your own Lisp-ette is a brilliant evening or weekend project, regardless of the language. It's some of the simplest non-toy parsing you can attempt, a bit of light data structure work, and understanding eval/apply is 80% of the work in implementing it. I would highly recommend anyone to have a go, and try not to follow existing code too closely: figure out the problems in your language of choice. The post ide…

I found none of these particularly difficult. (I've never attempted 3. or 5. though.) Functional values, however, are difficult. They work effortlessly in interpreted code, but in compiled code you're faced with the upwards funarg problem: https://en.wikipedia.org/wiki/Funarg_problem#Upwards_funarg_... A solution is needed if you want lazy evaluation.

> They work effortlessly in interpreted code, but in compiled code you're faced with the upwards funarg problem

No it's not about interpreted or compiled. It's about using the native stack or a heap for stack frames. Compiled code and interpreters can both use either, so that's orthogonal.

Re: Lisp in fewer than 200 lines of C

#58
post #53

Earlier quoted context omitted.

If you go with (hygenic) fexprs instead of macros, they're both easier to implement and more expressive, at the expense of performance. Check out John Shutt's thesis for more information on hygenic fexprs: https://web.wpi.edu/Pubs/ETD/Available/etd-090110-124904/unr...

Here's a small implementation of Kernel in around 700 lines of Haskell [ https://github.com/vito/hummus/tree/master/src/Hummus ]. Note that it's not Kernel proper, as it uses delimited continuations instead of the guarded undelimited continuations in the Kernel report, plus there's a few other differences and some bugs. Anyone looking for a more complete implementation, check out klisp [ http://klisp.org ]. It's not…

On the subject of Haskell, what's the shortest Haskell (possibly Haskell subset) interpreter anyone has written?

Re: Lisp in fewer than 200 lines of C

#60
Oof, all the macros are broken:

    #define is_space(x)  (x == ' ' || x == '\n')
    #define is_parens(x) (x == '(' || x == ')')
Should be

    #define is_space(x)  ((x) == ' ' || (x) == '\n')
    #define is_parens(x) ((x) == '(' || (x) == ')')
Probably doesn’t matter in practice for this. It could end up being a nasty source of bug later on in the project.
Post reply on HN