Is there syntax in CL for declaring a literal closure to be
dynamic-extent?
For example:
(defun foo (x)
(bar #'(lambda (y) (+ x y))))
Here I wish to declare the lambda closure to be dynamic-extent,
allowing the compiler to for example stack-allocate the x variable.
The one work-around I know of is to give the closure a name via flet,
and then add a dynamic-extent declaration for that name. But can this
be avoided?
--
Frode Vatvedt Fjeld
In article <··············@vserver.cs.uit.no>,
Frode Vatvedt Fjeld <······@acm.org> wrote:
>Is there syntax in CL for declaring a literal closure to be
>dynamic-extent?
>
>For example:
>
> (defun foo (x)
> (bar #'(lambda (y) (+ x y))))
>
>Here I wish to declare the lambda closure to be dynamic-extent,
>allowing the compiler to for example stack-allocate the x variable.
>
>The one work-around I know of is to give the closure a name via flet,
>and then add a dynamic-extent declaration for that name. But can this
>be avoided?
I don't think there's any way to declare an object to be dynamic extent
unless you associate it with a name. Closures are no exception.
I suppose if BAR declares its argument to be DYNAMIC-EXTENT, a smart
compiler could propagate this knowledge to the callers. BAR would have to
be declared INLINE, or be in the same source file as FOO and not be
declared NOTINLINE, for this to be permitted.
--
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
On Fri, 24 May 2002 17:36:44 +0200, Frode Vatvedt Fjeld <······@acm.org> wrote:
>Is there syntax in CL for declaring a literal closure to be
>dynamic-extent?
>
>For example:
>
> (defun foo (x)
> (bar #'(lambda (y) (+ x y))))
>
>Here I wish to declare the lambda closure to be dynamic-extent,
>allowing the compiler to for example stack-allocate the x variable.
>The one work-around I know of is to give the closure a name via flet,
>and then add a dynamic-extent declaration for that name. But can this
>be avoided?
How about:
(defun foo (x)
(declare (dynamic-extent x))
(let ((bar #'(lambda (y) (+ x y))))
(declare (dynamic-extent bar))
...
(call-somewhere bar) ;; passing closure down is okay
... ))
Of course, you cannot return this closure out of foo, because it has
captured a variable which is allowed to evaporate when foo completes.
Since you can't return the closure, you might as well declare the variable bar
to be dynamic-extent as well. This could give your compiler a hint that it
can blow the closure away, or even allocate it in some efficient way.
Closures that can only be passed downward are simpler to implement; even some
poorly endowed languages like Pascal have local functions that can be passed
down yet access the local variables in the parent when called up. The variable
references are not bound to a closure-like object, but directly to the caller's
stack frames display pointers or such like.
Frode Vatvedt Fjeld <······@acm.org> writes:
> Is there syntax in CL for declaring a literal closure to be
> dynamic-extent?
Search the Hyperspec and you shall find.. From Issue
DYNAMIC-EXTENT-FUNCTION:EXTEND:
[...]
Discussion:
Loosemore supports DYNAMIC-EXTENT-FUNCTION:EXTEND.
This proposal does not attempt to address the issue of specifying
dynamic extent for anonymous closures (which is really a special case
of the more general problem of specifying dynamic extent for unnamed
objects of any type). It's possible, although often awkward, to
restructure the program to give the object a name and explicitly
identify its extent.
One possible solution to the problem of dynamic extent for anonymous
lambdas would be to clarify that a reference to a closed-over variable
or function appearing lexically within a FUNCTION form is enough to
cause its value to be "saved" when the FUNCTION form is executed,
regardless of whether or not that reference is actually executed when
the resulting function is called. Then, if all of the closed-over
functions and variables referenced within a closure are declared to
have dynamic extent, the closure could be assumed to have dynamic
extent as well. (More precisely, its maximum extent would be the
intersection of the extents of the closed-over functions and
variables.)
--
Frode Vatvedt Fjeld
> The one work-around I know of is to give the closure a name via flet,
> and then add a dynamic-extent declaration for that name. But can this
> be avoided?
LispWorks has the declaration (DECLARE (DYNAMIC-EXTENT #':SELF)) which
is used by some of the system macros for this purpose
[eg see the expansion of
(with-simple-restart (abort "Exit command level ~D." level))]