| > you might not even have a guarantee of the order of evaluation of FORMs. However, a let based on lambda would have parallel binding. The evaluation of the forms would mainly come from the argument evaluation order of the lambda, where the macro would have to go out of its way to screw it up. It's worth noting that Common Lisp has optional parameters. These use sequential binding like let*. So we could translate (let* ((a (a)) (b (b))) c)
into (funcall (lambda (&optional (a (a)) (b (b)))))
The lambda is called with no arguments, so that the defaulting takes place, and that has all the semantics we need. (We could also similarly exploit &aux).The fact that CL's optional parameters use sequential binding kind of shows that it's the preferred mode. The reason that the fixed parameters of lambda have parallel binding is that the values don't come from the lambda form itself, but from the arguments, which are already evaluated. So there is no way for a parameter value to be calculated from another parameter value. They come into existence at the same time. Not so with optionals; they have default expressions, and those can refer to the prior variables. Thus let came from lambda, and was understood in terms of fixed, required parameters. Required parameters come into the scope simultaneously, and so let variables came into scope simultaneously. |