Re: nested 'our' subs - senseless?

2008-05-06 Thread TSa

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?

2008-05-06 Thread David Green

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?

2008-05-06 Thread TSa

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?

2008-05-05 Thread TSa

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


Re: nested 'our' subs - senseless?

2008-05-05 Thread John M. Dlugosz

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?

2008-05-05 Thread Jon Lang
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?

2008-05-05 Thread John M. Dlugosz

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?

2008-05-05 Thread David Green

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



nested 'our' subs - senseless?

2008-05-03 Thread John M. Dlugosz

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.


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;
 }
  }


If anyone wants to show the proper syntax for doing that, I'd appreciate it.


--John