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

Re: issue DYNAMIC-EXTENT-FUNCTION, version 1



    Date: Fri, 26 May 89 09:42:51 MDT
    From: sandra%defun@cs.utah.edu (Sandra J Loosemore)

    The last round of discussion on this issue was kind of inconclusive
    and then I got distracted with some real work, but I have some time
    now to work on a new version.  It sounded like there was some support
    for the idea of just extending the existing DYNAMIC-EXTENT declaration
    to take arguments like (FUNCTION <x>) instead of adding another
    declaration just for functions, so that'll probably be in the new
    version unless somebody complains.

Okay.

    I don't know what to do about the related issue of declaring that an
    anonymous lambda has dynamic extent -- none of the alternatives that
    have come up so far have much appeal.  Anyway, I don't think this
    problem is as critical, because you could just restructure the program
    to give the function a name.

Do you mean something like:

(defmacro dynamic-extent-lambda (lambda-list &body body)
  `(flet ((dummy-name ,lambda-list ,@body))
     (declare (dynamic-extent dummy-name))
     #'dummy-name))

The problem with this is that the scope of the dynamic-extent declaration
is too small, in fact, so small that this is an erroneous program.  That
shows something interesting about the Symbolics sys:downward-function
declaration: the scope that defines the dynamic extent is larger than
the lambda-expression containing the declaration.  Implementationally it's
the surrounding function definition, semantically it would be enough for it
to be the surrounding form.  I guess you're going to require that

  (funcall <foo> (lambda (...) (declare (sys:downward-function)) ...))

be restructured as

  (flet ((dummy (...) ...))
    (declare (dynamic-extent #'dummy))
    (funcall <foo> #'dummy))

which is okay except that it's hard to see how to define a macro that
gives it back a nice non-obtrusive syntax.  Maybe

  (call-with-dynamic-functions
    (funcall <foo> #'(lambda (...) ...)))

Where the call-with-dynamic-functions macro pulls apart its subform
looking for lambda expressions.  The macro doesn't need to be in the
standard, programming stylists can define it for themselves.  It's
still more obtrusive than something inside the lambda, though.

    I think you'd also get the right effect
    by declaring that all the closed-over variables and functions
    referenced in the lambda have dynamic extent.  

I don't think that would mean the same thing.  After all, in this example

  (let ((a <foo>))
    (declare (dynamic-extent a))
    (<bar> #'(lambda (z) (if (<baz> z) (<frob> a) (<borf> z)))))

the dynamic extent declaration for A might mean that by the time the
scope of the declaration is exited, something will happen that will
make <baz> return false from then on, so A will no longer be referenced,
even though the closure that was given as an argument to <bar> will
continue to be called.  You are correct that the environment of the
closure could be discarded, but I don't see how the closure itself
could be discarded; it would have to have indefinite extent.

    So, I don't plan on doing anything about it.

I guess that's probably for the best.