• by taeric on 5/30/2025, 2:32:39 PM

    A giant difference between eval in most languages versus lisp, is that eval in lisp doesn't just take in a string. Sounds somewhat subtle, but it can lead to some dramatic differences. And is, in at least a small part, why lisp people claim code is data. (I had a fun time exploring this a long time ago in https://taeric.github.io/CodeAsData.html)

  • by neilv on 5/30/2025, 6:26:52 PM

    I'm glad Matthew Flatt wrote this. There is a problem of newbies who read some academic textbook ("metacircular evaluator!") and then immediately try to use the eval feature when it doesn't make sense.

    (Also, there's a more general problem of newbies trying to use the most advanced tool they've been exposed to. Why use the standard `if` statement, when you can use a proprietary high-powered pattern-matching form, now backed by a networked Kubernetes cluster of deep learning and LLMs.)

    In the Racket community, one of my many attempts to discourage mistaken uses of `eval`:

    https://groups.google.com/g/racket-users/c/Z-IlF24RAKU/m/3h6...

    In the all-in-one practitioner's book I was writing, eval wouldn't be introduced until almost the end, in the "Dangerous Last Resort" part of the book. (Maybe I should've planned a marketing gimmick around it, as "free bonus DLC", and you need to do some ritual to be a Certified Certifiable Racketeer, before you can read the eval secret scroll.)

  • by dang on 5/28/2025, 8:47:54 PM

    Related. Others?

    On eval in dynamic languages generally and in Racket specifically (2011) - https://news.ycombinator.com/item?id=8098569 - July 2014 (18 comments)

  • by programLyrique on 5/30/2025, 5:04:29 PM

  • by behnamoh on 5/30/2025, 2:01:07 PM

    Is my understanding correct that Lisp's powerful macro system stems from the ability to write the eval function in Lisp itself? From what I gather, Lisp starts with a small set of primitives and special forms—seven in the original Lisp, including lambda. I recall Paul Graham demonstrating in one of his essays that you can build an eval function using just these primitives. Those primitives are typically implemented in a host language like C, but once you have an eval function in Lisp, you can extend it with new rules. The underlying C interpreter only sees the primitives, but as a programmer, you can introduce new syntax rules via eval. This seems like a way to understand macros, where you effectively add new language rules. I know Lisp macros are typically defined using specific keywords like defmacro, but is the core idea similar—extending the language by building on the eval function with new rules?

  • by TOGoS on 5/30/2025, 4:04:38 PM

    In summary: The more layers of interpretation your `eval` function needs to do (assumption of source language, tokenization/parsing rules, symbol definitions, etc), the less well-defined the semantics are.

    So on the less-well-defined end, you have something like JavaScript's `eval` function, in the middle you have lisp macros, which get an AST instead of just source code, and on the actually-pretty-well-defined end, you have a lambda that's already been parsed/compiled and just needs to be evaluated.

  • by kazinator on 5/31/2025, 3:38:28 AM

    The sandboxing of eval is something that can be left to a layer on top. You certainly don't want eval itself to be gutted of functionality; nothing less than he full language, thank you.

    eval can be sandboxed with a combination of multiple approaches, including validating the code, and evaluating it in a restricted environment in which only certain symbols exist. The full library package is not visible.