Referring to package variables in the default namespace in p6
Hi all, I've spent some of the afternoon wading through A12 and S10 trying to thoroughly understand scope in perl 6, in light of the death of use vars and the addition of class (as well as package & module) namespaces. In the process I came up against some confusion concerning how the default package namespace should work. Currently, pugs does: % pugs -e '$main::foo="foo"; say $foo' foo which contradicts S10, which states: The "::*" namespace is not "main". The default namespace for the main program is "::*Main". This turned out to be an oversight - but there was then confusion as to how one actually refers to variables in the "::*Main" namespace, as if $Foo::bar looks up the ::Foo object and fetches $bar from it, then presumably $*Main::foo should look up the ::*Main object, and fetch $foo from it. However (from #perl6): Arathorn: when you see $Foo::bar, it means looking up the ::Foo object, then fetch $bar from it and ::Foo, just like %Foo, can be lexical or package scoped or global (%*Foo) to restrict the lookup to ::*Foo you can't use the ordinary qualifying syntax, I think. but I may be completely wrong so it sounds as if to get the variable $bar from the global packagename ::*Foo (or just *Foo if disambiguation is not necessary), you'd use $*Foo::bar then. that may be the case, yes. $?Foo::bar means $?bar in Foo:: but $*Foo::bar can't mean $*bar in Foo:: because Foo:: will never contain a $*bar. so it must mean $bar in *Foo:: this is very weird. So the question is: what is the correct syntax for referring to package variables in the default namespace? Also, what is the correct syntax for referring to package variables in your 'current' namespace? $::foo? $?PACKAGENAME::foo? $::($?PACKAGENAME)::foo? %PACKAGENAME::? cheers, Matthew. -- Matthew Hodgson [EMAIL PROTECTED] Tel: +44 7968 722968 Arathorn: Co-Sysadmin, TheOneRing.net®
Re: Referring to package variables in the default namespace in p6
On Tue, 19 Jul 2005, Larry Wall wrote: On Tue, Jul 19, 2005 at 07:25:35PM +0100, Matthew Hodgson wrote: : : So the question is: what is the correct syntax for referring to package : variables in the default namespace? The * looks like a twigil but it isn't really. It's short for "*::", where the * is a wildcard package name, so in theory we could have $=*foo, meaning the $=foo in the *:: package. (But most of the twigils imply a scope that is immiscible with package scope.) So, if I understand this correctly, the conclusion for referring to the default program namespace is $*Main::foo - which is shorthand for $*::Main::foo, which pulls the variable $foo out of the globally-rooted namespace called Main. I'll plonk some tests into pugs to try to steer towards that... In terms of resolving non-fully-qualified namespaces, presumably $Main::foo would work most of the time, assuming that you weren't currently within any package/module/class namespace scopes called Main - as S02 says 'the "*" may generally be omitted if there is no inner declaration hiding the global name.'? : Also, what is the correct syntax for referring to package variables in : your 'current' namespace? $::foo? $?PACKAGENAME::foo? : $::($?PACKAGENAME)::foo? %PACKAGENAME::? That's currently: $OUR::foo right... I guess that goes with $MY:: and $OUTER:: in S06 and their respective hash access methods. I'm very surprised that package variables end up in OUR::, however - because surely they're not necessarily lexically scoped - and the whole point of 'our' was lexical global scoping, right? :/ is being able to: % perl6 -e '{ $*Main::foo = "foo"; } say $OUR::<$foo>' really a feature? Or is OUR:: actually intended to include non-lexically scoped package variables too as a special case? I'm not sure whether $::foo is usefully distinct from $foo these days. It almost seems to imply that ::foo is in type space and we have to dereference it somehow. There's a sense in which :: only implies type space after a name. We somehow seem to have the situation where :: is simultaneously trying to be a leading sigil, a trailing sigil, and a separator. I've tried to wrap my head around all these behaviours of :: and summarize them here for future readers: inevitable corrections more than welcome ;) ::Foo # leading sigil: disambiguates Foo as being in type space $Foo::bar # trailing sigil: indicates preceding term is in type space $Foo::Baz::bar # separator: type space hierarchy separator ::($foo) # special case leading form which behaves more like the # trailing sigil & separator form for building up type # terms from expressions, as ($foo):: would be ambiguous. I assume that I am correctly following your lead in referring to package/module/class namespaces as 'type space' here... As regards $::foo, making a special case for it being a synonym for $*Main::foo be yet another complication entirely without precedent in the current behaviour. But then again, using $::x in the past as a quick way to disambiguate between lexical & package variables in simple package-less scripts was quite handy... thanks hugely for the quick feedback :) M.
Re: Referring to package variables in the default namespace in p6
On Wed, 20 Jul 2005, "TSa (Thomas Sandlaß)" wrote: Matthew Hodgson wrote: I'm very surprised that package variables end up in OUR::, however - because surely they're not necessarily lexically scoped - and the whole point of 'our' was lexical global scoping, right? :/ Sorry, what is 'lexical global scoping' e.g. compared to non-global lexical scoping? Is it not so, that conceptually a program that is loaded from several files can be seen as a complete nesting of all used packages, modules, classes etc. where the file scopes are replaced by pairs of braces? Sure - a nesting of namespaces as opposed to lexical pads. The care takers of OUR:: are the package, module, class and role meta classes while MY:: is handled by everything in braces basically. Well, when I saw the pseudo-namespace OUR::, my first thoughts were that its contents would be the current our()d variables which we can access in a non-qualified manner in our current lexical pad. Not that it was actually all the package variables in our current namespace, be they currently lexically accessible or not. Surely this pseudo-namespace should be called PACKAGENAME:: or something rather than OUR:: in order to avoid this confusion? Whilst: % perl -we 'use strict; { our $foo = "foo"; } warn $::foo' makes sense in perl 5, I still maintain that: % perl6 -we '{ our $foo = "foo"; } warn $OUR::foo' is kinda confusing ;) I've tried to wrap my head around all these behaviours of :: and summarize them here for future readers: inevitable corrections more than welcome ;) Foo # leading sigil: disambiguates Foo as being in type space $Foo::bar # trailing sigil: indicates preceding term is in type space $Foo::Baz::bar # separator: type space hierarchy separator ($foo) # special case leading form which behaves more like the trailing sigil & separator form for building up type terms from expressions, as ($foo):: would be ambiguous. Isn't it easier to say that :: is a unary/binary, right associative pseudo operator with the following properties: 1) whitespace around :: is not allowed whitespace to the left stops outwards scanning this allows ?? :: 2) its rhs is the leaf name you want to refer to 3) the lhs is the namespace path to that leaf 4) a * wildcard starts lookup from the root (for details of *Foo versus *::Foo see above) 5) parentheses cause symbolic runtime lookup, otherwise the lookup is at compile time and needs pre-declared names because there are no barewords 6) a sigil determines the type you want to refer to: no sigil means autoderefed---that is called---Code whitespace means a type (if more than one leaf matches because the name is overloaded the least upper bound (lub = any type junction) supertype is returned. These rules are all fair enough - but they are then ambiguous for $::Foo. Is that the leaf name variable Foo in your current (innermost) namespace? Or is it an attempt to dereference the disambiguated type Foo? Or is it like perl5, shorthand for $*Main::Foo? Is there any reason why $::Foo could not do both, and not start by searching your current namespace for a variable called $Foo... and then start searching your current namespace hierarchy for a type called Foo and try to dereference it (whatever that does)? Presumably it should behave in precisely the same way that $::('Foo') does for sanity - does that search the current namespace for just types or variables or both? M.
Re: Referring to package variables in the default namespace in p6
On Thu, 21 Jul 2005, "TSa (Thomas Sandlaß)" wrote: Matthew Hodgson wrote: These rules are all fair enough - but they are then ambiguous for $::Foo. Is that the leaf name variable Foo in your current (innermost) namespace? It is not ambiguous if the sigil rules that expression. I assume that the parameters of a sub are definining innermost names to their body: sub foo ( $param ) { say $::param; # prints argument bound to $param say $param; # same say $OUTER::param; # prints value of result of a lookup # that starts outside of sub foo # but my ::param $x = ::param.new; # look for param type info Okay; if this is how $::foo works, then it makes a whole lot of sense :) Or is it an attempt to dereference the disambiguated type Foo? What is the use of reference to a type? I have no idea - I was going on the basis of Larry's comment concerning $::Foo looking a bit like an attempt to dereference ::Foo. In other words you just can't use a sigiled expression where a type is expected: my $::Foo $x; is just a syntax error. This is why I regard the sigils as type mark-up. That means writing $Foo or $::Foo just tells the compiler that you want to handle the item Foo. Is there any reason why $::Foo could not do both, and not start by searching your current namespace for a variable called $Foo... and then start searching your current namespace hierarchy for a type called Foo and try to dereference it (whatever that does)? This is my position if I read the double negation correctly. Oops - the double negative was a typo there; apologies... even then, I think I understand that you agree that $::foo simply means an outwards search of your current namespace scope for a variable called $foo. Sorry if that wasn't clear initially. But I hope the above rants clarify what I mean. I hope that i'm on the right page now - thank you for taking the time to clarify :) Presumably it should behave in precisely the same way that $::('Foo') does for sanity - does that search the current namespace for just types or variables or both? Not for sanity. $::Foo is just syntactic sugar for $::('Foo') because 'Foo' is a compile time constant. But $::( some_calculated_name ) might not in general be evaluateable at compile time and thus forces the compiler to generate symbolic lookup code which 1) calls some_calculated_value 2) starts lookup with the stringified return value Note that because of the $ sigil it looks for something that does the Scalar/Item role! We can consider the sigils as lookup filters. I guess $::('Foo') was a bad example - $Foo="Foo"; $::($Foo) would have been better at illustrating my point - which was that if $::($Foo) searches outwards through namespace for a variable whose name is held in $Foo, then $::Foo should end up referring to the same variable. Otherwise the two $::... forms would be horribly confusingly different in their behaviour, and I (and other future legions of newbies) would despair. :) thanks again; M.
Re: Referring to package variables in the default namespace in p6
On Thu, 21 Jul 2005, "TSa (Thomas Sandlaß)" wrote: Matthew Hodgson wrote: I guess $::('Foo') was a bad example - $Foo="Foo"; $::($Foo) would have been better at illustrating my point - which was that if $::($Foo) searches outwards through namespace for a variable whose name is held in $Foo, then $::Foo should end up referring to the same variable. Let me restate that in my own words. You mean that a symbolic runtime lookup $::($Foo) with the value of $Foo at that time shall be cached in the immediatly surrounding namespace and that cached ref is then accessable through the syntax $::Foo? Hm, I seem to be making a bit of a pigs ear of explaining myself here, but thank you for bearing with me. What I was trying to confirm was that if you create a variable in your immediately surrounding namespace: $*Main::foo = 'bar'; # (assuming you are in the default namespace) and a variable containing the string 'foo': my $varname = 'foo'; then the principle of least surprise suggests to me that the result of evaluating $::($varname) should be identical to that of evaluating $::foo. I wasn't getting hung up on whether $::($varname) should somehow be cached to avoid a dynamic lookup based on the current value of $varname every time. And I assume that if $*Main::foo hadn't been created, assigning to $::($varname) would create it as expected (again, without any caching of $varname). My confusion initially stemmed from chat on #perl6 about $::Foo and $::('Foo') being Very Different Things - and the fact that there was ever any confusion over whether $::foo was your 'closest' $foo variable or something else. BTW, I wonder if $::() means $::($_) :) hehe; that would almost be nice... :) Otherwise the two $::... forms would be horribly confusingly different Sorry, they are the same thing: namespace lookup. But without ::() the compiler does it at compile time for bareword resolving. Without a sigil in front the result can be used where a type is expected: for ("blahh", "fasel", "blubber") -> $name { ($name).new; } We can consider the equivalence of $foo and $::foo as TIMTOWTWI. I dought that assigning two different meanings just because their are two syntactical forms is a good idea. Fantastic - all my fears are allayed, then. $::foo is $::('foo') is $foo (assuming it hasn't been our'd or my'd), and all is well in the world. [lest] I (and other future legions of newbies) would despair. :) You consider yourself a 'legion of newbies' ;) Well, earlier I may have been legion, but I think i've regained my karmic balance a bit now... ;) cheers; M.