[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