4 ms·
The notation uses S-expressions, that’s true, but the point that I was trying to make is that you can’t understand anything about the meaning of those S-express
by jcrites 9y ago
The notation uses S-expressions, that’s true, but the point that I was trying to make is that you can’t understand anything about the meaning of those S-expressions without parsing them in a context-aware way.
It’s not as if there is just one form `(<op> <arg1> ... <argN>)` where the expression means invoking `op` with some arguments.
A human or machine interpreting the code needs to be aware of these forms and the meaning/semantics of each one. Consider the following S-exps:
(if a b)
(set! a b)
(define a b)
They’re all three-term S-expressions, but you can’t understand their meaning without contextually interpreting the first term. There is a second layer of contextual syntax. Similarly:
((lambda (x y) (list y x)) 1 2)
Consider the term `(x y)` in that expression. Without context, it looks like a call to the procedure `x` with `y` as input. With context, it’s a list of argument names for the lambda function.
In languages like C# and Java there is just one meaning of:
f(a, b);
You know this is actually a procedure invocation with some arguments.
There are trade offs to each approach. I’m not saying that one is better, just that there’s more to Scheme syntax than S-exps. Concatenative languages like Forth and Factor have even less syntax than Scheme.
- taeric 9y agoStrictly, this isn't true. In f(a, b), if f is while, it is not a procedure call. Or if it is a declaration. Then, of course, there is the specifics of the call. Is it single dispatch? Where is it dispatched? Etc. Which isn't really to argue against the point. Yes, you need context. Pretty much always. Having gotten used to lisp, I find it much easier to understand. I realize familiarity helps, though.