[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: stack level parameter
- From: Mark Hamburg <mark@...>
- Date: Tue, 19 Jan 2010 07:25:36 -0800
On Jan 18, 2010, at 10:47 PM, steve donovan wrote:
> On Tue, Jan 19, 2010 at 8:41 AM, Mark Hamburg <email@example.com> wrote:
>> The summary is "functions don't have environments, call frames (activation records) have environments". (Calling a function preserves the current environment. in-do-end temporarily changes the current environment.)
> So any function called from in-do-end effectively uses the new
> environment. And then for subsequent calls? Does it propagate?
It propagates. The rules are essentially:
* Lookup is done in the environment for the current call frame
* The environment in a new call frame is initialized to be equal to the environment in the preceding (calling) call frame
* in-do-end temporarily changes the environment in the current call frame
>> Certainly it probably pushes harder for using other mechanisms like upvalues to share private data since everything you call will by default be able to see the same globals you can see.
> That's a big difference. So lookup is first current environment, then global?
There is no additional global scope. Globals are looked up in the current environment of the current call frame.
This approach does not introduce a stack of environments akin to the PostScript dictionary stack. One could build such a stack via appropriately constructed environments:
in _G:pushenv( env ) do ... end
in pushenv( env ) do ... end
But that's a construct built on top of the basic mechanisms.
This approach is quite different from what Lua does now but at the same time is fully compatible with most code (under the assumption that setfenv is rare and getting rarer and hence most code was operating in a single shared environment anyway). It has pros and cons depending on what you want to do. One increasingly big pro for me when I look at it is that it is actually moderately easy to describe. It's also much more friendly toward threaded (coroutine) code than uses of setfenv at any time other than immediately after code has been loaded.