Austin Hastings wrote:
> Jonathan Lang wrote:
> > Maybe as an alternative to
> >
> >    role Stringify {must stringify();}
> >    sub print_it (Stringify $thingie) {print $thingie.stringify();}
> >
> > you might be able to say
> >
> >    sub print_it ($thingie must stringify()) {
> >       print $thingie.stringify();}
> >
> > Hmm... there's a certain elegance to being able to specify one or two
> > requirements directly in a signature.
> 
> Indeed. I like the idea of dynamic anonymous roles -- it's more
> behavioral
> than anything else.
> 
>  sub print_it ($thingie must stringify()) {...}
> 
> Definitely gets down to the lowest level quickly, which is nice. Even
> nicer is the ability to use this sort of requirement as kind of an 
> advanced signature: declare exactly what you're going to do. (In other 
> words, your signature may say
> 
>   sub foo(Object $o) {...}
> 
> because you want to accept anything in the hierarchy. But it's nice to
> extend it with
> 
>   sub foo(Object $o must stringify() must isa() must typeof()) {...}

Valid, if wordy.  Roles remain useful in that they provide a more concise
way of handling this if you want it - if you've got a dozen routines that
all C<must isa() must typeof()>, you might be better off defining a role
that makes those demands, and then just use it.  

> This kind of granularity does kind of imply a JavaScript-like ability to
> compose objects, too, no? (If you can compose requirements atomically,
> why not compose capabilities, too?)
> 
>   my $photon does Particle does Wave {...} = spark();

That's where C<but> comes in: 

   my $photon but does Particle does Wave {...} = spark();

would be equivelent to something like

   class _anonymous_photon does Particle does Wave {...}
   my _anonymous_photon $photon = spark();

> > Also: in the first of these two, would classof($thingie) actually have
> > to have Stringify as a role, or would it be reasonable to instead say
> > that classof($thingie) must meet Stringify's demands?  The latter 
> > would require more work on the compiler's part, but would be 
> > considerably more flexible.  
> 
> I prefer the latter. I want to be able to compose requirements on the
> way. I certainly don't want to have to rewrite the core libraries (or 
> extend them all) just to mix in an interface role that they already 
> satisfy.

In principle, I agree with you; in practice, it may not be workable.  

> >  Perhaps "Stringify $thingie" requires that the Stringify role must
> > actually be used, while something like "$thingie like Stringify" would
> > only require that Stringify's demands be met?
> 
> My thought would be that once you have an object in hand, you can do
> with it what you will. But all you get is the object.  

How would you handle the following: 

   role Dog {must bark();}
   role Tree {must bark();}

   class crossPerson {
      method bark() {speak_sharply;}
   }

   class Trog does Tree does Dog {
      method bark() {bark_like_a_trog;}
   }

   multi sub purchase(Dog $mansBestFriend) {...}
   multi sub purchase(Tree $shrubbery) {...}
   multi sub purchase($noisemaker must bark()) {...}

   my crossPerson $jack; 
   purchase $jack; 

   my Trog $spot; 
   purchase $spot; 

Which, if any, of the subs should be called in each case?  Or should the
compiler complain of duplicate definitions?  

=====
Jonathan "Dataweaver" Lang

__________________________________
Do you Yahoo!?
Yahoo! Hotjobs: Enter the "Signing Bonus" Sweepstakes
http://hotjobs.sweepstakes.yahoo.com/signingbonus

Reply via email to