4 ms·
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 s
by taeric 1y ago
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 https://taeric.github.io/CodeAsData.html)
- kevin_thibedeau 1y agoLisp was supposed to ingest M-expressions and convert them internally. Eval would have been more like other languages had that plan not been abandoned. It is not meaningfully different for languages that construct an AST from a string before evaluation.
- taeric 1y agoI'm not sure I follow? Presuming that the M-expressions were also made of atoms, they would still be meaningfully different than taking in the string of text. Closer to the same, agreed, but still not the same.
- spauldo 1y agoIIRC M-expressions broke homoiconicity, so you couldn't just spit sexps at eval and expect anything sensible. I believe that's a lot of the reason they never got implemented.
- taeric 1y agoI'm still not sure I understand. It isn't like you can just throw sexps at an eval and expect something sensible, either? As a sibling was showing, calling eval on (1 2 3) will probably not be anything useful. Seems that what makes strings terrible is that they don't really encode any other structure, already. Contrast this with atoms and lists, which do encode a bit of structure. It isn't just a string of characters, it is a list of atoms and lists. Structure is already part of the thing. It does not have to be parsed out. If m-expressions would break that, I think I can see your point. But I'm confused on what would be the point of m-expressions, if they are largely just to remove structure from the content.
- spauldo 1y agoM-expressions were intended to be easier for humans to read and write. They weren't meant to be structured. They never got implemented because sexps aren't hard to work with and homoiconicity was an unexpected bonus. Calling eval on (1 2 3) gives you exactly what you asked for. It's just probably not what you wanted. The problem isn't with eval, but with the idea that (eval (1 2 3)) or (eval '(1 2 3)) is what you want to do. You probably want (eval ''(1 2 3)) - two single quotes. That'll give you a list containing the first three positive integers.
- taeric 1y agoThe examples on the wiki page still have structure in the expressions. Though, I grant it is tough to see what was intended there? From the name, though, I would expect that they would still be fully developed expressions. Just as I would not think you would say the string "(1 2 3)" is the same as the list `(1 2 3)`. Specifically, the structure of it being a list of items there is a vital part of the s-expression. I don't understand the point on calling eval on the list `(1 2 3)`. My point is you can still have a syntax error, even if you pass it a structured list. Nothing more. To that end, it is not valid code. This does assume "is code" meant "is valid code." But, that feels a safe assumption? For fun, if you don't allow a distinction between the list `(1 2 3)` and the string "(1 2 3)", then you can also flat out eval "(1 2 3)" without error. But that kind of gets to my core point, that the string and the list are different things.
- RodgerTheGreat 1y agoMany practical applications of eval() boil down to accessing (and perhaps manipulating) scopes in a manner which the host language does not normally allow. Likewise, many potential dangers or pitfalls of eval() relate to how it allows (or does not allow) dynamically-assembled code to inherit access to some spatial or temporal scope of variables, definitions, "unsafe" libraries, and so forth. The interaction of eval() with scope is much a much more interesting design question than whether it accepts an AST, a string, or something in-between, except to the extent that non-stringy "programs" represent some form of reified closure.
- taeric 1y agoI mean, you aren't wrong. But, little bobby tables is essentially what happens when you build up eval statements using a string, no?
- RodgerTheGreat 1y agoif and only if a piece of eval'd code has the ability to produce harmful (let alone observable) side effects, which in a functional language will in turn largely be a consequence of what is imported into the code's scope.
- taeric 1y agoStrictly, this isn't true, either? If you can influence what is returned from the evaluation, that may be enough to cause bugs, no? Without needing any access to scope or side effects. Consider a case where you use sql injection style modification to change an authz query so that it returns indicating the current user has admin rights. (Notably without making any external change in doing this.) Granted, I fully cede that your point is largely right. Just feels like you are a bit too strong with the "if and only if" on it.
- deleted 1y ago[deleted]
- beanjuiceII 1y agois (1 2 3) code or data?
- zem 1y agothe whole point of the "code is data" mantra is that it is both - the list `(1 2 3)` and the lisp code that evaluates to said list when parsed and interpreted.
- beanjuiceII 1y agowouldn't the data version be '(1 2 3) ? sorry I am just trying to understand
- spauldo 1y agoYou're basically asking if literals are code. I imagine you'll get varied opinions about that. (And yes, that can be used unquoted in a few different contexts in Lisp, such as a special form or macro, or if you've managed to convince the reader that 1 is a function.)
- Xmd5a 1y agoUsually yes. To distinguish between lists and function calls. However if we are to pass code literals to eval, we need to quote them: =>(eval '(1 2 3)) Cannot call 1 as a function. =>(eval ''(1 2 3)) (1 2 3)
- taeric 1y agoI don't understand the question? In particular, it feels out of place? The common claim is that code is data. This does not necessarily imply that data is code. That said, amusingly, `(1 2 3)` can easily be considered code if you are able to evaluate permutation notation. No?
- kazinator 1y agoIt depends on the dialect. If we consider Common Lisp, it's a piece of data that doesn't constitute a valid form; it is calling 1 as a function. Some Lisp dialects off the mainstream path handle it. One that comes to mind is PicoLisp which admits (1 2 3) as an expression producing (1 2 3) (that object itself, essentially "auto-quoted", I think).