Re: generic ordinal-relevant operators

2006-11-17 Thread TSa

HaloO,

Smylers wrote:

TSa writes:


... one question remains that might actually make Duncan's proposal
pointless.


Didn't Larry actually accept Darren's proposal and add the Cbefore and
Cafter operators?


He did. 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.



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 infixbefore ( ::?CLASS $one, ::?CLASS $two ) {...}
multi infixafter  ( ::?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.


Regards, TSa.
--


Re: generic ordinal-relevant operators

2006-11-17 Thread Larry Wall
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 infixbefore ( ::?CLASS $one, ::?CLASS $two ) {...}
: multi infixafter  ( ::?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


Re: generic ordinal-relevant operators

2006-11-16 Thread TSa

HaloO Larry,

you wrote:

You guys should read The Search for the Perfect Language, by Umberto Eco.
It would disabuse you of the notion that perfect orthogonality is possible
or even desirable.


I'm sorry if my contributions to this thread are annoying. But one
question remains that might actually make Duncan's proposal
pointless. Are the comparison operators available for overloading
just like any other operator or is the casting of the operands
performed *before* dispatch sees the actual types? If overloading
is possible than the numeric and string comparison should be
adhered to in spirit.

I can imagine to have a role Order that composes the comparison ops.
E.g. Order[Num] composes , , =, = and =. Order[Str] composes
lt, gt, ge, le and leg. You get both when composing Order[Num|Str].
The generic Order[Foo] would compose before, after, their negations
and cmp. Order would imply Comparable, that is the equality checks
===, eqv, == and eq. Comparable would take the same type parameters
as Order and compose different sets of ops accordingly.

The binding check =:= is hardly useful for overloading because it
operates on the namespace level.

Regards, TSa.
--


Re: generic ordinal-relevant operators

2006-11-16 Thread Smylers
TSa writes:

 ... one question remains that might actually make Duncan's proposal
 pointless.

Didn't Larry actually accept Darren's proposal and add the Cbefore and
Cafter operators?

 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.

Smylers


Re: generic ordinal-relevant operators

2006-11-16 Thread Jonathan Lang

Smylers wrote:

Didn't Larry actually accept Darren's proposal and add the Cbefore and
Cafter operators?


Yes.  He also accepted the proposal to add min and max operators -
although I'm unsure why they weren't included as functions/methods
instead.  It seems more natural to me to say 'max($a, $b, $c)' or
'($a, $b, $c).max' instead of '[max] $a, $b, $c' or '$a max $b max
$c'.  Although it _does_ allow for such things as '$a max= $b' (which
is shorthand for something like '$a = $b if $a  $b').  And I suppose
that 'infix:max' doesn't stop you from having 'max' as well.

--
Jonathan Dataweaver Lang


Re: generic ordinal-relevant operators

2006-11-16 Thread Paul Seamons
 Yes.  He also accepted the proposal to add min and max operators -
 although I'm unsure why they weren't included as functions/methods
 instead.  It seems more natural to me to say 'max($a, $b, $c)' or
 '($a, $b, $c).max' instead of '[max] $a, $b, $c' or '$a max $b max
 $c'.  Although it _does_ allow for such things as '$a max= $b' (which
 is shorthand for something like '$a = $b if $a  $b').  And I suppose
 that 'infix:max' doesn't stop you from having 'max' as well.

In true chicken and egg fashion:

  Which comes first the operator or the function.

Do you define infix:max in terms of max or vice versa.  My guess
is the operators should win because there could be some low-level shenanigans 
that optimize things.  But maybe not.

Paul


Re: generic ordinal-relevant operators

2006-11-15 Thread TSa

HaloO,

Jonathan Lang wrote:

I agree that the distinctions between the five different equality
tests (=:=, ===, eqv, ==, eq) are rather difficult to grasp (I'm still
having trouble getting the difference between '===' and 'eqv', and
would appreciate some help).


So let's try to join our half knowledge, then! Here's my half.

The deep comparison operator eqv is relatively easy. It traverses
references until it has evaluated complete tree values that are
then compared. I'm unsure if e.g. 0..Inf eqv 0..Inf works without
looping endlessly. IOW, does eqv cause lazy values to be calculated
or can it compare them shallowly?

The === operator is supposed to stop traversal when it hits a container
and use the identity of the container. So with +(@a,@b) == 2 because the
arrays aren't flattened (are they?) we get

  @x = (@a,@b); # @x has two arrays as content, I hope.
  @y = (@a,@b); # Or does that need \(@a,@b)? If yes, add it.
  say @x === @y; # true irrespective of contents of @a and @b

I  hope that helps and is correct in the first place.



By changing things around so that what's currently called 'eqv' is
instead called '==', and the current '==' and 'eq' get replaced by
'+==' and '~==' (which would be diagonal) or are removed altogether
(which would be orthogonal),


I would use orthogonality in the sense that it spawns a new dimension.
That is the first dimension is the comparison operator ,,=,=,==
and the second dimension is the choice of type enforcement: none, +,
~ or ?. BTW, we should also allow meta ! versions !, !, != and !=
for completeness. How about the int context enforcer? I can think of
int== being useful.

Another advantage of the meta operator approach is that it can be
applied for other operators as well. So one can always force dispatches
to infixop(Num,Num) with +op etc.



the analogies between the various
equality tests become more intuitive: '==' and '===' are different
variations of 'test for equality of value' (again, I'm not quite clear
on how they differ),


You mean == becomes what === is right now and the new === takes over
the deep semantics of eqv. All letter ops are dropped. Right?

Well, for now we have got two new letter ops before and after. I wonder
how much code will be written with these just to become independent of
the enforcement of numeric comparison. This actually raises the question
if the numeric comparison operators can just be overloaded and
dispatched as normal. IOW, is the numeric comparison achieved in
standard Perl 6 by providing a :(Num,Num) target and a corresponding
proto that enforces Num and re-dispatches? Or is the numeric enforcement
more hard-wired, e.g. in the parser?

Regards, TSa.
--


Re: generic ordinal-relevant operators

2006-11-15 Thread Larry Wall
You guys should read The Search for the Perfect Language, by Umberto Eco.
It would disabuse you of the notion that perfect orthogonality is possible
or even desirable.

Larry


Re: generic ordinal-relevant operators

2006-11-14 Thread TSa

HaloO,

Smylers wrote:

BTW, could we define that the arithmetic shift ops do just that,
whereas the string ones do logical shift?  And in addition that for
the bit inversion +^$a == -1 - $a holds? Note that -1 == +^0.


Does that assume a two's complement system?  Is that a safe assumption
to make about everywhere Perl 6 will run?  (Is it even a safe assumption
to make about Perl 5?)


Well, there are two ways of conduct. Either the spec prescribes the
behavior on the language level or it leaves it undefined. The former
should go with the equalities I gave, the latter is a bad idea for a
high level language. I mean letting platform details shine through
only makes it convenient for the implementor but harder for users.



Note further that in infinite precision the arithmetic shift left
maintains the sign ...


Do we expect Perl 6 to be running on infinite-precision systems?


Well, IIRC the Int type is conceptually infinite. IOW,

  my Int $i = 0;
  while ++$i { say $i}

should die because of memory exhaustion not end up in a tight
endless loop that wraps around at the max integer. So arithmetic
shift left should preserve sign.

There are other arithmetic properties that I would expect from
a high level language: absence of zero divisors, proper modulo
and integer division including remainder, etc.


Regards,
--


Re: generic ordinal-relevant operators

2006-11-13 Thread TSa

HaloO,

Darren Duncan wrote:

For the record, my preference is to have the generics be the shortest,
[==,!==,=,,,=,=], and use [+,~] prefixes for Num or Str casting
versions.  And lengthen the bit-shift operators to use thin-tailed
arrowheads as you suggested.


I like this proposal for its orthogonality. And it allows to introduce
some more binary boolean functions:

  ?  inhibition?  reverse inhibition
  ?= implication   ?= reverse implication (dual of the above)
  ?== equivalence (dual of xor)

The only ones we lack then are nand ! and nor !|| :)
But they fall out naturally from the meta boolean negation
---which means equivalence might be spelled !^^ as well.
The low precedence versions might be spelled inh, rinh, imp and rimp.
Hmm, and eqv ;)


BTW, could we define that the arithmetic shift ops do just that,
whereas the string ones do logical shift? And in addition that for
the bit inversion +^$a == -1 - $a holds? Note that -1 == +^0. Note
further that in infinite precision the arithmetic shift left maintains
the sign in two's complement representation and we get the equality
$a +- $n == $a * 2**$n where Int $n = 0. In this I assume a big
endian representation. Hmm, and since + indicates numeric not integer
we could even demand $a +- $n == $a / 2**$n where Int $n = 0. Well,
and we could shift with non-Ints through these equalities. Not to
mention the introduction of a base used in the shift provided as adverb:
$a +-:10 $n == $a * 10**$n.


Regards, TSa.
--


Re: generic ordinal-relevant operators

2006-11-13 Thread Smylers
TSa writes:

 Darren Duncan wrote:

  For the record, my preference is to have the generics be the
  shortest, [==,!==,=,,,=,=], and use [+,~] prefixes for Num or
  Str casting versions.  And lengthen the bit-shift operators to use
  thin-tailed arrowheads as you suggested.
 
 I like this proposal for its orthogonality.

Bzzzt, wrong language!

  But Perl isn't an orthogonal language, it's a diagonal language.

  http://www.oreilly.com/catalog/pperl2/excerpt/ch01.html

For what it's worth, I don't like the proposal because I was already
having trouble getting my head round the number of different operators
for asking is this thing at least vaguely like this other thing.

Please can proposals for new operators (not just operators, for that
matter) be supported by examples along with the form:

  Look at this awkward code (which could plausibly occur in the wild),
  and look how less awkward the code is when rewritten using my proposed
  operator.

 And it allows to introduce some more binary boolean functions:

Woo, _more_ binary boolean functions -- what a boon!

   ?  inhibition?  reverse inhibition
   ?= implication   ?= reverse implication (dual of the above)
   ?== equivalence (dual of xor)
 
 The low precedence versions might be spelled inh, rinh, imp and rimp.
 Hmm, and eqv ;)

Personally I choose to use a language such as Perl in preference to,
say, 6502 Assembly Language, to avoid operators being non-intuitive
sequences of three letters.

 BTW, could we define that the arithmetic shift ops do just that,
 whereas the string ones do logical shift?  And in addition that for
 the bit inversion +^$a == -1 - $a holds? Note that -1 == +^0.

Does that assume a two's complement system?  Is that a safe assumption
to make about everywhere Perl 6 will run?  (Is it even a safe assumption
to make about Perl 5?)

 Note further that in infinite precision the arithmetic shift left
 maintains the sign ...

Do we expect Perl 6 to be running on infinite-precision systems?

Smylers


Re: generic ordinal-relevant operators

2006-11-13 Thread Jonathan Lang

Smylers wrote:

Bzzzt, wrong language!

 But Perl isn't an orthogonal language, it's a diagonal language.

 http://www.oreilly.com/catalog/pperl2/excerpt/ch01.html


In the section quoted, it was indicated that orthogonal and
diagonal are being used to mean minimalist and loaded with
special-purpose tools (by analogy to move left, then up vs. go
straight to your target).  However, the sense that I'd use
orthogonal in this case is similarly-named operators perform
similar tasks, and differently-named operators perform different
tasks - i.e., change part of the name in a certain way, and the
functionality changes in a predicatable manner.

IOW, it's all about organizing your toolkit so that you can easily
find the right tool - whereas the meaning referred to above is more
akin to using a swiss army knife instead of a toolkit.


For what it's worth, I don't like the proposal because I was already
having trouble getting my head round the number of different operators
for asking is this thing at least vaguely like this other thing.


I agree that the distinctions between the five different equality
tests (=:=, ===, eqv, ==, eq) are rather difficult to grasp (I'm still
having trouble getting the difference between '===' and 'eqv', and
would appreciate some help).  Part of the problem, however, is that
the names chosen aren't always clear on what the differences are.
Sure, there's the analogy between the '=:=' comparison and the :=
assignment (i.e., binding) - so it's obvious to me that '=:=' is an
identity test (are these two variables bound to the same thing?),
just like ':=' means bind this variable to that thing.  But beyond
that, confusion reigns.  The similarity between 'eqv' and 'eq' implies
a similarity to their operations that isn't there; likewise with '=='
and '==='.  IOW, 'eqv' is not to '===' as 'eq' is to '=='; nor is
'eqv' to 'eq' as '===' is to '=='.  And '==' means more than just do
these two variables have the same value? as one would suppose by
analogy to '=' (assign a value to the variable) - it means do these
two variables have the same _numeric_ value?.

By changing things around so that what's currently called 'eqv' is
instead called '==', and the current '==' and 'eq' get replaced by
'+==' and '~==' (which would be diagonal) or are removed altogether
(which would be orthogonal), the analogies between the various
equality tests become more intuitive: '==' and '===' are different
variations of 'test for equality of value' (again, I'm not quite clear
on how they differ), while '+==' and '~==' (if included) are like
'==', except that they qualify their arguments as numbers or strings
before testing (in analogy to the unary + and ~ prefix operators).

--

The strongest argument that I can see _against_ redefining '==' to
mean 'generic equivalence' is that it has a long history of meaning
numeric equality in perl pre-6 - which is why I included an
alternate proposal that leaves all existing operator names unchanged.


Please can proposals for new operators (not just operators, for that
matter) be supported by examples along with the form:

 Look at this awkward code (which could plausibly occur in the wild),
 and look how less awkward the code is when rewritten using my proposed
 operator.


Not quite following the letter of your request, but hopefully
capturing its spirit:

I don't like the fact that three very different operator names (cmp,
=, leg) all mean subtly different variations of the same thing (what
do legs have to do with comparisons?).  I'd rather have it such that
similar operations (e.g., determine the order between these two
terms) have similar operators - thus, (=, +=, ~=) instead of
(cmp, =, leg).  I'm hoping to either regularize the set of
comparison operators by banishing letter-soup versions as described
above, or to streamline it by ditching the implicit-coercion forms
entirely: under this minimalist version of the proposal, if you want
to ensure a numeric comparison between $a and $b, you'd say '+$a =
+$b'; and a string comparison would be '~$a = ~$b'.  Under the
organized toolkit version, they'd be $a += $b and $a ~= $b,
respectively.

--

I have a problem with extending the numeric-vs-string comparisons idea
to include boolean comparisons, and then using those as logical
operators: my problem is that the resulting operators start looking
less like operators ('→') and more like line noise ('?='), and they
aren't very intuitive (logical implication generally is not thought of
as an ordinal comparison of truth values, and I'd expect an awful lot
of people to type something like '?-' or '?=' and expect it to mean
implication).  In addition, precedence and associativity don't
neccessarily match up correctly: these kinds of logical operators
would have a higher precedence than , and would be list-associative.

If you're going to add more logical operators (which I don't have much
of a problem with, other than failing to see enough utility in them
for the effort), I'd rather 

Re: generic ordinal-relevant operators

2006-11-11 Thread Jonathan Lang

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.


Agreed.


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(...)[0]'
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


Re: generic ordinal-relevant operators

2006-11-11 Thread Darren Duncan

At 5:24 PM -0800 11/11/06, Jonathan Lang wrote:

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 '='.

snip

  Better, ditch the letter soup entirely: in
reverse analogy to my original suggestion, use a '*' leading character
to denote the generic comparators: '*', '*', '*=', and '*='.


I like that proposal a lot, in principle, as it gives us a lot more 
flexability and visual consistency.  I hope that @Larry can get 
behind something like it.


One detail to work out is whether we use * etc or  etc for the 
generic.  Either option has its advantages or disadvantages.


(Whatever's chosen and any renaming fall-out from that, I don't think 
a main operator can contain a  or  like your bit-shift examples 
since those could be confused with hyper-operators.)



(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.)


I don't see that it would be a bad thing.  Even if little used, it 
does make conceptual sense.  ?== checks if both arguments are the 
same truth-wise, and !?== checks if they are different.  Assuming we 
defined for repeatable ordering purposes that False  True (which is 
consistent with any common string or numifications of booleans), then 
? et al produce predictable results.



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 ''.


I agree.  And in fact, once we have a third column of order-determing 
operators rather than just Num + Str, the arrangement of some 
alphabetic and some not comes to look positively ugly.  So better to 
make them all alpha or all non, and it would seem non is better.  So 
== and  and so on for all comparing operators.  (And as an aside, we 
get rid of !ne.)



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'.


Yes.  And I was thinking about an Ordinal role before too.

Logically, some types are ordinal (eg, numbers (except complex?), 
strings, dates), or could be assigned a canonical ordinal form (eg, 
booleans, bits) and some are simply not ordinal (probably eg, a 
polygon or a collection type).


So, while it could make sense to have an Ordinal role, which types 
individually can .does(), and only those have , , =, =, =, min, 
max, sort, etc, there is the question about how to handle types that 
don't .does() Ordinal in some generic situations.  Either they fail, 
or there is some sort of fallback provided by Object, such as they 
end up sorting on their memory addresses; but in the latter case, we 
don't need an Ordinal role because every type will be doing it in 
some fashion or other due to Object's defaults.



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).


If I'm not mistaken, the 

Re: generic ordinal-relevant operators

2006-11-11 Thread Jonathan Lang

Darren Duncan wrote:

Jonathan Lang wrote:
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 '+').

-snip-

   Better, ditch the letter soup entirely: in
reverse analogy to my original suggestion, use a '*' leading character
to denote the generic comparators: '*', '*', '*=', and '*='.

I like that proposal a lot, in principle, as it gives us a lot more
flexability and visual consistency.  I hope that @Larry can get
behind something like it.


Note that this is two competing suggestions: one where '==' means
'generic equivalence', '+==' means 'numeric equivalence', and '*=='
means 'string equivalence'; and another where '*==' means 'generic
equivalence', '==' means 'numeric equivalence', and 'eq' means 'string
equivalence' (with '', '', etc. following suit).  The goal of the
second proposal is to leave existing operator names unchanged, while
the goal of the first proposal is to provide a consistent and
intuitive naming convention.


One detail to work out is whether we use * etc or  etc for the
generic.  Either option has its advantages or disadvantages.

(Whatever's chosen and any renaming fall-out from that, I don't think
a main operator can contain a  or  like your bit-shift examples
since those could be confused with hyper-operators.)


Yes and no; binary hyper-operators require double arrows on both
sides, so it's possible that the parser _could_ distinguish
double-angle bit-shift operators from hyper-operators.  Still, for the
sake of clarity, I could see basing bit-shifting off of thin-tailed
arrowheads: '+-' and '+-'.  Note that this isn't a problem with the
'*' model: '*' would be a generic less-than; '' would be a numeric
less-than; 'lt' would be a stringified less than; '+' would be a
numeric bit-shift; and '~' would be a string-based bit-shift.  No
ambiguity.


(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.)

I don't see that it would be a bad thing.  Even if little used, it
does make conceptual sense.  ?== checks if both arguments are the
same truth-wise, and !?== checks if they are different.  Assuming we
defined for repeatable ordering purposes that False  True (which is
consistent with any common string or numifications of booleans), then
? et al produce predictable results.


True enough.  It's not _much_ of a mark in favor of the 'consistent
and intuitive naming convention' proposal; but it's a mark in its
favor nonetheless.


And in fact, once we have a third column of order-determing
operators rather than just Num + Str, the arrangement of some
alphabetic and some not comes to look positively ugly.  So better to
make them all alpha or all non, and it would seem non is better.  So
== and  and so on for all comparing operators.  (And as an aside, we
get rid of !ne.)


Another mark in its favor... :)

The two biggest marks against it are what it does to the bit-shift
operators (which isn't much of an issue IMHO; they're already changed
from perl5) and the drastic change from perl5-style thinking, where
numeric comparisons are effectively the default (which could very well
be a show-stopper).


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'.

Yes.  And I was thinking about an Ordinal role before too.

Logically, some types are ordinal (eg, numbers (except complex?),
strings, dates), or could be assigned a canonical ordinal form (eg,
booleans, bits) and some are simply not ordinal (probably eg, a
polygon or a collection type).


Complex numbers can be ordered, but only if you're willing to accept
that multiplication by a complex number will mess with that order in a
not-always-intuitive way (as opposed to non-zero real numbers, where
the order will always be either preserved exactly or completely
reversed).  I've seen the arguments against the validity of ordering
complex numbers, and I don't find them very persuasive.  That said,
even if complex numbers aren't ordinal, they _can_ be assigned a
canonical ordinal form.  Perhaps a better name for the role might be
something along the lines of Sortable...

And yes, there _are_ cases where assigning a canonical ordering to a
type is counterintuitive at best.


So, while it could make sense to have an Ordinal role, which types
individually can .does(), and only those have , , =, =, =, min,
max, sort, etc, there is the question about how to handle types that
don't .does() Ordinal in some generic 

Re: generic ordinal-relevant operators

2006-11-11 Thread Darren Duncan

At 10:30 PM -0800 11/11/06, Jonathan Lang wrote:

Note that this is two competing suggestions: one where '==' means
'generic equivalence', '+==' means 'numeric equivalence', and '*=='
means 'string equivalence'; and another where '*==' means 'generic
equivalence', '==' means 'numeric equivalence', and 'eq' means 'string
equivalence' (with '', '', etc. following suit).  The goal of the
second proposal is to leave existing operator names unchangåed, while
the goal of the first proposal is to provide a consistent and
intuitive naming convention.

snip

For the record, my preference is to have the 
generics be the shortest, [==,!==,=,,,=,=], 
and use [+,~] prefixes for Num or Str casting 
versions.  And lengthen the bit-shift operators 
to use thin-tailed arrowheads as you suggested.


If this practice is followed, then we get these benefits:

1. Better self-documenting of code.
2. Better visual consistency of comparison operators - easier to learn.
3. Fewer base operators and/or fewer alternate shorthands - simplicity.
4. Eliminate the alphabet soup and related ugliness.
5. Better huffman coding because most people will 
want to sort their values by their native types; 
people normally want to sort Str as Str and Num 
as Num, and plain == etc will do that.  I don't 
see any use of weak types as reducing the 
benefits either.
6. In my mind, bit shifting is a less commonly 
coded activity, so making those ops a bit longer 
shouldn't hurt anything.


-- Darren Duncan