Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-08-15 Thread Smylers
David Green writes:

 On 8/13/06, Smylers wrote:
 
  Please could the proponets of the various behaviours being discussed
  here share a few more concrete examples ...
 
 OK,

Thanks for that.  In summary, if I've understood you correctly, it's
that:

  =:=  two aliases to the same actual variable
  ===  one variable contains a copy of the other's actual contents
  eqv  both contain contents which represent the same thing but may have
   come from different sources

And that being true at one level implies being true for the above
levels.  Yes?

 ===
 Example: Suppose I have some employee objects, and I employ two John 
 Smiths.  They have the same name, work in the same department, and by 
 stunning coincidence everything my class knows about them just 
 happens to be the same.

Except that they wouldn't.  Because each one would have a separate
payroll number, or some artificial thing invented just for the sake of
being different.  So this example doesn't sound plausible to me.

 But they're still different objects (the payroll system definitely
 needs to produce two cheques, although since they earn the same
 salary, it doesn't matter which one of them gets which cheque); so
 $john1 !=== $john2, and I can tell them apart.

And why on earth would you be making such a comparison?  If you have a
list of employees who need cheques then you just iterate through them
and process them in turn; you wouldn't be comparing an arbitrary pair of
them.

So I now understand what this operator does.  But I'm still struggling
to fathom where I would ever have a use for it.

Smylers


Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-08-15 Thread Dr.Ruud
David Green schreef:

 ===
 ...is equality-of-contents, basically meaning that the things you're
 comparing contain the same [...] values.

How about strings; are normalized copies used with the === ?

http://www.unicode.org/faq/normalization.html
http://www.unicode.org/notes/tn5/

-- 
Affijn, Ruud

Gewoon is een tijger.




Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-08-15 Thread David Green

On 8/14/06, Smylers wrote:

David Green writes:
Thanks for that.  In summary, if I've understood you correctly, it's that:

  =:=  two aliases to the same actual variable
  ===  one variable contains a copy of the other's actual contents
  eqv  both contain contents which represent the same thing but may have
   come from different sources

And that being true at one level implies being true for the above 
levels.  Yes?


Right. (Where the ordering for above means =:= implies ===, and === 
implies eqv, but not in the other direction, of course.)



  ===

 Example: Suppose I have some employee objects, and I employ two John
 Smiths.  They have the same name, work in the same department, and by
 stunning coincidence everything my class knows about them just
 happens to be the same.


Except that they wouldn't.  Because each one would have a separate 
payroll number, or some artificial thing invented just for the sake 
of being different.  So this example doesn't sound plausible to me.


Well, I didn't say it was a *good* payroll system!  OK, it's a silly 
contrived example; maybe my objects should have represented the 
reticulated flanges I have in stock, since one piece of inventory is 
the same as any other.  Except I wouldn't really create an object for 
each one, I'd just have a single group-object that contained a 
$num_available counter

(Anyone cleverer than I should feel free to jump in with a better example.)

So I now understand what this operator does.  But I'm still 
struggling to fathom where I would ever have a use for it.


Maybe you wouldn't -- eqv is what most of us will use most of the 
time, I expect (being the ordinary everyday parallel to == and eq). 
But since it is possible to use variables both by value and by 
reference, there still needs to be a way to work with and compare 
both of them when you want to do fancy advanced stuff.



-David


Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-08-13 Thread Smylers
On July 14th Yuval Kogman wrote:

 On Fri, Jul 14, 2006 at 11:42:24 +0100, Smylers wrote:
 
  I'm afraid I still don't get it.
  
  Or rather, while I can manage to read an explanation of what one of
  these operators does and see how it applies to the variables in the
  examples next to it, I am struggling to retain a feeling of _why_ I
  would want to use any of these operators in real-life Perl 6 code.
 
 To compare deep structures ;-)
 
  Already in Perl 5 having 2 different equality operators is something
  that learners often stumble over.
 
 But only for low level types. To see if two objects are the same, or
 two hashes, you need to use Data::Compare, or to overload either ==
 or eq, neither of which is a perfect fit.
 
 I have to catch my flight, so I'll explain more later.

Hi there.  Ann's (excellent, very useful, and much appreciated) summary
reminded me that this was still pending.  Did you catch your flight?

For the benefit of anybody else who's struggling to remember a thread
from a month ago this was my original request.

  Please could the proponets of the various behaviours being discussed
  here share a few more concrete examples which start by explaning a
  scenario in which there is a desire to do something, preferably one
  that Perl 5 coders can identify with, and then show how one of these
  new operators would meet that desire (and that without that operator
  it would be hard or clumsy to achieve the same thing)?

Cheers.

Smylers


Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-08-13 Thread David Green

On 8/13/06, Smylers wrote:

  Please could the proponets of the various behaviours being discussed
  here share a few more concrete examples which start by explaning a
  scenario in which there is a desire to do something, preferably one
  that Perl 5 coders can identify with, and then show how one of these
  new operators would meet that desire (and that without that operator
  it would be hard or clumsy to achieve the same thing)?


OK, if I can come up with examples that make sense, then that 
probably means I actually understand it myself!



eqv
...is your standard equality-of-values, which would be just = or == 
in many languages, and which Perl has never really had.  == and eq 
coerce their operands to be numbers or strings, which was fine back 
in days or yore when Perl only had nums and strings.  With the 
introduction of references/objects, Perl effectively got 
user-definable types without a user-definable equality operator, so 
you either had to rely on suitable numifications (or 
stringifications) of your objects to make sense, or overload stuff, 
or something.  In P6 you can just compare their values in a normal 
way (or still numify/stringify them using == or eq if that's what you 
want).


Example: I have a Date class that lets each of its objects carry 
around its own different epoch value, so using == won't work (unless 
both dates that I'm comparing happen to share the same epoch -- a 
yucky work-around might be if $a==$b  $a.epoch==$b.epoch).  And 
let's suppose my Dates are text-insensitive-but-preserving, meaning 
that objects created as 2006/1/1 and as Jan. 1, 2006 return those 
exact strings when stringified, even though they represent the same 
date: so comparing with eq won't work either.


Instead I want to compare my dates with eqv which compares their 
real values.  (Real is determined by the class -- this is where 
the Special Key ID stuff comes in.  In this example, the SKID for a 
date might be an int using a fixed epoch; or it might be a text 
representation in canonical form.  The user doesn't have to care, of 
course.)


(eqv also means you no longer need code like if (we're using ints) 
return $a==$b else if (we've got strings) return $a eq $b, which was 
occasionally a pain even in those Days of Yore.  Now that P6 can use 
variable types, you don't [necessarily] need to specify the type in 
the equality operator, you can just use eqv to do the appropriate 
kind of comparison.  (And cmp is becoming the analogue of eqv 
instead of eq.))



===
...is equality-of-contents, basically meaning that the things you're 
comparing contain the same variables and values.  (E.g. things that 
are references to other variables, possibly nested in some kind of 
data structure.)  Now if you have a couple of plain old ints, then 
it's the same as testing whether they have the same values (eqv). 
But if $a contains a ref to @x and $b contains a ref to @y, then $a 
will not === $b.  (Unless @x and @y are really the same variable in 
disguise, of course.  $a might *eqv* $b, because @x and @y could have 
the same value, but as long as $x and $y are different guys, then $a 
!=== $b.  Conversely, if $a does === $b, then they must have the same 
value too, i.e. it follows that $a eqv $b.)


Example: Suppose I have some employee objects, and I employ two John 
Smiths.  They have the same name, work in the same department, and by 
stunning coincidence everything my class knows about them just 
happens to be the same.  So they're basically indistinguishable 
(serialising one John Smith object produces the same results as the 
other -- and indeed, $john1 eqv $john2).  But they're still different 
objects (the payroll system definitely needs to produce two cheques, 
although since they earn the same salary, it doesn't matter which one 
of them gets which cheque); so $john1 !=== $john2, and I can tell 
them apart.


In fact, === is how a hash tests its keys (assuming it's a hash that 
uses objects rather than a P5-like hash that uses stringy keys -- of 
course, for a string hash, === wouldn't work out any different from 
eqv anyway).



=:=
...is equality-of-variable, or binding -- it simply checks whether 
its operands are both the same variable (possibly under different 
names).  This might be a little esoteric for ordinary code (if 
there is any such thing), but binding is pretty common in P6, even if 
inconspicuous: sub foo($a, $b) will bind $x to both $a and $b if I 
call foo($x, $x).  I might want to know whether my $a and $b really 
are the same variable passed in twice or not.


Example: a fairly simple reason why you might care whether you've got 
the same variable twice is if you're doing some expensive comparison 
-- an easy optimisation is to check whether the two things you're 
comparing are really the same thing to start with.


(Or, going back to my double John Smiths setup, my payroll functions 
can make sure that all the John Smith really are different people, 
and not a single 

Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-08-13 Thread David Green

Way back on 7/14/06, Larry Wall wrote:

On Thu, Jul 13, 2006 at 10:19:24PM -0600, David Green wrote:

[...]


No, === is also deep.  It's only shallower (or potentially shallower)
in the sense that it treats any mutable object node as a leaf node
rather than changing to snapshot semantics like eqv does.


Yup, which it would have to be even given the slightly-off way I was 
thinking of it.  So I've quietly snipped the part where I said it 
wasn't and will pretend it was never there.



: (One [1,2] is as good as any other [1,2] -- what's the use of ever
: having them not compared as the same?  I can see maybe for =:=, since
: something that doesn't have a name cannot, by definition, have the
: same name as something else... although even there, it arguably makes
: sense to consider equivalent anonymous values as bound to the same
: place.  There's only one unique [1,2] in platonic heaven, I'm just
: mentioning it directly instead of dropping a name.)

On the contrary, there isn't one single platonic [1,2], since square
brackets construct a mutable Array object:
@a := [1,2];
@b := [1,2];
@b[0]++;
say @a @b;  # 1 2 2 2


$ perl -e 'print ++([1,2]-[1])'
3

Hmm... well, I guess I shouldn't be surprised that that worked, it 
makes sense -- you can't have an array-ref unless it refers to 
something.  But something still bothers me...  Perl knows that my 
anonymous array-ref is pointing at something, so it's [effectively] 
got some kind of internal name that it knows about, but I don't. 
So it isn't really anonymous... it's a Rumpelstiltskin array!


I guess my problem is that [1,2] *feels* like it should === [1,2]. 
You can explain that there's this mutable object stuff going on, and 
I can follow that (sort of...), but it seems like an implementation 
detail leaking out.  In many languages, strings are just character 
arrays, and presumably someone could write a version of Perl that 
actually built strings out of array refs, but I'd still want foo to 
=== foo.


And I feel this way because [1,2] looks like it should be 
platonically unique.  Or at least leibnizianly unique: if two things 
don't have any different features, then they aren't different.  And 
one [1,2] can do anything that another [1,2] can.  ...Except have the 
same object ID, which doesn't seem particularly useful, except for 
distinguishing them, which is what I don't want to do.


Is there a useful non-implementary reason to tell them apart 
(excepting obfuscated P6 and stuff Damian might do), or can you just 
hide it?? (Ignorance is bliss for bears of little brain like me.) 
Some convenient skidding around to make identical array-refs look, 
well, the identical.  Of course, when you suppress one thing, you 
have to start stomping down spots all over the waterbed, and 
eventually it might burst.  Maybe I'm just not thinking about it from 
the right direction...  Do I feel that \1 (a ref to a literal 1) 
should be platonic?  Does it matter?  As you said, ordinarily I'll be 
assigning rather than binding, so stuff will just work.


Can I make a nested Seq with something like (1;2; 3,4)?  Compared to 
the nested Array referential [1,2, [3,4]]?


[EMAIL PROTECTED] should be different from (!===) [EMAIL PROTECTED] because even if @a eqv 
@b eqv (1,2), @b might change.  But if $a=[1,2] and $b=[1,2] there's 
nothing I can change that will make $a and $b different, so for $a 
not to === $b is Fairly Surprising in Principle.  That is, nothing 
*else* I can change, since of course changing either $a or $b will 
make them different.


You may tell me that $b[0]++ *is* changing something other than $b, 
but it sure looks like changing $b.  The only way I can get at the 
original [1,2] is by going through $b, so I think I am changing $b. 
But wouldn't I think the same thing if [EMAIL PROTECTED] and I do $b[0]++?  It 
might look superficially as though I were changing $b, but $b still 
is [EMAIL PROTECTED] -- @b is what's really changed.  Hmmm.  If Perl is simply more 
complex, there's no point my trying to hold a naive view.


Maybe it's one of those things that never will seem quite comfortable 
until I just get used to it



-David



Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-07-14 Thread Darren Duncan
I think that Jonathan meant for his reply to my message to go to the 
list, so I am including it in its entirety, in my reply.


At 11:23 PM -0700 7/13/06, Jonathan Lang wrote:

Darren Duncan wrote:

Jonathan Lang wrote:

So the purpose of === is to provide a means of comparison that doesn't
implicitly coerce its arguments to a particular type?


Yes, absolutely.  The === takes 2 arguments exactly as they are,
without changing anything, and says if they are two appearances of
the same value.  It would always return false if the 2 arguments are
of different declared types.  And if they are of the same types, then
no coersion is necessary in order to compare them for equality.


So the difference between eqv and === is:

 @a eqv @b iff all(for each(@a, @b) - $a, $b { $a === $b }) # a deep
comparison

or

 @a === @b iff all(for each(@a, @b) - $a, $b { $a =:= $b }) # a
shallow comparison

?

That seems counterintuitive to me; I'd rather see both === and eqv
represent a deep comparison, and leave shallow comparisons to less
elegant approaches.


I see eqv and === as both being recursive with their own kinds when 
used on any and immutable data types respectively.


Arrays are mutable, so I see that the above examples mean the 
following (only relevant parts changed, other syntax parts may be 
wrong):


  @a eqv @b iff all(for each(@a, @b) - $a, $b { $a eqv $b })
# a deep comparison using eqv all along

  @a === @b iff @a =:= @b
# a shallow comparison since === only tests immutable aspects

Now, lets try two Seq, $a and $b, instead, which are like Array but immutable:

  $a === $b iff all(for each($a.values, $b.values) - $a, $b { $a === $b })
# a deep-as-possible comparison using === all along

Assuming that all elements of $a and $b are themselves immutable to 
all levels of recursion, === then does a full deep copy like eqv.  If 
at any level we get a mutable object, then at that point it turns 
into =:= (a trivial case) and stops.


Note that if your Seqs just contain other immutable things like Str 
or Int or Set or Pair or Mapping etc to all recursion levels, which 
they are highly likely to do, then === is simply a deep recursion.


That's how I understand it, and it seems quite elegant and simple.

-- Darren Duncan


Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-07-14 Thread Smylers
Yuval Kogman writes:

 So, Larry assisted by Audrey explained the purpose of === vs eqv vs
 =:=.

I'm afraid I still don't get it.

Or rather, while I can manage to read an explanation of what one of
these operators does and see how it applies to the variables in the
examples next to it, I am struggling to retain a feeling of _why_ I
would want to use any of these operators in real-life Perl 6 code.

Please could the proponets of the various behaviours being discussed
here share a few more concrete examples which start by explaning a
scenario in which there is a desire to do something, preferably one that
Perl 5 coders can identify with, and then show how one of these new
operators would meet that desire (and that without that operator it
would be hard or clumsy to achieve the same thing)?

Already in Perl 5 having 2 different equality operators is something
that learners often stumble over.  If we're going to have 5 of the
things in Perl 6 then there needs to be a very clear way of explaining
how to determine which one to use (or at least an explanation that 3 of
the operators are very esoteric and beginners don't need to worry about
them).

Smylers


Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-07-14 Thread Yuval Kogman
On Fri, Jul 14, 2006 at 11:42:24 +0100, Smylers wrote:

 I'm afraid I still don't get it.
 
 Or rather, while I can manage to read an explanation of what one of
 these operators does and see how it applies to the variables in the
 examples next to it, I am struggling to retain a feeling of _why_ I
 would want to use any of these operators in real-life Perl 6 code.

To compare deep structures ;-)

 Already in Perl 5 having 2 different equality operators is something
 that learners often stumble over.

But only for low level types. To see if two objects are the same, or
two hashes, you need to use Data::Compare, or to overload either ==
or eq, neither of which is a perfect fit.

I have to catch my flight, so I'll explain more later.


-- 
  Yuval Kogman [EMAIL PROTECTED]
http://nothingmuch.woobling.org  0xEBD27418



pgp4zdMSoN13m.pgp
Description: PGP signature


Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-07-14 Thread Smylers
Yuval Kogman writes:

 On Fri, Jul 14, 2006 at 11:42:24 +0100, Smylers wrote:
 
  Or rather, while I can manage to read an explanation of what one of
  these operators does and see how it applies to the variables in the
  examples next to it, I am struggling to retain a feeling of _why_ I
  would want to use any of these operators in real-life Perl 6 code.
 
 To compare deep structures ;-)

Thank you.  That helps.

My initial instinct was that this meant the new operators can all be
dismissed as ignorable by learners, as they won't be using nested data
structures anyway.

But actually deep doesn't have to be very deep in order for such a
comparison op to have use: merely wanting to see if the contents of 2
arrays are the same doesn't involve any nesting and is a concept that is
well within the grasp of a beginner.

 so I'll explain more later.

Great.  I appreciate your help, and I'm looking forward to your
explanation of the different behaviours in this thread.

Smylers


Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-07-14 Thread Mark A. Biggar

Darren Duncan wrote:
Now, I didn't see them yet anywhere in Synopsis 3, but I strongly 
recommend having negated versions of all these various types of equality 
tests.  Eg, !== for ===, nev for eqv, etc.  They would be used very 
frequently, I believe (and I have even tried to do so), and of course we 
get the nice parity.


Yes and they should be strictly implicitly defined in term of the 
positive versions in such a way that you can't explicitly redefine them 
separately.  I.e., $x !== $y should always mean exactly the same thing 
as !($x === $y).  Maybe by a macro definition. To do otherwise would be 
very confusing as it would make such simple program transformations as:


say foo if $x !== $y;

into

say foo unless $x === $y;

very unreliable.

Actually a similar argument could be made about '' vs '', '=' and 
'=' in other words just redefining '=='  '' should automatically get 
you '!=', '=', '=' and ''.


--
[EMAIL PROTECTED]
[EMAIL PROTECTED]


Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-07-14 Thread Dave Whipp

Darren Duncan wrote:

Assuming that all elements of $a and $b are themselves immutable to all 
levels of recursion, === then does a full deep copy like eqv.  If at any 
level we get a mutable object, then at that point it turns into =:= (a 
trivial case) and stops.


  ( 1, 2.0, 3 ) === ( 1,2,3 )

True or false?

More imprtantly, how do I tell perl what I mean? The best I can think of is:

  [] (@a »==« @b)
Vs
  [] (@a »eq« @b)

But this only works for nice flat structures. For arbitrary tree 
structures, we probably need adverbs on a comparison op (I think Larry 
mentioned this a few posts back) ... but if we're going with adverbs do 
we really need 5 different base operators? Are all of the 5 so common 
that it would be clumbersome to require adverbs for their behavior?


Also, when sorting things, maybe deep inequalities would be useful, too.


Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-07-14 Thread Dr.Ruud
Mark A. Biggar schreef:
 Darren Duncan:

 Now, I didn't see them yet anywhere in Synopsis 3, but I strongly
 recommend having negated versions of all these various types of
 equality tests.  Eg, !== for ===, nev for eqv, etc.  They would be
 used very frequently, I believe (and I have even tried to do so),
 and of course we get the nice parity.

 Yes and they should be strictly implicitly defined in term of the
 positive versions in such a way that you can't explicitly redefine
 them separately.  I.e., $x !== $y should always mean exactly the same
 thing as !($x === $y).  Maybe by a macro definition. To do otherwise
 would be very confusing as it would make such simple program
 transformations as:

   say foo if $x !== $y;

 into

   say foo unless $x === $y;

And how about symmetry:

  say foo unless $y === $x;

 very unreliable.

-- 
Affijn, Ruud

Gewoon is een tijger.




Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-07-14 Thread Darren Duncan

At 9:22 AM -0700 7/14/06, Dave Whipp wrote:

Darren Duncan wrote:
Assuming that all elements of $a and $b are 
themselves immutable to all levels of 
recursion, === then does a full deep copy like 
eqv.  If at any level we get a mutable object, 
then at that point it turns into =:= (a trivial 
case) and stops.


  ( 1, 2.0, 3 ) === ( 1,2,3 )

True or false?


That would be false, because a Str does not === an Int.

I should point out, though, that in at least some 
situations where you are ===, you would have more 
control of the creation of the structures in the 
first place and they will probably have been 
created in a more strict fashion that required 
the data to be of corresponding types in the 
first place.  Eg, each Seq would have only been 
allowed to store Ints in the first place.  The 
best place to normalize input is as early as 
possible, after all, like when the Ints were 
input and before they were put in the Seq to be 
compared.



More imprtantly, how do I tell perl what I mean? The best I can think of is:

  [] (@a »==« @b)
Vs
  [] (@a »eq« @b)

But this only works for nice flat structures. 
For arbitrary tree structures, we probably need 
adverbs on a comparison op (I think Larry 
mentioned this a few posts back) ... but if 
we're going with adverbs do we really need 5 
different base operators? Are all of the 5 so 
common that it would be clumbersome to require 
adverbs for their behavior?


Also, when sorting things, maybe deep inequalities would be useful, too.


I will punt on that one.

-- Darren Duncan


Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-07-14 Thread Darren Duncan

At 6:55 PM +0200 7/14/06, Dr.Ruud wrote:

say foo if $x !== $y;


 into

   say foo unless $x === $y;


And how about symmetry:

  say foo unless $y === $x;

  very unreliable.


Any equality or inequality operator is commutative, so it doesn't 
matter whether you have $x and $y or $y and $x, the result is the 
same.  So you can use whichever order you want without it needing to 
be coded for. -- Darren Duncan


Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-07-14 Thread Larry Wall
On Thu, Jul 13, 2006 at 10:56:59PM -0700, Darren Duncan wrote:
: Now, I didn't see them yet anywhere in Synopsis 3, but I strongly 
: recommend having negated versions of all these various types of 
: equality tests.  Eg, !== for ===, nev for eqv, etc.  They would be 
: used very frequently, I believe (and I have even tried to do so), and 
: of course we get the nice parity.

My gut feeling contradicts yours--I think these are going to be far
rarer in practice than == and eq, so they don't warrant yet more
special forms that have to be memorized.

And !== is too easy to confuse with != visually, or with !(==) semantically.
For such long operators, I'd try to do exact syntactical composition rather
than replacement, so they'd be !=== and neqv, probably, along with !=:=.
Maybe even go with !eqv rather than neqv, and make ! into a metaoperator
on relationals.  Then !== and !eq would be identical to != and ne.

But a lot of the time the negated versions are going to be disallowed anyway,
simply because English mangles junctions when it does not raising.

Valid English:

If X doesn't equal one or two or three, say out of range.

Naïve Perl:

if $x != 1 | 2 | 3 {
say out of range;
}

But that's wrong because Perl doesn't do not raising, so the statement
above always prints out of range.  You should have said one of:

if not $x == 1 | 2 | 3 {
say out of range;
}

if $x != 1  2  3 {
say out of range;
}

So either we have to make Perl do not-raising like English, which will
probably confuse non-English speakers, or we have to disallow negative
operators from participating in junctional logic, or we have a huge
educational problem (read FAQ).  My money is currently on disallowing
distribution of junctions over negated operators, and forcing people
to do not-raising explicitly, at least in the syntactic case above.
Perhaps we can still allow the semantics where it's not likely to be
confused with English.

Anyway, that's just another reason for going slow on throwing in the
negated versions.

Larry


Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-07-14 Thread Darren Duncan

At 12:55 PM -0700 7/14/06, Larry Wall wrote:

On Thu, Jul 13, 2006 at 10:56:59PM -0700, Darren Duncan wrote (edited):
: Now, I didn't see them yet anywhere in Synopsis 3, but I strongly
: recommend having negated versions of all these various types of
: equality tests.  Eg, !=== for ===, !eqv for eqv, etc.  They would be
: used very frequently, I believe (and I have even tried to do so), and
: of course we get the nice parity.

My gut feeling contradicts yours--I think these are going to be far
rarer in practice than == and eq, so they don't warrant yet more
special forms that have to be memorized.


Actually, now that I think about it, I could use 'not' to avoid a lot 
of the syntactic hassle that I've been having with a lack of !===. 
Eg, what I wanted was to avoid having to say:


  if (!($foo === $bar) and ...) { ... }

So I had proposed instead:

  if ($foo !=== $bar and ...) { ... }

But then your post reminded me of 'not', and since it binds tighter 
than 'and' and 'or', I can say:


  if (not $foo === $bar and ...) { ... }

While I still like the second example best, in light of the issues of 
not-raising you mention that could confuse others, I'll withdraw my 
request for now.


-- Darren Duncan


Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-07-14 Thread Yuval Kogman
On Fri, Jul 14, 2006 at 09:22:10 -0700, Dave Whipp wrote:
 Darren Duncan wrote:
 
 Assuming that all elements of $a and $b are themselves immutable to all 
 levels of recursion, === then does a full deep copy like eqv.  If at any 
 level we get a mutable object, then at 
 that point it turns into =:= (a trivial case) and stops.
 
   ( 1, 2.0, 3 ) === ( 1,2,3 )
 
 True or false?

false

 More imprtantly, how do I tell perl what I mean? The best I can think of is:
 
   [] (@a »==« @b)
 Vs
   [] (@a »eq« @b)

Neither - it's on the natural types. If the types are different it's
!=

-- 
  Yuval Kogman [EMAIL PROTECTED]
http://nothingmuch.woobling.org  0xEBD27418



pgpdVijcRjp0Q.pgp
Description: PGP signature


Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-07-14 Thread Dr.Ruud
Darren Duncan schreef:
 Dr.Ruud:

say foo if $x !== $y;
 into
say foo unless $x === $y;

 And how about symmetry:
say foo unless $y === $x;

 Any equality or inequality operator is commutative,

If $x and $y are not of the same type, and one or both of the involved
types has its own (or overloaded?) 'deep equality operator', the choice
(which implementation is used) can depend on the order.

Not so long ago, there was an issue with Perl5 in this area (IIRC with
'==' and undef).


 so it doesn't
 matter whether you have $x and $y or $y and $x, the result is the
 same.  So you can use whichever order you want without it needing to
 be coded for. -- Darren Duncan

-- 
Affijn, Ruud

Gewoon is een tijger.




Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-07-14 Thread Charles Bailey

On 7/14/06, David Green [EMAIL PROTECTED] wrote:


On 7/13/06, Yuval Kogman wrote:
So, Larry assisted by Audrey explained the purpose of === vs eqv vs =:=.
It makes sense now, but I still feel that as far as ergonomics go
this is not perfect.

I think I understand it... (my only quibble with the syntax is that
=== and eqv look like spin-offs of == and eq, but I don't know what
to suggest instead (we're running short of combinations of = and : !))

So there are three basic kinds of comparison: whether the variables
are the same (different names, but naming the same thing); whether
the values are the same (deep comparison, i.e. recursively all the
way down in the case of nested containers); and in-between (shallow
comparison, i.e. we compare the top-level values, but we don't work
out *their* values too, etc., the way a deep comparison would).  If
I've got it right, this is what =:=, eqv, and === give us,
respectively.



It may well be that I'm misunderstanding here -- I've been away from Perl
development for too long and have a lot of catching up to do -- but I'm
uneasy about using the terms shallow comparison and immutably equal to
describe the same thing.  If the  true meaning of  $a === $b is that
$a.id eq $b.id, where .id is the value for a simple type, I think it'd be
least confusing to just call it a shallow comparison.  Immutable equality
sounds more like a promise of deep and lasting equality, not an assertion
that equality is skin deep.  I make a similar inference from the long sigil
-- it has more the flavor of more equal than a special case of equal (to
me, at least).  Just to muddy the waters further, I'd think -- off the cuff
-- that you might do well with expectations to say

 == and eq - shallow comparison of numeric and string values, specifically
(with other types being
free to specify what their numeric and string values
are -- caveat usor)
Matches existing expectations of these operators
 ===   - deeply equal (equivalent to the current eqv); alias for
isreally or isdeeply
Expectation based on extending the == metaphor
 eqv   - Different names for the same thing (what I think =:= means
now)
Expectation based on glossing as equivalent rather
than equal value.
 =:=- Defined identically, with no promise about contents (what
I think === means now).
Expectation based on the use of : to indicate
declaratory behavior

Just two cents from a Perl6 newbie.

--
Regards,
Charles Bailey
Lists: bailey _dot_ charles _at_ gmail _dot_ com
Other: bailey _at_ newman _dot_ upenn _dot_ edu


Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-07-14 Thread Larry Wall
On Thu, Jul 13, 2006 at 10:19:24PM -0600, David Green wrote:
: On 7/13/06, Yuval Kogman wrote:
: So, Larry assisted by Audrey explained the purpose of === vs eqv vs =:=.
: It makes sense now, but I still feel that as far as ergonomics go 
: this is not perfect.
: 
: I think I understand it... (my only quibble with the syntax is that 
: === and eqv look like spin-offs of == and eq, but I don't know what 
: to suggest instead (we're running short of combinations of = and : !))

That's partly because they *are* spinoffs, on a metaphorical level.
The === operator is a mathematically equal, where that implies
equality henceforth and forevermore.  There is also a bit of the
notion that, since a number is a singular thing, you can't treat
any of the bits of a number as mutable.  There's no lvalue substr()
defined on a number, as it were.

The eqv operator, on the other hand, is a you have to work at figuring
this out by serializing both values conceptually to canonical strings
(think Storable) and see if those are eq.  (Only you don't really go
to all that work, if you can short circuit any of it.)  There is also
the notion (though this breaks down if you look at it too hard) that
a string can be modified in place, so a string value is mutable (at
least from the standpoint of the variable holding it; from the
standpoint of ===, string values are immutable, which is where the
analogy breaks down).

: So there are three basic kinds of comparison: whether the variables 
: are the same (different names, but naming the same thing); whether 
: the values are the same (deep comparison, i.e. recursively all the 
: way down in the case of nested containers); and in-between (shallow 
: comparison, i.e. we compare the top-level values, but we don't work 
: out *their* values too, etc., the way a deep comparison would).  If 
: I've got it right, this is what =:=, eqv, and === give us, 
: respectively.

No, === is also deep.  It's only shallower (or potentially shallower)
in the sense that it treats any mutable object node as a leaf node
rather than changing to snapshot semantics like eqv does.

: (When I say value I'm thinking of everything that makes up the 
: value, such as type (so the number 3 is different from the string 
: 3), or details like the encoding for a string, etc.)

Arguably the encoding of a string has nothing to do with its value
most of the time, if the semantics are supposed to be consistent Unicode
semantics at the codepoint or grapheme level.  But yes, by and large
types do have to be included.  Bool::True is a different value from 1,
even though they are often interchangable in many contexts.

: Examples:
: 
:   @x=foo bar;
:   @y=foo bar;
: 
:   $a=[1, 2, [EMAIL PROTECTED];
:   $b:=$a;
:   $c=[1, 2, [EMAIL PROTECTED];
:   $d=[1, 2, [EMAIL PROTECTED];
: 
: 
:   $a =:= $b;  #true, same variable with two names
:   $a === $b;  #true   _/ $b just another name for $a,
:   $a eqv $b;  #true\ so comparable at all levels
: 
:   $a =:= $c;  #false, different variables
:   $a === $c;  #true, same elements make up $a and $c
:   $a eqv $c;  #true, same elements therefore same values
: 
:   $a =:= $d;  #false, different variables
:   $a === $d;  #false, [EMAIL PROTECTED] and [EMAIL PROTECTED] are 
different refs
:   $a eqv $d;  #true, values of @x and @y happen to be the same

All correct.

: (Of course, @x eqv @y, @[EMAIL PROTECTED], but not @x=:[EMAIL PROTECTED])
: Note that if $i=:=$j, then $i===$j; and of course if $i===$j, then $i eqv 
: $j.

Those are necessarily true, assuming nobody else is meddling with
our data structures in the middle of our comparison.  If someone is
modifying some mutable component in $i or $j while we're taking a
snapshot, then we can get into inconsistent states where eqv can
return false despite === being true.

: OK, looking at S03 again, that still isn't correct.  I think my =:= 
: and eqv are all right, but I don't understand exactly what === is 
: supposed to do, or why it's useful.  And how do I do my 
: shallow-comparison above?

S03 hasn't been updated to reflect all this yet.  === semantics are
useful for figuring out whether you have a unique key for a hash when
you want to hash on live objects.  eqv is for dead keys, because
as soon as you've taken a snapshot of your data, you can't modify the
snapshot or dereference any object in your hash key.  eqv semantics
are what Perl 5 hashes use for keys, which is why you can't deref
a hash key directly even if you thought you were putting an object
in as the key.

: (One [1,2] is as good as any other [1,2] -- what's the use of ever 
: having them not compared as the same?  I can see maybe for =:=, since 
: something that doesn't have a name cannot, by definition, have the 
: same name as something else... although even there, it arguably makes 
: sense to consider equivalent anonymous values as bound to the same 
: place.  There's only one unique [1,2] in 

Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-07-13 Thread Yuval Kogman
So, Larry assisted by Audrey explained the purpose of === vs eqv vs
=:=.

It makes sense now, but I still feel that as far as ergonomics go
this is not perfect. Then again, I trust that Larry's opinion is
probably better and at the very least more likely to be accepted
than mine ;-) [1]


So, this is the deal:


=== is for checking immutable equality. This is a bit nasty to
explain.

eqv is going to be deep comparison, like most of us thought '==='
was going to be (I had initially thought that eqv was renamed to ===
when === started popping up).

=:= is something completely different, but will be easy to explain
in a moment.


What it means for something to be immutable can be demonstrated
rather easily here:

my $x = 10;
my $y = $x;

$x === $y; # true

$y++:

$x === $y; # false

Since numbers (and also strings) are simple values, that are not
modified in place (at least not explicitly), but are instead copied
and modified or just replaced when you change them, the .id of the
thing inside $x and $y is bound to the value.

You could rationalize this such that .id is the same if and only if
it doesn't actually matter (and never will matter) if the value is
in the same chunk of memory or a separate one, as far as the runtime
is concerned.

Arrays and hashes, and other complex types can, on the other hand
have parts of them transformed without first cloning everything
(which is precisely why they're useful).

The underlying idea is that === can be used to test if two values are
*always* going to be the same (if they're container gets a different
value in it that does not mean that they are no longer the same).

eqv, on the other hand is used to test whether or not two values are
the same right now, without making any implications as to what their
values will be later on, since they may mutate. This is deceivingly
like == and eq if you assume that numbers and strings are changed,
instead of replaced.

Lastly, =:= is really variable($x) === variable($y) - that is,
whether or not the container is the same value or not. This
basically checks whether either $x or $y was at some point bound to
the other, or in specific situations whether they're tied to the
same representation even if they are different containers.

Overridding .id is useful for when you want to imply that two items
are exactly the same and will always be the same and will never
change as far as their comparison is concerned (both eqv and ===
will always be true), even if the default implementation of === does
not return true due to technical details. === can be thought of as
.id eqv .id.

I hope this clears things up, and thanks again, Larry and Audrey, for
clearing this up.

I'd like for someone with better english skills to summarize into an
S03 patch please. It needs to be much shorter =)

[1] My preferred ergonomics:

1. eqv goes away
2. what was eqv is renamed to ===
3. === becomes =:=, which has a constant feel to it
4. =:= is rarely useful IMHO, so you can just type
variable($x) =:= variable($y)

Ciao

-- 
  Yuval Kogman [EMAIL PROTECTED]
http://nothingmuch.woobling.org  0xEBD27418



pgpU0Qe5CPlhQ.pgp
Description: PGP signature


Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-07-13 Thread Larry Wall
On Thu, Jul 13, 2006 at 09:32:08PM +0300, Yuval Kogman wrote:
: [1] My preferred ergonomics:
: 
:   1. eqv goes away
:   2. what was eqv is renamed to ===
:   3. === becomes =:=, which has a constant feel to it
:   4. =:= is rarely useful IMHO, so you can just type
:   variable($x) =:= variable($y)

It is important for eqv to be alphabetic so we can have the functional
form take an optional signature parameter to specify what is compared.

eqv($a,$b, :($x,$y))

Think of this as the same as the sort specifier that says what to sort on,
only we're only interested in eqv-ness rather than cmp-ness.

In fact, cmp (or something like it) also wants to take a third parameter:

leg($a,$b, :($x is num,$y is rev));

and then sort is just done with the same signature:

sort :($x is num,$y is rev), @foo;

or some such, however you want to canonicalize the records.
The sort routine can decide whether it'll be more efficient to do
various transforms or maneuvers based on the declarative syntax of
the signature.

Then $a eqv $b and $a leg $b both just default to a signature that selects
everything.

Larry


Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-07-13 Thread Larry Wall
On Thu, Jul 13, 2006 at 12:50:19PM -0700, Larry Wall wrote:
: Then $a eqv $b and $a leg $b both just default to a signature that selects
: everything.

Though arguably P5's string-forcing semantics should be Cleg and the
polymorphic semantics should probably be Ccmp.

Larry


Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-07-13 Thread David Green

On 7/13/06, Yuval Kogman wrote:

So, Larry assisted by Audrey explained the purpose of === vs eqv vs =:=.
It makes sense now, but I still feel that as far as ergonomics go 
this is not perfect.


I think I understand it... (my only quibble with the syntax is that 
=== and eqv look like spin-offs of == and eq, but I don't know what 
to suggest instead (we're running short of combinations of = and : !))


So there are three basic kinds of comparison: whether the variables 
are the same (different names, but naming the same thing); whether 
the values are the same (deep comparison, i.e. recursively all the 
way down in the case of nested containers); and in-between (shallow 
comparison, i.e. we compare the top-level values, but we don't work 
out *their* values too, etc., the way a deep comparison would).  If 
I've got it right, this is what =:=, eqv, and === give us, 
respectively.


(When I say value I'm thinking of everything that makes up the 
value, such as type (so the number 3 is different from the string 
3), or details like the encoding for a string, etc.)



Examples:

  @x=foo bar;
  @y=foo bar;

  $a=[1, 2, [EMAIL PROTECTED];
  $b:=$a;
  $c=[1, 2, [EMAIL PROTECTED];
  $d=[1, 2, [EMAIL PROTECTED];


$a =:= $b;  #true, same variable with two names
$a === $b;  #true   _/ $b just another name for $a,
$a eqv $b;  #true\ so comparable at all levels

$a =:= $c;  #false, different variables
$a === $c;  #true, same elements make up $a and $c
$a eqv $c;  #true, same elements therefore same values

$a =:= $d;  #false, different variables
$a === $d;  #false, [EMAIL PROTECTED] and [EMAIL PROTECTED] are 
different refs
$a eqv $d;  #true, values of @x and @y happen to be the same


(Of course, @x eqv @y, @[EMAIL PROTECTED], but not @x=:[EMAIL PROTECTED])
Note that if $i=:=$j, then $i===$j; and of course if $i===$j, then $i eqv $j.


OK, looking at S03 again, that still isn't correct.  I think my =:= 
and eqv are all right, but I don't understand exactly what === is 
supposed to do, or why it's useful.  And how do I do my 
shallow-comparison above?


(One [1,2] is as good as any other [1,2] -- what's the use of ever 
having them not compared as the same?  I can see maybe for =:=, since 
something that doesn't have a name cannot, by definition, have the 
same name as something else... although even there, it arguably makes 
sense to consider equivalent anonymous values as bound to the same 
place.  There's only one unique [1,2] in platonic heaven, I'm just 
mentioning it directly instead of dropping a name.)



-David


Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-07-13 Thread Jonathan Lang

David Green wrote:

I think I understand it... (my only quibble with the syntax is that
=== and eqv look like spin-offs of == and eq, but I don't know what
to suggest instead (we're running short of combinations of = and : !))


Agreed.


So there are three basic kinds of comparison: whether the variables
are the same (different names, but naming the same thing); whether
the values are the same (deep comparison, i.e. recursively all the
way down in the case of nested containers); and in-between (shallow
comparison, i.e. we compare the top-level values, but we don't work
out *their* values too, etc., the way a deep comparison would).  If
I've got it right, this is what =:=, eqv, and === give us,
respectively.


Apparently, there are _four_ basic kinds of comparison: the ones
mentioned above, and == (I believe that eq works enough like == that
whatever can be said about one in relation to ===, =:=, or eqv can be
said about the other).  I'd be quite interested in an expansion of
David's example to demonstrate how == differs from the others.

--
Jonathan Dataweaver Lang


Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-07-13 Thread Yuval Kogman
On Thu, Jul 13, 2006 at 12:50:19 -0700, Larry Wall wrote:
 On Thu, Jul 13, 2006 at 09:32:08PM +0300, Yuval Kogman wrote:
 : [1] My preferred ergonomics:
 : 
 : 1. eqv goes away
 : 2. what was eqv is renamed to ===
 : 3. === becomes =:=, which has a constant feel to it
 : 4. =:= is rarely useful IMHO, so you can just type
 : variable($x) =:= variable($y)
 
 It is important for eqv to be alphabetic so we can have the functional
 form take an optional signature parameter to specify what is compared.

There's no contradiction, === could be an alias to eqv ;-)

-- 
  Yuval Kogman [EMAIL PROTECTED]
http://nothingmuch.woobling.org  0xEBD27418



pgpPDRBxXCeip.pgp
Description: PGP signature


Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-07-13 Thread Yuval Kogman
On Thu, Jul 13, 2006 at 21:55:15 -0700, Jonathan Lang wrote:

 Apparently, there are _four_ basic kinds of comparison: the ones
 mentioned above, and == (I believe that eq works enough like == that
 whatever can be said about one in relation to ===, =:=, or eqv can be
 said about the other).  I'd be quite interested in an expansion of
 David's example to demonstrate how == differs from the others.

sub infix:== ( Any $x, Any $y ) { 
+$x === +$y; # propagate coercion failure warnings to caller
}

sub infix:eq ( Any $x, Any $y ) { 
~$x === ~$y
}


-- 
  Yuval Kogman [EMAIL PROTECTED]
http://nothingmuch.woobling.org  0xEBD27418



pgp3B4GnByYFK.pgp
Description: PGP signature


Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-07-13 Thread Jonathan Lang

Yuval Kogman wrote:

Jonathan Lang wrote:
 Apparently, there are _four_ basic kinds of comparison: the ones
 mentioned above, and == (I believe that eq works enough like == that
 whatever can be said about one in relation to ===, =:=, or eqv can be
 said about the other).  I'd be quite interested in an expansion of
 David's example to demonstrate how == differs from the others.

sub infix:== ( Any $x, Any $y ) {
+$x === +$y; # propagate coercion failure warnings to caller
}

sub infix:eq ( Any $x, Any $y ) {
~$x === ~$y
}


So the purpose of === is to provide a means of comparison that doesn't
implicitly coerce its arguments to a particular type?

--
Jonathan Dataweaver Lang


Re: ===, =:=, ~~, eq and == revisited (blame ajs!) -- Explained

2006-07-13 Thread Darren Duncan

At 10:36 PM -0700 7/13/06, Jonathan Lang wrote:

So the purpose of === is to provide a means of comparison that doesn't
implicitly coerce its arguments to a particular type?


Yes, absolutely.  The === takes 2 arguments exactly as they are, 
without changing anything, and says if they are two appearances of 
the same value.  It would always return false if the 2 arguments are 
of different declared types.  And if they are of the same types, then 
no coersion is necessary in order to compare them for equality.


Now, I didn't see them yet anywhere in Synopsis 3, but I strongly 
recommend having negated versions of all these various types of 
equality tests.  Eg, !== for ===, nev for eqv, etc.  They would be 
used very frequently, I believe (and I have even tried to do so), and 
of course we get the nice parity.


-- Darren Duncan