[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Nested funcs and "upvalues"
- From: Mark@... (Mark Ian Barlow)
- Date: Thu, 30 Oct 1997 23:28:25 GMT
In message <9710301707.AA01718@exu.inf.puc-rio.br> lua-l@tecgraf.puc-rio.br writes:
> > I doubt the latter is identical to the proposed
> > "foreach" function because of scope, although I could be wrong.
>
> The reason why Lua 3.0 doesn't have nested functions is scope. At one
> hand, it is almost useless to be able to write a nested function without
> access to local variables of the enclosing environment. On the other hand,
> it is well known the problem of "dangling references" to these variables,
> like below:
>
> function f(x) return function (y) return x+y end end
>
> a = f(4)
> print(a(5)) -- where/what is "x"??
I'm not sure why this is a problem. Here, you appear to be returning the
result of a function declaration as the result of the outer function.
What's the problem with making this an error, or at least making it
nil by convention. Surely the unnamed function is a local of f()?
How is this different from writing:
function f(x) return local z end
... which is equally pointless. My question would be where/what is the
call to our unnamed function? In other languages with nested functions you
write things like:
function f(x)
local z = x*x
function g(y)
return z+y -- z looks like a free variable of g(), same as the globals
end
return g(4)+g(7)
end
... and it's all statically checkable when you're compiling f() into
bytecode. You might want to mandate that the nested function be declared
as 'local function g(y)', to emphasise the point to the user. All you're
effectively doing is using your knowledge of where outer-scope locals
belonging to f() are on the stack to treat them like hidden reference
parameters passed into g().
> In Lua 3.1, we are proposing a solution to this problem which we have
> called "upvalues" (don't pay much attention to the name...). An upvalue
> is an expression of the form "%name", which is evaluated when a function
> is *created*, and not when it is called. "name" can be any variable
> visible at the point where the function is created, that is, a local
> variable of the enclosing environment or a global variable. With this,
> the above example could be written as:
>
> function f(x) return function (y) return %x+y end end
>
> Now, when "f(4)" is executed, the inner function is created and the "%x" is
> evaluated to the constant "4"; so "a" will get a function like
> "function (y) return 4+y end", and "a(5)" will give the correct result.
> (Notice that if you write "x+y" in the function body you get a
> compiler error, since 'x' is out of scope; therefore it is not that
> difficult to remember to use the '%'. On the other hand, the '%' reminds
> that this is not an usual variable access.)
Ah, I see. This is "late binding" with a vengance! Will it be efficient
enough for practical use, with every call to f() re-creating the nested
unnamed function?
<snip stuff on foreach>
-- Mark Ian Barlow Non-Linear Control Consultants Ltd.
-----------------------------------------------------------------
Mark@nlcc.demon.co.uk Voice / Fax: +44 (0)1207 562 154