|
|
|
|
|
by all2
435 days ago
|
|
The lisp is harder to read, for me. The first double paren is confusing. (let (bar-x (bar x))
(quux-y (quux y)))
(foo bar-x quux-y z)
Why is the second set of parens necessary?The nesting makes sense to an interpreter, I'm sure, but it doesn't make sense to me. Is each top-level set of parens a 'statement' that executes? Or does everything have to be embedded in a single list? This is all semantics, but for my python-addled brain these are the things I get stuck on. |
|
The variable-bindings occupy one argument position in let. This argument position has to be a list, so we can have multiple variables:
Within the list we have about two design choices: just interleave the variables and their initializing expressions: Or pair them together: There is some value in pairing them together in that if something is missing, you know what. Like where is the error here? we can't tell at a glance which variable is missing its initializer.Another aspect to this is that Common Lisp allows a variable binding to be expressed in three ways:
For instance binds i, j and k to an initial value of nil, and m to 9.Interleaved vars and initforms would make initforms mandatory. Which is not a bad thing.
Now suppose we have a form of let which evaluates only one expression (let variable-bindings expr), which is mandatory. Then there is no ambiguity; we know that the last item is the expr, and everything before that is variables. We can contemplate the following syntax:
This is doable with a macro. If you would prefer to write your Lisp code like this, you can have that today and never look back. (Just don't call it let; pick another name like le!)If I have to work with your code, I will grok that instantly and not have any problems.
In the wild, I've seen a let1 macro which binds one variable: