Re: Why submethods

2005-11-03 Thread TSa

HaloO,

Luke Palmer wrote:

On 10/29/05, Damian Conway [EMAIL PROTECTED] wrote:


So we need a mechanism that is externally (i.e. from a class interface
point-of-view) a subroutine, but internally has the features of a method (i.e.
has an invocant). Since it's externally sub-like but internally method-like,
we call this useful construct a submethod.


Wouldn't the semantics fall out naturally from
1) beeing a scoped 'our sub'
2) the topic type ^_ of the topic item $_ beeing
   contra-variantly defined to the concrete class type?

Number 1) assumes that a sub definition in a class without my or our gets
a sig of :(Any $_ = CALLER$_, [EMAIL PROTECTED]). The property 2) ensures the
non-inheritance indirectly because an overriding sub in a derived class
would permit the Foo::bar application.

That is Luke's example could read

  class Foo
  {
 has $.data; # creates rw accessor
 our sub bar # sig is :( void: Foo $_, [EMAIL PROTECTED] )
 {
$.data = 23; # Not allowed outside of class scope?
  #  .data = 23; # Or force through accessor?
 }
  }

  my $foo = Foo.new;

  $foo.bar;  # binds $_ := $foo and all member refs through $foo,
 # then calls Foo::bar with empty @_

  say $foo.data;  # prints 23



For most of that, doesn't a private method suffice?

When it doesn't, I feel uneasy about:

class Foo {
submethod bar() { ... }
}
my $foo = Foo.new;
$foo.bar;

If that's externally sub-like, why does it look so much like a method?


Isn't looking like a method more a feature of the dot syntax than anything
else? Does bar($foo) cause the same perception? If my signature assumptions
above are correct then an argumentless bar call without invocant is a
too few arguments error.

If I understand the term 'package dispatch' of Sam Vilain correctly the
package that contains class Foo would maintain a dispatch into class scoped
subs depending on the immediate class---is that the eigenclass?---of the
invocant. That is we could define

  class Bar
  {
 has $.data; # creates rw accessor
 our sub bar # sig is :( void: Bar $_, [EMAIL PROTECTED] )
 {
$.data = 42;
 }
  }

in addition to the Foo from above and then

  sub package_dispatched ($x) { $x.bar }

  my $bar = Bar.new;

  package_dispatched( $foo ); say $foo.data; # 23
  package_dispatched( $bar ); say $bar.data; # 42

But I can understand that Damian thinks that spelling 'our sub' as
'submethod' is good documentation and not a subtlety. OTOH, a 'my sub'
is not considered too subtle. Actually a 'has sub foo ...' form might be
an alternate spelling for 'has .foo = sub ...' and we can drop the
strange word 'submethod' and nicely unify all code types. That is

sub = package dispatch on void
 method = unary dispatch on single invocant item type
  multi = symmetric multi dispatch on invocant tuple type
  or left biased successive single dispatch on invocant list
  or a mix of both
--


Re: Why submethods

2005-10-30 Thread Uri Guttman
 DC == Damian Conway [EMAIL PROTECTED] writes:

  DC But factoring method implementations out into a subroutines is
  DC also extremely annoying, because a subroutine doesn't provide the
  DC internal conveniences that a method does. In particular, it
  DC doesn't have an invocant and so you can't call $.attrs or
  DC .methods. Instead you would have to pass the invocant to the
  DC subroutine call as an argument and then call accessors and methods
  DC explicitly through that argument.

  DC So we need a mechanism that is externally (i.e. from a class
  DC interface point-of-view) a subroutine, but internally has the
  DC features of a method (i.e. has an invocant). Since it's externally
  DC sub-like but internally method-like, we call this useful construct
  DC a submethod.

so it sounds like to me these are methods private to this class. they
can't found by any other class (via inheritance). so what is the
external sub interface for? we can see the need for private worker
methods and even p5 has a convention of marking such subs with a leading
_. 


uri

-- 
Uri Guttman  --  [EMAIL PROTECTED]   http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs    http://jobs.perl.org


Re: Why submethods

2005-10-30 Thread Sam Vilain
On Sat, 2005-10-29 at 17:30 -0400, Stevan Little wrote:
 However, it could also be that the creator of Foo did not intend for  
 subclasses to be able to Just Work, and that the whole idea of Foo  
 is to do a Template Method style pattern in which subclasses must  
 implement the help_process_data submethod in order for things to  
 work. This is an entirely valid usage for a submethod, and in fact, I  
 think it is an excellent way for implementing the Template Method  
 pattern.

Hmm.  I think I much prefer;

  method you_must_implement { ... }

or a trait, perhaps

  method you_must_implement is required;

I think that methods disappearing out of scope in subclasses is just
Nasty And Wrong™, for the exact reason Luke outlined.  Side-effects like
that are just asking for trouble IMHO.

 It is also possible that we could bring over the role idea of  
 required methods and have the same basic principle relate to  
 classes and submethods. If marked as such, a submethod is required to  
 be implemented by a subclass, or class composition fails.
 I think that could be a useful feature which would allow very safe
 re-use along those lines.

Good point, which is why the is required as above would be better.

It seems to me that there's an awful lot of specification going into
these varied types of methods.

  Method Type  Purpose   DispatchVisibility
 ---|--|---|
  $.method()|  external API|  MMD  |  all
  $.submethod() |  refactoring |  package  |  single
  $:private()   |  internal API|  package  |  single

I must admit I also fail to see the difference between submethods and
private methods.  And what do I use for methods that I don't want to
make visible to the world?

Perhaps a more useful definition might be that submethods are only
available on $?SELF (and are still subject to normal dispatch).

Sam.



Re: Why submethods

2005-10-29 Thread Luke Palmer
On 10/29/05, Damian Conway [EMAIL PROTECTED] wrote:
 So we need a mechanism that is externally (i.e. from a class interface
 point-of-view) a subroutine, but internally has the features of a method (i.e.
 has an invocant). Since it's externally sub-like but internally method-like,
 we call this useful construct a submethod.

Hmm, thanks.

For most of that, doesn't a private method suffice?

When it doesn't, I feel uneasy about:

class Foo {
submethod bar() { ... }
}
my $foo = Foo.new;
$foo.bar;

If that's externally sub-like, why does it look so much like a method?

Another thing that scares me with the utility sub point of view follows:

class Foo {
method process_data($data) {
$.help_process_data($data);
}
submethod help_process_data($data) {
$data+1;
}
}

Foo.new.process_data(0); # 1

class Bar is Foo { }

Bar.new.process_data(0); # dies[1]

What???  I didn't change anything yet!  Why does it die?  (This is the
first principle in the journal entry you quoted)

Let's presume that I want to extend Foo by adding a method completely
unrelated to process_data, and I would like its behavior to stay the
same for process_data.  How would I do that?

Luke

[1] Well, it wouldn't, since for Liskov sanity we require that a
method of the same name already exists.  Let's say that Foo's parent
class implemented submethod help_process_data($data) { die }.


Re: Why submethods

2005-10-29 Thread Stevan Little

Luke,

On Oct 29, 2005, at 3:42 PM, Luke Palmer wrote:
Another thing that scares me with the utility sub point of view  
follows:


class Foo {
method process_data($data) {
$.help_process_data($data);
}
submethod help_process_data($data) {
$data+1;
}
}

Foo.new.process_data(0); # 1

class Bar is Foo { }

Bar.new.process_data(0); # dies[1]

What???  I didn't change anything yet!  Why does it die?  (This is the
first principle in the journal entry you quoted)


This is true, but I think that it is easily rectified. A submethod is  
said to have an implicit


  next METHOD unless $?SELF.class =:= $?CLASS

I think we could add onto that and say that in addition to checking  
the invocant's class, we could also check the calling context, and do  
like we do with private methods, and allow things like this to Just  
Work.


However, it could also be that the creator of Foo did not intend for  
subclasses to be able to Just Work, and that the whole idea of Foo  
is to do a Template Method style pattern in which subclasses must  
implement the help_process_data submethod in order for things to  
work. This is an entirely valid usage for a submethod, and in fact, I  
think it is an excellent way for implementing the Template Method  
pattern.


It is also possible that we could bring over the role idea of  
required methods and have the same basic principle relate to  
classes and submethods. If marked as such, a submethod is required to  
be implemented by a subclass, or class composition fails. I think  
that could be a useful feature which would allow very safe re-use  
along those lines.


Anyway, just my 2 cents.

Stevan