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!

Reply via email to