[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: DECLARE SPECIAL Considered Confusing
Date: Sat, 12 Jul 86 22:48 EDT
From: "Scott E. Fahlman" <Fahlman@C.CS.CMU.EDU>
...
We would also need to spell out in detail exactly how all this works
in
DO, DO*, and friends. It's obvious what should happen if you think
in
terms of the expansion into a LET or LET* form, but we don't want to
leave that up to the readers to figure out.
Actually, I think that we ought to provide example macro definitions for
almost all of the macros in CLtL in order to avoid the ambiguity in
their descriptions. For example, as I think Moon or Weinreb pointed
out, CLtL doesn't specify the result of this program:
(setq foo nil)
(dotimes (i 10)
(push #'(lambda (n) n) foo))
(mapcar #'funcall foo)
At the very least, it should be specified for DO, DOLIST and DOTIMES
whether they repeatedly rebind their variables or simply SETQ them. I
don't imagine that any implementation does rebinding for DO, but it's
just as simple as SETQ for DOLIST.
I disagree with Pavel's proposal for LAMBDA (and, therefore, DEFUN).
He
suggests that the scope of all the declarations should coincide with
the
scope of the first required parameter -- in effect, this follows the
current rule of making the declarations wrap everything. That seems
wrong to me. The variables are bound and the init-forms are computed
left-to-right, as in LET*. If we change LET* in the way Pavel
suggests,
we ought to change LAMBDA in the corresponding way: the scope of a
declaration matches the scope of the variable binding it applies to;
the
scope of declarations that do not apply to variable-bindings created
by
the lambda list includes only the body of the form.
-- Scott
I considered that approach in writing up my proposal and actually like
it better than the ``whole form'' notion given there. The only problem
I saw (and still see) with it is that in cases like this:
(defun bar (&optional (x (foo)))
(declare (inline foo))
...)
the call to FOO in the init-form is not covered by the INLINE
declaration. Further, the only way to affect it at all is to use
LOCALLY. I wasn't sure if this was an important enough problem to force
a change, so I put in the current semantics and waited to see. Now that
you've pointed it out, I'm in agreement with you; the consistency with
LET* is much more important than any obscure difficulty in init-forms.
Pavel