Thomas Sandlaà writes:
> Luke Palmer wrote:
> 
> >But I counter that arguability by saying that you really shouldn't be
> >putting one() in type signatures.  If you want something to be an A or a
> >B, and you're not doing any checking later on in the code, then it's
> >fine if it's both A and B.  If you are doing checking later on, then it
> >should either be in a multimethod or you should factor it out into an
> >abstract type.  Perl's not so keen on what you "should" do, though, but
> >I offer this as solace for those who wish to break the guidelines:
> >
> >    sub foo ( one(Dog, Cat, Horse) $x )
> 
> I think there is a practical application of this. If the classes are
> derived from the same base e.g. Mammal then &foo<Dog^Cat^Horse> cannot
> be called with a Mammal instance but &foo<Dog|Cat|Horse> could. 

Uhh, only if Perl could give a proof that there were no other mammals
than those three.  I wish Perl could do that.

What you probably mean is that &foo<Horse^Bird> could not be called with
Pegasus, but &foo<Horse|Bird> could.  Multiple inheritance restriction.
And now you've lost Liskov substitutability, among other things.  

And I claim that such would not be a good programming practice, or used
very often in real life.  But see above for a possible solution :-)

> I also have another idea where the exclusivity of one() is usefull, but
> I don't know how to write that in Perl6. I want a
> 
> method
>   Mammal::reproduce( Mammal[male^female]                $self:
>                      Mammal[$self.type ^ (male|female)] $partner )
>   returns  Mammal[male^female];

I see where you're going with this.  In this specfic case, I'd probably
do:

    enum Gender { male, female }  # Creates mutually-exclusive roles
    
    multi sub reproduce( Mammal & male, Mammal & female )
        is symmetric
        returns Mammal
    { ... }

But the symmetric bit wouldn't work in the general case.  There's also
this:

    enum Charge { positive, negative }

    multi sub force( Charge $x, Charge ^ ::($left.Charge) $y) {
        "attract"
    }
    multi sub force( Charge $left, ::($left.Charge) $y) {
        "repel"
    }

Which would define semantics independent of the number of Charges there
actually were.  And here we actually did use ^.  But that really doesn't
change my argument at all.

Luke

Reply via email to