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.
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.
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.
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.
(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.)
=>(eval '(1 2 3))
Cannot call 1 as a function.
=>(eval ''(1 2 3))
(1 2 3)That said, amusingly, `(1 2 3)` can easily be considered code if you are able to evaluate permutation notation. No?
To be specific, it is data. It can also be code when placed in a context where code is expected (for example in the REPL).
If taken as code and evaluated it will probably raise some kind of exception (saying that '1' isn't a function). Saying that it isn't code because it raises an exception would be an interesting take, considering something like...
(sqrt "Hello, World!")
...would also raise an exception (something about wanting a number and getting a string) when evaluated, yet I doubt many people would argue that it isn't code.Data can also be taken literally, as is the case when macros get involved. We do that every time we define a function, for example:
(defun square (x)
(declare (type Number x))
(* x x))
In this case the argument x is passed through a list which doesn't get evaluated as code.And of course you can have conditional evaluating of data as code, which still makes it code even though it doesn't necessarily get evaluated:
(define (may-error quote-the-thing)
(if quote-the-thing
(quote (1 2 3))
(1 2 3)))
...which will only evaluate the literal list (1 2 3) when the may-error function is passed a boolean false value.