Re: nested 'our' subs - senseless?
HaloO, David Green wrote: The assignment happens only when foo() is invoked. However, the variable $*Main::inner is declared at compile-time. Similarly, an "our sub inner" inside foo() would declare the name, but you couldn't call inner() until after running foo() --or bar()-- since you can't call an undefined sub. Do you mean there is an uninitialized variable &*Main::inner that is only bound when either foo or bar are executed? How is the body handled? If there are different bodies in foo and bar, is that a "re-definition of inner" error at compile time? If not, does the body bound to &*Main::inner depend on whether foo or bar was called first? Or does it even toggle? I don't understand what a "sub doing Package" is supposed to do. I think you get the same thing from that last example whether foo and bar are classes or whether they're subs: either way, bar will raise a redefinition error, and "say inner.new.x" will throw a "no 'inner' in scope" error. No, a class definitely does Package. So, my classes foo and bar get two separate classes foo::inner and bar::inner and there is *no* *Main::inner class at all. In particular there should be no re-definition error in bar. This is exactly the behavior I want for subs as well. Regards, TSa. -- "The unavoidable price of reliability is simplicity" -- C.A.R. Hoare "Simplicity does not precede complexity, but follows it." -- A.J. Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: nested 'our' subs - senseless?
On 2008-May-6, at 6:07 am, TSa wrote: Just to ensure that I get the our behavior right, consider sub foo { our $inner = 3; } sub bar { our $inner = 4; # redeclaration error? } say $inner; Does this print 3 even when foo was never called? No, it throws an error about "$inner" not being declared properly -- just as in P5 you'd get 'Variable "$inner" is not imported. Global symbol "$inner" requires explicit package name'. There's no redeclaration error in bar() because it's declaring the name for the first time (in bar's scope, that is), and then (re)assigning a value to $inner, which is fine. If foo said "our Int $inner" and then bar said "our Str $inner", that should be an error though. sub foo { our $inner = 3; } sub bar { our $inner = 4; # fine, assigns or re-assigns $inner } say $inner; # error, name "$inner" not recognised here our $inner; # now the name is available in this scope say $inner; # OK, $inner is undef foo; say $inner; # prints 3 bar; say $inner; # prints 4 IOW, is the assignment in foo a real one that only happens when foo is invoked or is it a pseudo-assignment that initializes the variables as if the whole statement where outside of foo? The assignment happens only when foo() is invoked. However, the variable $*Main::inner is declared at compile-time. Similarly, an "our sub inner" inside foo() would declare the name, but you couldn't call inner() until after running foo() --or bar()-- since you can't call an undefined sub. The consequence of a sub not doing Package is that there are no separate foo::inner and bar::inner classes as in class foo { our class inner { has $.x = 3 } } class bar { our class inner { has $.x = 4 } } say inner.new.x; # error: no inner in scope My personal idea is to unify class and sub by allowing sub to do Package. I don't understand what a "sub doing Package" is supposed to do. I think you get the same thing from that last example whether foo and bar are classes or whether they're subs: either way, bar will raise a redefinition error, and "say inner.new.x" will throw a "no 'inner' in scope" error. -David
Re: nested 'our' subs - senseless?
HaloO, David Green wrote: On 2008-May-3, at 5:04 pm, John M. Dlugosz wrote: What does this mean? our sub outer () { ... our sub inner () { ... } } inner; # defined? > I don't know why it would be any more illegal than "sub foo { our $var... }". The inner sub would be in the package's scope, but the name "inner()" would be available only in outer's scope. So that use of "inner" in the last line would be an error. Why that? I would think assuming that inner has a defined body, the our scope is around the outer somewhere. So the call there should succeed. Or is this not like our works? I assume that sub is not an our scope, BTW. Just to ensure that I get the our behavior right, consider sub foo { our $inner = 3; } sub bar { our $inner = 4; # redeclaration error? } say $inner; Does this print 3 even when foo was never called? IOW, is the assignment in foo a real one that only happens when foo is invoked or is it a pseudo-assignment that initializes the variables as if the whole statement where outside of foo? The latter would actually mean that the line in foo behaves different with or without the our. Without the our, the say would print 3, 4 or undef depending on the call sequence of foo and bar, right? Now how does that compare to sub definition? sub foo { our sub inner { 3 } } sub bar { our sub inner { 4 } # redefinition error? } say inner; My favorite is what the spec already seems to say: a symbol can be declared/defined exactly once in a scope. Usage prior to declaration/definition is an error. Usage of undeclared/undefined symbols is parsed provisionally as if defined/declared with our immediately before this use. Take e.g. class definition in a sub sub foo { our class inner { has $.x = 3 } } sub bar { our class inner { has $.x = 4 } # redefinition error? } say inner.new.x; The consequence of a sub not doing Package is that there are no separate foo::inner and bar::inner classes as in class foo { our class inner { has $.x = 3 } } class bar { our class inner { has $.x = 4 } } say inner.new.x; # error: no inner in scope My personal idea is to unify class and sub by allowing sub to do Package. Regards, TSa. -- "The unavoidable price of reliability is simplicity" -- C.A.R. Hoare "Simplicity does not precede complexity, but follows it." -- A.J. Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan
Re: nested 'our' subs - senseless?
On 2008-May-3, at 5:04 pm, John M. Dlugosz wrote: What does this mean? our sub outer () { ... our sub inner () { ... } } inner; # defined? I think this should be illegal. Nested named subs makes sense for 'my', with the rules of visibility matching the ability to clone the closure. But putting the nested sub into package scope is nonsense. It's really a different clone every time outer is called, and doesn't make sense to call unless outer is already pending. I don't know why it would be any more illegal than "sub foo { our $var... }". The inner sub would be in the package's scope, but the name "inner()" would be available only in outer's scope. So that use of "inner" in the last line would be an error. If inner doesn't actually need anything from outer's block scope, then there is no reason to declare it nested. If you have something specific in mind, like creating specific clones on the fly, then the code in outer can explicitly post the version it creates to the package scope and make it clear exactly when it's being created. E.g. our sub outer (::T $x) { # explicitly create a new multi with every specialization state %didit; unless ++ %didit{ $x.HOW } { my multi sub inner (T $x) { ... } Package::<&inner> = &inner; } } Well, for one thing, "Package::inner" in this example is set at run- time, while "our sub inner" in your first example is declared at compile-time, right? -David
Re: nested 'our' subs - senseless?
Jon Lang dataweaver-at-gmail.com |Perl 6| wrote: On Mon, May 5, 2008 at 6:01 AM, John M. Dlugosz <[EMAIL PROTECTED]> wrote: TSa Thomas.Sandlass-at-barco.com |Perl 6| wrote: No, because {...} is just a declaration. You can give a definition later in the surrounding module/package/class. Within that scope there can be only one definition, of course. I did not mean to use { ... } to mean declaration only, but to show that I omitted the good stuff. In Perl 6, it is not "declaration only" but a body that doesn't complain when it is redefined, so that should not matter. Given that Perl 6 assigns a specific meaning to '{ ... }', it's recommended that examples that omit code instead be written as '{ doit }' or the like. Larry said it should be clear from context, either way something is omitted. And an actual { ... } body does not change the meaning here. It just allows that the sub can be redefined without error, but does not change how it is entered into the symbol tables now. --John
Re: nested 'our' subs - senseless?
On Mon, May 5, 2008 at 6:01 AM, John M. Dlugosz <[EMAIL PROTECTED]> wrote: > TSa Thomas.Sandlass-at-barco.com |Perl 6| wrote: > > > > > No, because {...} is just a declaration. You can give a > > definition later in the surrounding module/package/class. > > Within that scope there can be only one definition, of course. > > > > I did not mean to use { ... } to mean declaration only, but to show that I > omitted the good stuff. In Perl 6, it is not "declaration only" but a body > that doesn't complain when it is redefined, so that should not matter. Given that Perl 6 assigns a specific meaning to '{ ... }', it's recommended that examples that omit code instead be written as '{ doit }' or the like. -- Jonathan "Dataweaver" Lang
Re: nested 'our' subs - senseless?
TSa Thomas.Sandlass-at-barco.com |Perl 6| wrote: No, because {...} is just a declaration. You can give a definition later in the surrounding module/package/class. Within that scope there can be only one definition, of course. I did not mean to use { ... } to mean declaration only, but to show that I omitted the good stuff. In Perl 6, it is not "declaration only" but a body that doesn't complain when it is redefined, so that should not matter.
Re: nested 'our' subs - senseless?
HaloO, John M. Dlugosz wrote: What does this mean? our sub outer () { ... our sub inner () { ... } } inner; # defined? No, because {...} is just a declaration. You can give a definition later in the surrounding module/package/class. Within that scope there can be only one definition, of course. The above just is the same as sub outer () {...} sub inner () {...} unless of course a sub special form also creates an 'our' scope. Well, or I don't understand what 'our' means. I think this should be illegal. Nested named subs makes sense for 'my', with the rules of visibility matching the ability to clone the closure. But putting the nested sub into package scope is nonsense. It's really a different clone every time outer is called, and doesn't make sense to call unless outer is already pending. Sorry, I have the impression you mix up the definition of the inner sub and the creation of invocations of it. Why should an invocation of outer also invoke inner? Or why should that cause a re-definition at runtime or some such. If inner doesn't actually need anything from outer's block scope, then there is no reason to declare it nested. If you have something specific in mind, like creating specific clones on the fly, then the code in outer can explicitly post the version it creates to the package scope and make it clear exactly when it's being created. If I understand that correctly, then it's orthogonal to the issue of scoping. Yet in other words, writing the definition of inner into outer is a matter of taste, like e.g. indentation style. our sub outer (::T $x) { # explicitly create a new multi with every specialization state %didit; unless ++ %didit{ $x.HOW } { my multi sub inner (T $x) { ... } Package::<&inner> = &inner; } } Why should a programmer do a compiler's task? Note that the last line simply overwrites the previous binding of the symbol unless multis have special assignment semantics. So I think it should read &OUR::inner:(T) = &inner; I always thought that a generic sub is about sharing a single body between several types. The above seems to require different bodies for different bindings of ::T. That is the task of a multi sub. Now if you can write a type function that computes the implementations from the input types then you can eagerly call that at compile time or lazily at runtime. In the latter case you can cache the implementations if you like. But you can also forget them as needed because they can be re-computed. Thus dispatch is just an implementation strategy to fit the abstract concept onto a concrete, finite machine. Regards, TSa. -- "The unavoidable price of reliability is simplicity" -- C.A.R. Hoare "Simplicity does not precede complexity, but follows it." -- A.J. Perlis 1 + 2 + 3 + 4 + ... = -1/12 -- Srinivasa Ramanujan