lua-users home
lua-l archive

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


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!"