On Thursday, March 13, 2014 7:19:22 PM UTC-5, henrik lindberg wrote: > > > We also have to decide if any of the relative name-space functionality > should remain (i.e. reference to x::y is relative to potentially a series > of > other name spaces ("dynamic scoping"), or if it is always a global > reference when it is qualified. > >
Can you choose a different term than "dynamic scoping" for what you're describing there? It's not consistent with other uses of that term with which I am familiar, and historically "dynamic scoping" has meant something different in Puppet. > The implementation idea we have in mind is that there is one global > scope where all "qualified variables" are found/can be resolved, and > that all other variables are in local scopes that nest. (Local scopes > include ephemeral scopes for match variables). > > Given the numbers from measuring the read ratio, we (sort of already > know, but still need to measure) need a fast route from any scope to the > global - we know that a qualified variable is never resolved by any > local scope so we can go straight to the global scope. (This way > we do not have to traverse the chain up to the "parent most" scope (the > global one). I think that's fine, as long as it's consistent, but it has the potential to present oddities. For example, in the body of class m, can one declare class ::m::a via its unqualified name (e.g. "include 'a'")? If so, then should one not also from the same scope be able to refer to the variables of ::m::a via relative names ($a::foo)? I see two main reasonable alternatives: - class names are always treated as absolute. Class ::m can declare class ::m::a only via its qualified name, and $a::foo is always equivalent to $::a::foo. - class names can be expressed absolutely or relative to the innermost enclosing class scope (~ the current namespace), only, both for class declaration and for variable lookup. Class ::m can declare class ::m::a via its unqualified name, and can refer to the variables of ::m::a via relative names ($a::var). Either approach provides consistency in that any way it is permissible to refer to a class itself, it is also permissible to refer to that class's variables by appending '::varname'. Note that the latter does not require traversing the chain of enclosing scopes, nor looking up names directly in any local scope; rather, it could be implemented as maximum two lookups against the global scope. I expect that we will retain the ability to refer to variables via their unqualified names within some nest of scopes related to where they are declared (e.g. up to the innermost named (class or resource) scope). Given, then, that that form of relative name lookup will be supported, I think generalizing that to classes and resources as well (second alternative) bears serious consideration. On the other hand, those who have commented in the past seem to agree that Puppet's historic behavior of traversing the full chain of nested scopes, trying to resolve relative names with respect to each, is more surprising than useful. I'm on board with that; I'm just suggesting that there may be both room and use for a more limited form of relative naming. Local scopes are always local, there is no way to address > the local variables from some other non-nested scope - essentially how > the regular CPU stack works, or how variables in a language like C work). > > i.e. we have something like this in Scope > > Scope > attr_reader :global_scope > attr_reader :parent_scope > # ... > end > > > The global scope keeps an index designed to be as fast as possible to > resolve a qualified name to a value. The design of this index depends on > the frequency of different types of lookup. If all qualified lookups are > absolute it would simply be a hash of all absolute names to values (it > really cannot be faster than that). > > The logic for lookup then becomes: > - for un-qualified name, search up the parent chain (this chain does not > reach the global scope), if still unresolved, look in global scope. > >From the description alone, I'm not sure how it can be asserted that the chain of local scopes does not reach global scope, unless by the the trivial fact that the global scope is not itself a local scope. What I would hope to see, and perhaps what is meant, is that the lookup stops at local scopes that correspond to classes and resources. In particular, I think it is essential that unqualified class name lookups not be resolved against parent namespaces. That is, in class ::m::a::b, "include 'foo'" must not refer to ::m::a::foo, and certainly not to ::m::foo, but I'd be ok if it could refer to ::m::a::b::foo. As a special (but important) case, in ::m::a::b, "include 'b'" must not refer to ::m::a::b itself, and "include 'a'" should not refer to ::m::a. I'm going to try to digest some more of this over the weekend. Perhaps I'll have more to say on Monday. Such as about scoping function names so that different environments can bind different implementations to the same name, maybe. John -- You received this message because you are subscribed to the Google Groups "Puppet Developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to puppet-dev+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-dev/e5ae6533-f61a-4f12-a94f-2eb2747b268a%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.