Darren Duncan wrote:
Considering this context of comparison operators:
Generic Num Str
=:= # equality (container)
!=:= # negated equality (container)
=== # equality (value, eternal semantics)
!=== # negated equality (value, eternal semantics)
eqv == eq # equality (value, snapshot semantics)
!eqv !== !eq # negated equality (value, snapshot semantics)
!= ne # traditional shortcuts for previous
Remind me again why it's a good idea to have distinct eqv, ==, and eq
operators, and for == to represent the numeric equivalence test
instead of an argument-based equivalence test?
Personally, I'd rather replace ('eqv', '==', 'eq') with either ('==',
'+==', '~==') or just '=='. In the latter case, the current '==' and
'eq' semantics could be preserved by applying the unary '+' or '~'
operators to both operands: as I understand it, "$a == $b" is
semantically indistinguishable from "+$a eqv +$b".
In terms of ordinal types, '>', '<', '>=', and '<=' would be the
"generic" ordinal comparators, and you'd do the same sort of implicit
or explicit type coercion that's done with '=='. Mind you, if you go
with the ('==', '+==', '~==') set of equivalence operators, '+>' and
'+<' would now mean "numerically greater than" and "numerically less
than", respectively, and the shift-right and shift-left operators
would have to be relabelled (e.g., to '+>>' and '+<<').
Likewise, ('cmp', '<=>', 'leg') would become ('<=>', '+<=>', '~<=>'),
or just '<=>'.
(Technically, the existence of '+==' and '~==' would imply the
existence of '?==' for completeness sake; but I can't think of any
reasonable case where '?==' would be used.)
While one can still emulate such operators on generic types using cmp
(whose existence I am very glad for), I would like to propose that
explicit less-than, greater-than etc exist partly for reasons of
parity, so for example, one can take for example 2 Date-representing
types and ask simply if one is earlier than the other, etc, and do
this within the native type.
Agreed. If we assume that the semantics of '==' are non-negotiable, then:
Barring any better suggestions for names of such operators, I suggest
we could follow a precedent laid down by eqv and name them: ltv, gtv,
lev, gev (and also nev if that is useful); and we have visual
consistency in that way.
My problem with these is the alphabet soup mentality that they entail:
'eq' meaning "string-based equivalence" makes _some_ sense because
'eq' is composed of letters and strings are composed of letters; but
even here, there's cognitive dissonance as my brain sees things like
'<=>' vs. 'leg' and has to reconcile them as being essentially the
same thing. Extending this to generic ordinal comparisons aggravates
the problem without even the tenuous "use letters to compare letters"
reasoning to back it up. If you're going to use letter-based
operators, follow the precedence set by 'cmp' (which abbreviates
'compare'): use something like 'before' and 'after' for the generic
versions of '<' and '>'. Better, ditch the letter soup entirely: in
reverse analogy to my original suggestion, use a '*' leading character
to denote the generic comparators: '*<', '*>', '*<=', and '*>='.
On a tangential matter, I believe there should also be generic 'min'
and 'max' type operators for all ordinal types, which would be useful
in list summarizing activities; they would return the value from a
list that would sort first or last.
I don't see the reduce
meta-operator as being applicable to this, since reducing using
less-than eg, will return a boolean result.
And rightfully so: '[<] $a, $b, $c, ...' is asking "are these
arguments in a strictly decreasing order?" which is a perfectly valid
question to ask.
Unlike, say, 'avg' or
'sum', 'min' and 'max' are conceptually generic to all ordinal types.
And they're more readable (and probably faster) than 'sort(...)'
and 'sort(...)[-1]', which would accomplish the same thing.
In effect, we're talking about an Ordinal role, which would package
together the generic ordinal comparators ('*<', '*>', '*<=', '*>=',
and 'cmp'), along with 'sort', 'min', and 'max'.
Tangentially related, I'd like to suggest that the negation
meta-operator be generalized from comparison operators to any binary
operator that returns a boolean value (or possibly even to any
operator that returns a boolean value, so that '!?$x' would mean
"coerce to boolean, then negate its value").
Jonathan "Dataweaver" Lang