guile-devel
[Top][All Lists]
Advanced

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

Re: Anything better for delayed lexical evaluation than (lambda () ...)?


From: David Kastrup
Subject: Re: Anything better for delayed lexical evaluation than (lambda () ...)?
Date: Wed, 14 Dec 2011 09:16:09 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.92 (gnu/linux)

Mark H Weaver <address@hidden> writes:

> Andy Wingo <address@hidden> writes:
>> On Wed 14 Dec 2011 00:00, Noah Lavine <address@hidden> writes:
>>> I haven't really been contributing to this thread, so please take my
>>> opinion with a grain of salt. But it does appear to me that we should
>>> support capturing a lexical environment, as Mark and David describe.
>>>
>>> So I took a look at ice-9/eval.scm....
>>
>> The details of the interpreter's implementation are not public, I'm
>> afraid.  The interpreter does its job, but not quickly, and any change
>> to make it better would involve a change to the environment
>> representation.
>
> I agree that the returned "lexical environment object" should opaque.
> Probably the only operation that needs this object is "local-eval",
> though I'm not sure there's any disadvantage to printing it in
> human-readable form for debugging purposes.

I was actually somewhat surprised that one could not just use "eval"
here and give it the environment instead of a module argument.  It is
not actually obvious from the documentation whether the active module is
part of the environment or not.

To be fair, not much is obvious from the documentation of local-eval
(documented in Guile 1.8, one occurence of "memoized" in this version).

@c snarfed from debug.c:406
@deffn {Scheme Procedure} local-eval exp [env]
@deffnx {C Function} scm_local_eval (exp, env)
Evaluate @var{exp} in its environment.  If @var{env} is supplied,
it is the environment in which to evaluate @var{exp}.  Otherwise,
@var{exp} must be a memoized code object (in which case, its environment
is implicit).
@end deffn

>> Anyway, it's looking in the wrong place.  There is a compiler too.
>
> The most obvious implementation of (capture-lexical-environment) would
> inhibit compilation of any top-level form that contains it.

Well, it probably is less invasive than the equivalent of marking every
local variable (similarly to global ones) as subject to change across
calls.

> Therefore, the only thing the compiler would need to do is detect the
> presence of (capture-lexical-environment), and in that case, abort
> compilation of the entire top-level form.  I guess such a form should
> be "compiled" simply as a call to the evaluator with the entire
> top-level form as its argument.  This would all happen after macro
> expansion, of course.
>
> Does this make sense?

Sounds a bit heavy-handed.  For the use cases in Lilypond, I don't
expect noticeable slow-downs as long as "the evaluator" works with
reasonable performance for an interpreter and is not coded with the "we
have a compiler anyway, so this will only run in exceptional cases and
can be exceptionally slow" frame of mind.

But it does a reasonably simple job, and probably is not significantly
changed from Guile v1, so I don't expect much of a problem here.

So this would basically work for Lilypond.  It would, however, be likely
a good idea to have it in a state where attaching strong-worded warnings
to the documentation is not necessary.

Something like "If an environment is being captured, the enclosing code
can't be optimized (in the current implementation, it is simply left
uncompiled).  So it is a good idea to place performance-critical code in
functions separate from those where you need to capture the
environment." should likely be enough.

-- 
David Kastrup



reply via email to

[Prev in Thread] Current Thread [Next in Thread]