HaloO, this sort of follows up on the 'Re: Junctions again (was Re: binding arguments)' thread. The point I tried to make there is that the optimizer needs the permission to change boolean checks in the prime boolean block controller 'if' and its friends like unless, while etc.
Of course certain contstraints must hold. These are IMHO the axioms of a group with the six compare ops <, ==, >, >=, !=, <= and negation in general. And of course the string equivalents lt, eq, gt, ge, ne, le. These ops are not fundamental, though. I see them more as syntactic sugar for an underlying framework build around <=> and cmp which return one(-1,0,+1). In the numeric case the minus function might suffice. Well and there is the fourth return type undef that somehow must be digested by if and unless. For if the undef right away prevents the entry to the controlled block, but should unless allow entry? I see an undef boolean more like none(true,false) which might nicely prevent entry in both cases, or so. Here is the lattice defining the join and meet replacement operations that the optimizer might use to cut away branches in a truth check. For junctions this has to be deferred until runtime: ( ) # undef, none(-1,0,+1) / | \ / | \ /\ / | \ meet / | \ (-1) (0) (+1) # one(-1,0,+1) "element belt" join |\ / \ /| \/ | \/ \/ | # no intersection of diagonals | /\ /\ | |/ \ / \| (-1,0) (-1,+1) (0,+1) # one( any(-1,0), any(-1,+1), any(0,+1) ) \ | / \ | / \ | / \ | / (-1,0,+1) # any(-1,0,+1) The underlying idea is that the Int type arises similarly Void / | \ / | \ / | \ / | \ Neg Zero Pos |\ / \ /| | \/ \/ | | /\ /\ | |/ \ / \| NonPos NonZero NonNeg \ | / \ | / \ | / \ | / Int NonPos ::= Neg | Zero # (-1, 0) NonZero ::= Neg | Pos # (-1, +1) NonNeg ::= Zero | Pos # ( 0,+1) The full glory of Num arises when the void between the int values is filled with remainders. Doubling then gives the Complex type which drops out of Order ;) Not to mention Quaternions and Octonions! The ternary compare MMD method then has the default entries &compare:(Str,Str,Str) &compare:(Str,Any,Any) &compare:(Num,Num,Num) &compare:(Num,Any,Any) and perhaps and optimized version for &compare:(Int,Int,Int) The first parameter is just used to constrain the choice of MMD. It is usually provided syntactically. The interesting question is how a *heterogenous* list of things is sorted! Because there this first parameter needs to be determined upfront from the other two. In other words the above compare methods might actually look like &compare:( ::X, ::Y : ::Z where { Z does meet(X,Y): } --> one(-1,0,+1) ) with the syntactic parameter last for syntactic reasons. Note the two colons to indicate a two step dispatch! BTW, I would welcome the addition of meet and join lattice operations to the set of Perl6's ops. With the nice operator spelling /\ and \/ respectively: \/ join, supremum, least upper bound, |, any(), .kind, max, union /\ meet, infimum, greatest lower bound, &, all(), .meta, min, intersection Comments? -- $TSa.greeting := "HaloO"; # mind the echo!