[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Closure of lexical environment in Scheme closures
- From: Brian Casiello <bcasiello@...>
- Date: Thu, 11 Nov 2004 16:12:42 -0500
On Thu, 11 Nov 2004 15:27:48 -0500, Aaron Brown
<aaron-lua@oakadaptive.com> wrote:
> Rich Artym wrote:
>
>
>
> ; Defines and applies function incfoo1 using free variable foo
> ; but overrides (foo 10) with (foo 20) before function is used.
> (let* ((foo
> 10)
> (incfoo1
> (lambda () (+ foo 0.1)))
> (incfoo2
> (let* ((foo ; Let's change foo (as in Lua)
> 20)) ; to try to make incfoo1 use 20.
> incfoo1)) ; Will this closure be affected?
>
> (bar
> 65))
> (incfoo2)) ; No, prints 10.1 because incfoo1 is a closure
> ; which protects it against the change in foo
> ; ----------------------------------------------------------------
>
> A Lua equivalent of that is the following, which acts the
> same way:
>
> do
> local foo = 10
> local incfoo1 = function()
> return foo + 0.1
> end -- incfoo1
> local incfoo2 = function()
> local foo = 20 -- Changing a new foo in
> -- a different scope; doesn't affect
> -- incfoo1.
> return incfoo1()
> end -- incfoo2
> local bar = 65
> print(incfoo2()) -- Prints 10.1 because Lua is lexically scoped.
> end
>
> Instead of thinking of 'local' as being like one of the
> versions of 'let' (I can never remember which version is
> which), think of the space between the 'do' and the 'end' as
> being the 'let', and the individual 'local's are like
> different variables being set within the same 'let'.
>
> --
> Aaron
>
That's equivalent to the lua code I came up with as a translation of
the scheme. I think the point is that the
> (let* ((foo ; Let's change foo (as in Lua)
> 20)) ; to try to make incfoo1 use 20.
in the scheme creates a new binding to foo, unrelated to the one
created by the prior
> (let* ((foo
> 10)
It doesn't assign a new value to the old foo.
So, what if the scheme were changed to
> ; Defines and applies function incfoo1 using free variable foo
> ; but overrides (foo 10) with (foo 20) before function is used.
> (let* ((foo
> 10)
> (incfoo1
> (lambda () (+ foo 0.1)))
(set! foo 12) ; assign a new value to the above bound foo
> (incfoo2
> (let* ((foo ; Let's change foo (as in Lua)
> 20)) ; to try to make incfoo1 use 20.
> incfoo1)) ; Will this closure be affected?
>
> (bar
> 65))
> (incfoo2)) ; No, prints 10.1 because incfoo1 is a closure
> ; which protects it against the change in foo
and the lua to
> do
> local foo = 10
> local incfoo1 = function()
> return foo + 0.1
> end -- incfoo1
foo = 12 -- assign a new value to the above bound foo
> local incfoo2 = function()
> local foo = 20 -- Changing a new foo in
> -- a different scope; doesn't affect
> -- incfoo1.
> return incfoo1()
> end -- incfoo2
> local bar = 65
> print(incfoo2()) -- Prints 10.1 because Lua is lexically scoped.
> end
>
In that case, lua prints 12.1. What would scheme do? (WWSD ;-) I don't
have a scheme interpreter handy, but I suspect it would print 12.1 as
well.
--
Brian
"Clarifying the water with just a little more mud!"