On eval in dynamic languages generally and in Racket specifically (2011)

by swatson741on 5/28/2025, 8:44 PMwith 32 comments

by taericon 5/30/2025, 2:32 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 neilvon 5/30/2025, 6:26 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 dangon 5/28/2025, 8:47 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 programLyriqueon 5/30/2025, 5:04 PM

About how eval is used in other languages:

- in Javascript: https://link.springer.com/chapter/10.1007/978-3-642-22655-7_...

- in R: https://dl.acm.org/doi/abs/10.1145/3485502

by behnamohon 5/30/2025, 2:01 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 TOGoSon 5/30/2025, 4:04 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 kazinatoron 5/31/2025, 3:38 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.