On Fri, Nov 17, 2006 at 04:57:59PM +0100, TSa wrote: : But I don't understand exactly how the coercive semantics : of the numeric and string comparisons are achieved. I assume there : are protos defined with signature :(Any,Any) that coerce the args : to numeric or string and re-dispatch. Right? IIRC, these protos : kick in when dispatch ends in a draw.
That makes sense as a default. In a given lexical scope you might pragmatically instruct the optimizer to assume that $a == $b can be turned into +$a === +$b or some such for efficiency. Or maybe certain types can be coercive that way. But by default we should be assuming that MMD will be relatively efficient. : >>Are the comparison operators available for overloading just like any : >>other operator : > : >Yes. This feature is used often enough in Perl 5 classes, and I'm : >almost certain there are no plans to remove it from Perl 6. : : That sounds good and places the numeric and string comparison ops : close to generic. I think that there will be a role as follows: : : role Order[Str $lt = '<', : Str $gt = '>', : Str $le = '<=', : Str $ge = '>=', : Str $cmp = '<=>' : Str $eq = '==' ] does Compare[$eq] # provides === and eqv : { : enum <Increase(1) Same(0) Decrease(-1)>; : # these two need to be provided : multi infix<before> ( ::?CLASS $one, ::?CLASS $two ) {...} : multi infix<after> ( ::?CLASS $one, ::?CLASS $two ) {...} : # the other ops can be expressed in terms of before and after : multi infix:«$lt» ( ::?CLASS $one, ::?CLASS $two ) : { : $one before $two : } : multi infix:«$gt» ( ::?CLASS $one, ::?CLASS $two ) : { : $one after $two : } : multi infix:«$le» ( ::?CLASS $one, ::?CLASS $two ) : { : $one !after $two : } : multi infix:«$ge» ( ::?CLASS $one, ::?CLASS $two ) : { : $one !before $two : } : multi infix:«$cmp»( ::?CLASS $one, ::?CLASS $two ) : { : if $one before $two { return Increase } : elsif $one === $two { return Same } : elsif $one after $two { return Decrease } : else { return undef } # ? : } : } : : With that you can write : : class Str does Order[|<lt gt le ge leg eq>] {...} : : But that is a bit clumsy and I would like to call the role : as does Order[Str] to get the string comparison ops and as : Order[Num] for the numeric ones. Order[Str|Num] would bring : in both and all other Order[Foo] would just get the generic : before and after. How does one write such a role? I mean you : need to match a type parameter with Str and Num and prepare : the corresponding multis for composition. Well, obviously the multis are declarations, so an ordinary switch isn't going to work. But I think that selection of parameterized roles is naturally also going to involve MMD, and since we have prototype objects like Str and Num already, they naturally can select which role to instantiate as unbound parameters, assuming an appropriate parameter declaration, which could just be role Order[Str] {...} role Order[Num] {...} role Order[Any] {...} Not sure about your junctional type though unless role composition autothreads. Might make sense in this case. As I've mentioned elsewhere I don't really believe in junctional types yet except as constraints (or possibly as shorthand for sets of types, but then we're likely to mess things up later if we do introduce real junctional types). Note that with our undefined prototype object semantics, you can also say Order["pizza"] to get whatever type double quotes are compiling to at the moment, without having to say Order["pizza".WHAT]. But I think we need a better term for typed undefs, since "prototype" is already overloaded in OO literature. We need a better metaphor for these valueless type carriers, I think. Something that is a placeholder for a real one of something. Sigh, "proxy" implies delegation, at least to OOfolk; "token" would have worked well if that term hadn't been thoroughly usurped by the lexerfolk... Larry