chicken-users
[Top][All Lists]
Advanced

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

Re: [Chicken-users] eval environment


From: Matthew David Parker
Subject: Re: [Chicken-users] eval environment
Date: Wed, 31 May 2006 13:52:28 -0400 (EDT)


Thanks Alejandro, I got it working with your info you gave me.

I had to have the user give me the function quoted (which is how they were
going to do it anyways) and then I just made a new quoted function that
looked like this:

`(lambda args
        (let ((self (lambda (cmd) (object-ops ,id cmd))))
                (apply ,userfunction args)))

Then I just "eval" that and it turns into a usable function in which the
user can call "self" to access the object's own variables
and methods (this is for a simple object oriented code I'm making (I
know there are already some out there; I just wanted to make my own
little one)).

Thanks,
Matt

On Tue, 30 May 2006, Alejandro Forero Cuervo wrote:

> > > (define jim
> >     (lambda (fun)
> >         (letrec ((self (lambda (a) (+ 1 a))))
> >             (fun 5))))
> > > (jim (lambda (b) b))
> > 5
> > > (jim (lambda (b) (self b)))
> > Error: unbound variable: self
>
> This happens because only the expression inside the letrec has access
> to the variables it defines.  Since your call to self does not appear
> inside the letrec expression (nevermind the fact that when evaluating
> your program your “(self b)” expression gets evaluated as a result of
> the code inside the letrec).  This is what the experts call “having a
> lexical scope” (rather than dynamical scope).  I'm told original Lisp
> dialects had a dynamical scope, which made the code very difficult to
> follow.  Before I came across Lisp, I had designed a similar language
> with dynamical scope and programs expressed on it had a propension to
> get incredibly messy.  But I digress.
>
> You probably want to do this:
>
>   (define jim
>     (lambda (fun)
>       (letrec ((self (lambda (a) (+ 1 a))))
>         (fun 5 self))))
>
>   (jim (lambda (b f) b))
>
>   (jim (lambda (b f) (f b)))
>
> Of course, your definition can be written with a more idiomatic form:
>
>   (define (jim fun)
>     (fun 5 (lambda (a) (+ 1 a))))
>
> > I was hoping that when "fun" is run and it didn't find "self" in its
> > own little environment, then it would look for it in the next
> > envornment, which would be within the letrec.  Do I have to run eval
> > on '(fun 5) with the current environment somehow?
>
> Think of each environment as a list of symbols, with no such thing as
> "the next environment".  Let (or letrec) copies the entire enviroment
> it appears in, defines its variables in the resulting environment and
> uses it to evaluate its inner forms.  When a procedure defined with a
> lambda form gets called, the environment used to evaluate its body is
> the one that was in use when it was created (with the addition of the
> parameters bound to the values passed in the call) instead of the one
> in use when it was called.  Again, there's no such thing as "the next
> environment".
>
> Scheme implementations are actually smarter than what I described and
> optimize the whole process.  Internally, environments usually do have
> a "next environment".  The whole result, however, is exactly the same
> as what I described above, only faster.
>
> I hope my explanation made sense.
>
> Happy Schemeing! :-)
>
> Alejo.
> http://azul.freaks-unidos.net/
>




reply via email to

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