lua-users home
lua-l archive

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


On Jan 16, 2010, at 11:21 PM, steve donovan wrote:

> On Sat, Jan 16, 2010 at 7:10 PM, Mark Hamburg <mark@grubmah.com> wrote:
>>> setfenv(function()
>>>    x = 1
>>>    y = 2
>>>    g = function() return x+y end
>>>    z = 2
>>> end,t)()
>>> 
>>> assert(t.g() == 3)
>>> 
>> This, by the way, is a case where dynamic scoping would hurt. t.g() would generally result in an error because definitions for x and y could not be found.
> 
> It works precisely because the new function g acquires the environment
> t. So as long as that's fine, it works (tested on Lua .5.1.4)

My point was that the dynamic scoping -- i.e., environment tied purely to the activation stack -- proposal would not associate an environment with the function created for g and hence when it was later invoked it would not contain the desired environment.

	local t = {}

	in t  do
		x = 1
		y = 2
		g = function() return x + y end
		z = 2
	end

	t.g()

With the 5.2 Lua scoping rules, this is fine. t.g picks up t as its environment. With the dynamic scoping proposal, the call to t.g takes place in whatever the environment was when we entered the chunk which presumably does not provide definitions for x and y.

Maybe this is why PostScript provided the bind operation to complement the dictionary stack. bind takes a function and resolves all of its globals in the current global environment. bound functions can't be repurposed, but they execute a lot faster since they don't need to do lookups for globals. In this example, however, we might want a weaker form of binding in which we resolved where to fetch the value but didn't store the value at the time of the bind so that we could later change x or y and have g adapt appropriately.

Mark