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: Sun, 11 Dec 2011 10:51:06 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.92 (gnu/linux)

David Kastrup <address@hidden> writes:

> Marco Maggi <address@hidden> writes:
>
>> David Kastrup wrote:
>>> Hi, if I have something  read that is evaluated later, the
>>> lack  of procedure-environment in  Guilev2 implies  that I
>>> have  to wrap the  stuff in  (lambda ()  ...) in  order to
>>> capture the lexical environment for evaluation.
>>
>> Sorry to step in without  an answer.  What are you trying to
>> do?  What I  understand is that a Scheme  program reads some
>> expressions and tries to evaluate them in a specific context
>> of the program.   Are you looking for a  way to do something
>> like the following chunk I found on the Net?
>>
>> (define x 0)
>> (define clo 
>>   (let ((x 1)) 
>>     (lambda () '())))
>> (local-eval 'x (procedure-environment clo))
>> => 1 
>
> It is more like
> (define (myeval what)
>   (let* ((x 1)
>          (clo (procedure-environment (lambda () #f))))
>      (local-eval (read (open-input-string what)) clo)))
>
> (myeval "(+ x 3)")
>
> Basically a string evaluation of a string that will be captured with
> read-hash-extend in our application.
>
> In practice, _both_ the environment created by (let* ((x 1)) ...) as
> well as the string to be interpreted later are written by the user, but
> they are spliced together at quite different points of time since the
> environment from which the string for myeval gets delivered is available
> only when the definition is being executed, not yet at its definition
> time.
>
> Basically I need to evaluate dynamic code in a given lexical environment
> rather than at top and/or module level.
>
> For a language that is supposed to be a building block for extension
> languages, not really a concept that is all that unusual I would think.

To come back to the original request:
> Is it possible to have a shortcut (make-closure ...) or so for that
> purpose?  The reason is that if ... is a call to a
> procedure-with-setter, (lambda () ...) actually does not cut it for
> capturing the semantics of ..., and I need
> (make-procedure-with-setter (lambda () ...)
>                             (lambda (x) (set! ... x)))

I now implement this more or less as
(define clo #t)
(define (myeval what)
  (let* ((x 1))
     (set! clo (list (cons 'x (lambda () x))))
     (primitive-eval (read (open-input-string what)))))

(myeval "(+ ((assq-ref clo 'x)) 3)")

But of course if I want to translate something like
(set! x 7)
(also when x is something like (myprop k 'g) or so)
with that technique, it falls down again.

So in short, doing that sort of stuff by prewrapping all conceivable
evaluation candidates into (lambda () ...) and doing source code location
association at runtime to figure out which lambda to call is quite icky
and more restricted than actually capturing an environment.

See
<URL:http://git.savannah.gnu.org/gitweb/?p=lilypond.git;a=blob;f=scm/parser-ly-from-scheme.scm;h=0e697d22bda657f3e970efa0281b01a0cd56360c;hb=HEAD>

for the actual current source code that pushes small lambda capsules
into the variable "closures" instead of just capturing a single local
procedure-environment for _all_ parts of the string that is going to be
parsed and interpreted at run time including small Scheme scraps.

This is not hypothetical, but bonafide code running in a production
environment.

-- 
David Kastrup




reply via email to

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