[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

LAMBDA proposals and counter-proposals



Your last note addresses an interesting and important problem of how to
scope the declaration correctly. I am familiar with the LET/LET* problem
with propagating declarations around right.  It's a pain. But I think the
problem is caused by the fact that you really have a request that a
different kind of binding be done and you're trying to overload LAMBDA to
make it be able to bind several different kinds of cells. So my answer is
to create a different kind of binding primitive. ie, let the user write 

  (DEFUN F (X &SPECIAL Y Z) ...code...)

if he feels strongly that that's how he wants to visualize it, but let it
macroexpand into:

  (SETF #'F #'(VANILLA-LAMBDA (X G0001 Z)
			      ((SPECIAL-LAMBDA (Y) ...code...) G0001)))

A smart compiler will make the right code for this without blinking. A
not-so-smart one could easily enough be tought to look for this idiom and
not compile the extra stack push. The loss of time in the interpreter would
likely be negligible. With appropriate macro expansion and printer hooks,
the user should rarely have to look at this visually. BUT the great thing
is that code-walkers can really handle this kind of stuff VERY elegantly.
Similarly, suppose you had  an &SPECIAL keyword which was sticky and could
go in LET*'s as given here:

  (LET* ((W 1) &SPECIAL (X 2) (Y 3) &UNSPECIAL (Z 4)) ...code...)

Then it might expand into the conceptually elegant underlying form:

  ((VANILLA-LAMBDA (W) ((SPECIAL-LAMBDA (X Y)
			   ((VANILLA-LAMBDA (Z) ...code...) 4))
			2 3))
   1)

which is explicit, parse-free, and which does not have the LET/LET*
declaration scoping problem you alluded out in your note.

Such an approach does mean that you would have to have several kinds of
binding primitives around -- eg,

  VANILLA-LAMBDA -- does the really primitive kind of binding which the
   compiler is allowed to assume is essentially lexical.

  SPECIAL-LAMBDA -- binds the variable's special cell always.

  FUNCTIONAL-LAMBDA -- binds the variable's function cell.

These are the only ones I think you would need at the lowest level. Perhaps
one or two more could be shown to be necessary. But the nice thing is that
they all have very simple meanings and are very easy to be manipulated by
code-manipulating programs.

I think that a basing a language on the composition of small number of
well-understood primitives -- even if it means that we have to create some
that have not been needed until now -- is far better than trying to do
everything all in one place.