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

Re: SOME (and other mapping functions)



At 12:37 AM 1/5/94 +0000, Philip L. Stubblefield wrote:
>In article <9401040915.aa17365@paris.ics.uci.edu>
>pazzani@pan.ICS.UCI.EDU (Michael Pazzani) writes:
>
>> I prefer to use mapping functions when possible instead of do or loop.
>> However, it appears that I pay a penalty for my stylistic preference
>> because when using some lambda expressions as the function argument
>> (e.g., one that references a lexical variable other than the parameter)
>> space gets allocated.
>>
>> (defun greater-some (x list)
>>     (some #'(lambda(e)(> e x)) list))
>>
>> (time (greater-some 7 '(1 2 3 4 5 6 7 8)))
>> (GREATER-SOME 7 '(1 2 3 4 5 6 7 8)) took 0 milliseconds (0.000 seconds) to run.
>>  40 bytes of memory allocated.
>> T
>>
>> Is there any declaration, etc that can avoid this spoce allocation.
>
>You can use the DYNAMIC-EXTENT declaration to inform MCL that a named
>function has dynamic extent, i.e., that it will never be referenced
>once the establishing construct has been exited (CLtL/2 pp. 42-46).
>Given this declaration, MCL can allocate the function on the stack
>(CLtL/2 pp. 232-236, especially p. 232).  The only disadvantage is that
>you must use FLET or LABELS to define the function so that it has a
>name.  For example:
>
>? (defun greater-some-1 (x list)
>    (flet ((greater-than-x (e)
>             (> e x)))
>      (declare (dynamic-extent #'greater-than-x))
>      (some #'greater-than-x list)))
>[...]

Genera (Symbolics Lisp) has a way for SOME to declare that its first argument
is a function that can safely have dynamic extent. All its built-in
mapping functions contain the appropriate declarations, and
the compiler uses them to automagically stack-cons the closure
in (some #'(lambda (3) (> e x)) list). MCL does not have this feature,
so Phillip's dynamic-extent declaration is the best you can do.

--------------
Bill St. Clair
bill@cambridge.apple.com