[Top][All Lists]
[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/
>