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-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 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 Smylers
David Green writes:

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

The currently defined behaviour seems intuitive to me, from a starting
point of Perl 5.  The difference between:

  my $new = [EMAIL PROTECTED];

and:

  my $new = [EMAIL PROTECTED];

is that the second one is a copy; square brackets always create a new
anonymous array rather than merely refering to an existing one, and
that's the same thing that's happening here.  Think of square brackets
as meaning something like Array->new and each one is obviously distinct.

> And I feel this way because [1,2] looks like it should be platonically
> unique.

I'd say that C< (1, 2) > looks like that.  But C< [1, 2] > looks like
it's its own thing that won't be equal to another one.

Smylers


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-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 peopl

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-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=;
:   @y=;
: 
:   $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,

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


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

2006-07-14 Thread Jonathan Lang

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?

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.


IIRC, this is because the implicit coercion to number or string gets
in the way.

IMHO, "@a == @b" ought to be synonymous with "all (@a »==« @b)" - it's
far more likely to DWIM.  Likewise with "@a eq @b" and "all (@a »eq«
@b)".  If what you want to do is to compare the lengths of two lists,
you ought to do so explicitly: "[EMAIL PROTECTED] == [EMAIL PROTECTED]".

Getting back to the notion of immutability: can someone give me an
example of a realistic immutable analog to a list, and then give an
example demonstrating the practical distinction between === and eqv
based on that?  I want to see why it's important to distinguish
between comparing mutable data types and comparing immutable data
types.

(Incidently, I think that a suitable word-based synonym for =:= would be "is".)

--
Jonathan "Dataweaver" Lang


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 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 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 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 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 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:

> 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-13 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-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


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: ( 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 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: ( 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 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 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 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=;
  @y=;

  $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!)

2006-07-13 Thread Darren Duncan

At 5:36 PM +0300 7/13/06, Yuval Kogman wrote:
 > User defined types can choose on their own whether to override 
=== and/or .id or not, and they would use their own knowledge of 
their internal structures to do an appropriate
 deep comparison.  There is no need to try to generate some kind of 
unique numerical .id for arbitrarily complex objects.


That creates a mess - sometimes objects compare themselves based on
their value, and sometimes based on their containing slot. These are
very different semantics.


The idea here is that === is a test for deep-as-possible immutable 
equality.  If the user-defined object is immutable, then === does a 
full deep compare.  If the object is mutable, then === goes only as 
deep as can be guaranteed will never change, which is usually what 
=:= looks at and no further.  There is no mess at all, the comparing 
by value is related to the immutability, and all objects of the same 
class would be the same in that respect.  Incidentally, your Currency 
example would likely be an immutable type. -- Darren Duncan


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 C and the
polymorphic semantics should probably be C.

Larry


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

2006-07-13 Thread Yuval Kogman
On Thu, Jul 13, 2006 at 00:55:30 -0700, Darren Duncan wrote:

> So, in the general case, it would seem best if the binary operator === was 
> just an ordinary method that each class provides, rather than requiring 
> classes to defined a .id.  Or 
> in addition to this to help with performance, a .id can exist anyway that 
> optionally returns an appropriate hash of an object.

But what is the benefit here?

Keying by object is a difficult topic. In Perl 5 you sometimes want
to key by refaddr (more often than not) because you are associating
new metadata with the instance, that does not belong inside the
instance.

On the other hand you also often want something like "$obj" to be
the key, if it can properly stringify, so that an object like a
currency:

my $x = Currency.new( code => "USD" );
my $y = Currency.new( code => "USD" );

$hash{$x} = 1;

say $hash{$y}; # 1

will DWIM. But this really depends on both the item being used,
*and* the way it is being used.

So I can see the value of making the second type of keying possible
and easy with an .id method (which at the very lowest level can
probably just emit e.g. a YAML representation of an object to ensure
uniqueness, if performance is *really* not an issue).

But this does not relate to equality, it's only useful for defining
it.

We were essentially questioning the reason === is specced to behave
as it currently does, because we feel that it's not very useful if
it's not clear cut that it should either *really* compare, or not
compare at all. And if it doesn't compare, we'd like a deep
comparison operator in S03.

> Built-in mutable types, like Array or Hash, would not override the 
> Object-defined ===, which is equivalent to =:=, nor the built-in .id, which 
> returns the object itself.  This 
> is reasonable in practice because the contents of those containers could be 
> changed at any time, especially if the containers are aliased to multiple 
> variables that are outside 
> of the testing code's control.  The only thing that can be guaranteed to be 
> constant over time is that whether or not an object is itself, as determined 
> by =:=.  By contrast, if 
> === were to do a deep copy with mutable types, the results could not be 
> trusted to be repeatable because the moment after === returns, the 
> container's value may have changed 
> again, so actions done based on the === return value would be invalid if they 
> assumed the value to still be the same at that time, such as if the mutable 
> type was used as a hash 
> key and was to be retrievable by its value.


The behavior for arrays is useless to me, because I already have
=:=. I can write a hybrid ===/=:= operator for very special cases,
but 99% of the time I want to ask "do these (arrays|hashes) contain
the same values *right now*?"

> User defined types can choose on their own whether to override === and/or .id 
> or not, and they would use their own knowledge of their internal structures 
> to do an appropriate 
> deep comparison.  There is no need to try to generate some kind of unique 
> numerical .id for arbitrarily complex objects.

That creates a mess - sometimes objects compare themselves based on
their value, and sometimes based on their containing slot. These are
very different semantics.


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



pgpxFsetaGrOi.pgp
Description: PGP signature


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

2006-07-13 Thread Darren Duncan

At 7:25 PM +0300 7/12/06, Yuval Kogman wrote:

Over at #perl6 we had a short discussion on =:=, ===, and ~~, mostly raised by
ajs's discussion on Str items and ===.



Coincidentally, I raised almost the same questions there a week 
earlier, and had a brief discussion with audreyt about it, though the 
answers that came out of it seemed rather different than what was in 
this thread so far, so I will share them.  See the following url:


http://colabti.de/irclogger/irclogger_log/perl6?date=2006-07-06,Thu&sel=376#l599

I will also quote the text as it was short, snipping out unrelated parts:

[ 11:29pm ] dduncan : slight change of topic, but I was wondering how 
.id works with non-trivial types

[ 11:29pm ] dduncan : eg, what does the .id of a Pair look like?
[ 11:29pm ] dduncan : I know that to users it shouldn't matter, but 
to people implementing composite types, it does

[ 11:30pm ] audreyt : dduncan: one possibility - could be just itself.
[ 11:33pm ] dduncan : one key thing I'm wondering about .id for 
immutable types is ... are they supposed to generate some neutral 
value like an integer, two of which can then be compared 
independently of the type definition, or will they contain references 
to the actual object all the time and that the object's class still 
needs to declare a === method which is invoked as needed?
[ 11:33pm ] dduncan : if it is the latter, I imagine that 
implementation will be simpler, at a possible cost of performance if 
the same comparison is done a lot

[ 11:34pm ] audreyt : dduncan: the latter
[ 11:34pm ] dduncan : okay, that answers my question

So, in the general case, it would seem best if the binary operator 
=== was just an ordinary method that each class provides, rather than 
requiring classes to defined a .id.  Or in addition to this to help 
with performance, a .id can exist anyway that optionally returns an 
appropriate hash of an object.


A default === would be defined in Object, which returns the same 
result as =:= returns; two objects are equivalent iff they are the 
same container.  A default .id defined in Object would simply return 
the same object it was invoked on.


Built-in immutable types, like Str and Int and Pair and Seq, would 
override that === such that they return true iff the two operands are 
containers of the same class and the two containers both hold 
appearances of the same (universally distinct) value.  This is 
determined by doing a deep comparison of the values themselves, as is 
appropriate.  (Internally to the type's implementation, a 
domain-appropriate hash of the value could optionally be generated at 
an appropriate time and be used to speed up === operations, with 
appropriate action taken if it isn't guaranteed that multiple 
distinct values won't become identical hash values.)  The .id could 
be overridden to return a simple number or string or binary for 
simpler types, and return the object itself otherwise.


Built-in mutable types, like Array or Hash, would not override the 
Object-defined ===, which is equivalent to =:=, nor the built-in .id, 
which returns the object itself.  This is reasonable in practice 
because the contents of those containers could be changed at any 
time, especially if the containers are aliased to multiple variables 
that are outside of the testing code's control.  The only thing that 
can be guaranteed to be constant over time is that whether or not an 
object is itself, as determined by =:=.  By contrast, if === were to 
do a deep copy with mutable types, the results could not be trusted 
to be repeatable because the moment after === returns, the 
container's value may have changed again, so actions done based on 
the === return value would be invalid if they assumed the value to 
still be the same at that time, such as if the mutable type was used 
as a hash key and was to be retrievable by its value.


User defined types can choose on their own whether to override === 
and/or .id or not, and they would use their own knowledge of their 
internal structures to do an appropriate deep comparison.  There is 
no need to try to generate some kind of unique numerical .id for 
arbitrarily complex objects.


One thing that can't be overridden is that === can only return true 
iff both operands are of the same class.  This includes undef, as 
each class has its own undef that is distinct from those of other 
classes.


So if this is the way that things worked, then it would be very easy 
to implement it for any kind of type.  And it would be very reliable 
to use any type as a hash key.


Note that, while the fact may be determinable by some other means, it 
may be useful to have an explicit meta-method for all types that says 
whether the type is immutable or mutable.  A user defined type saying 
that it is immutable is making a promise to the compiler that its 
objects won't change after they are created.


As for being able to tersely do deep comparisons of mutable types, I 
don't think that === is ap

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

2006-07-12 Thread Aaron Sherman

Yuval Kogman wrote:

On Wed, Jul 12, 2006 at 17:58:03 -0400, Aaron Sherman wrote:

  

Then ~~ is wrong in that respect, and I think we should be talking about
that, not about making === into "~~, but without invoking code when it
shouldn't."



But it should! It's the smart match! If the rhs matches the code ref
(the code ref gets it as an argument it's a match!

That's why ~~ isn't a comparison operator, but a smart match
operator - it DWIMs *very* deeply


DWIM generally means "don't shoot me in the head for trying this", and 
it can be strongly argued that C is almost certain to shoot 
you in the head a couple of times in your P6 career if we don't fix it.


Now, I'm all for every single case that Larry put in the table for Smart 
Matching in S03... EXCEPT FOR RUNTIME DISPATCH! There are only two cases 
of runtime dispatch in there that you could possibly invoke: Array/Array 
and Any/Any. Fix those two, and I think ~~ DWIMs safely and just as 
powerfully (perhaps much more so).


My suggestion (falling back to a much simpler and less dynamic =~= for 
runtime dispatch) is one way to fix them, and I think that if we DO fix 
them in that manner, then no one's expectations will be violated (unless 
you expected C<@a1 ~~ @a2> to be shorthand for a function vector, 
dot-product-like, parallel dispatch, in which case I'm going to make the 
suggestion that you quietly retire from public life and find a nice 
place in the mountains. ;-)


Really, all of the magic on ~~ isn't intended for such runtime traversal 
of containers. it's intended for the immediate semantic value of the 
compile-time typed match, most notably in the case of given which has 
more connotations to hang semantic meaning off of in English. To invoke 
those special rules when recursively evaluating the "sameness" of 
containers doesn't even make sense if you stop and consider why you 
would do such a comparison. Why is C<$a ~~ $b> going to invoke code when 
I know nothing about $a and $b at compile time? Is that useful other 
than in defining an alias for ~~?




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

2006-07-12 Thread Yuval Kogman
On Wed, Jul 12, 2006 at 16:16:13 -0400, Aaron Sherman wrote:

> The other way to think about === would be that it tells you if its LHS
> *could* be constant-folded onto its RHS (if it were constant for long
> enough)

What is the benefit here?

> Because of the word "deep". Deep implies arbitrary work, which isn't
> really what you want in such a low-level operator. However, using these
> operator, one could easily build whatever you like.

The number of times i *sigh*ed at having to reinvent deep operators
in a clunky way in Perl 5 is really not in line with Perlishness and
DWIM.

Also ~~ is deep in exactly the same way.

Perl is also not low level.

I could build it, and I have, but I don't want to.

It can short circuit and be faster when the structure is definitely
not the same (totally different early on) or definitely the same
(refaddr is equal, etc).

Should I go on?

> I'd avoid saying "memory", here. Some implementations of Perl 6 might
> not know what memory looks like (on a sufficiently abstract VM).

"Slot"

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



pgpvVdjsJ0Et9.pgp
Description: PGP signature


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

2006-07-12 Thread Yuval Kogman
On Wed, Jul 12, 2006 at 17:58:03 -0400, Aaron Sherman wrote:

> Then ~~ is wrong in that respect, and I think we should be talking about
> that, not about making === into "~~, but without invoking code when it
> shouldn't."

But it should! It's the smart match! If the rhs matches the code ref
(the code ref gets it as an argument it's a match!

That's why ~~ isn't a comparison operator, but a smart match
operator - it DWIMs *very* deeply.

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



pgpyx4u1552HO.pgp
Description: PGP signature


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

2006-07-12 Thread Yuval Kogman
On Wed, Jul 12, 2006 at 16:16:13 -0400, Aaron Sherman wrote:

> Isn't that ~~?
> 
> Per S03:
> 
> Array   Array arrays are comparablematch if $_ »~~« $x
> 
> ~~ is really the all-purpose, bake-your-bread, clean-your-floors,
> wax-your-cat operator that you're looking for.

Not at all, because:

( [ 1, 2 ], 3 ) ~~ ( { 1 }, { 1 } )

It's matching, not equality.

> which is true. Ain't recursive hyperoperators grand?

It isn't a hyperoperator, it's just recursive ;-)

> > 2. is .id *always* a low level type representation of the object's value? 
> > It's
> > specced that low level typed items have the same ID when they have the same
> > value. What about complex types?
> 
> It cannot be for complex types or even strings... well, at least it
> I not be I we care about performance

That's orthogonal. .id is used for hash keys. If you're keying y
hubble images then they must be unique for some keyspace, and that's
where .id makes a mapping.

> =:= looks in the "symbol table" (caveat dragons) to see if LHS
> refers to the same variable as the RHS. Does this dereference?
> Probably not, but I'm not sure, based on S03.

Then it's a purely lexical opeation, and it doesn't even work for 

my $x := $array[3];

$x =:= $array[3];

but i'll pretend you didn't say that ;-)

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



pgpPMmzta8SWk.pgp
Description: PGP signature


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

2006-07-12 Thread Aaron Sherman
On Wed, 2006-07-12 at 15:32 -0500, Jonathan Scott Duff wrote:
> On Wed, Jul 12, 2006 at 04:16:13PM -0400, Aaron Sherman wrote:
> > On Wed, 2006-07-12 at 19:25 +0300, Yuval Kogman wrote:
> > > 4. will we have a deep (possibly optimized[1]) equality operator, that
> > > *will* return true for @foo = ( [ 1, 2 ], 3 ); @bar = ( [ 1, 2 ], 3 ); 
> > > op(@foo, @bar)?
> > > Is it going to be easy to make the newbies use that when they mean "it's 
> > > the
> > > same", like they currently expect == and eq to work on "simple" values?
> > 
> > Isn't that ~~?

[...] # hmm, what kind of reduction IS that? ;)

> > ~~ is really the all-purpose, bake-your-bread, clean-your-floors,
> > wax-your-cat operator that you're looking for.
> 
> Granted, ~~ will return true in that case.  I think the main problem
> is Yuval wants a guarantee that it will return true if and only if
> the things on either side have the same deep structure and values.
> 
> Currently, ~~ will also return true for structures where this does
> not hold.  For example:
> 
> @a = ( [ 1, 2] , 3 );
> @b = ( sub { return 1 }, sub { return 1 } );
> @a ~~ @b;   # true

Then ~~ is wrong in that respect, and I think we should be talking about
that, not about making === into "~~, but without invoking code when it
shouldn't."

> Why is that true?  By the rules of hyper-operation, it turns into
> this:
> 
> [1,2] ~~ sub { return 1 }
> 3 ~~ sub { return 1 }
> 
> which is true if these return true values:
> 
> sub { return 1 }->([1,2])
> sub { return 1 }->(3)

OK, so this always bothered me, I just wasn't sure why. Now I know, and
I think I agree with Yuval quite a bit more. ~~ should never imply
running it's data arguments as code *when dispatched at runtime*. It's:

  * likely to cause security problems when I accidentally compare a
safe, internal structure that (probably unknown to me) contains
code against an unsafe, external structure that I got from a
user.
  * potentially a destructive comparison.
  * potentially not hyper-parallelization friendly
  * probably bad in other ways I could think of, given time.

Let me boil that down to a simple assertion: comparison via ~~ which
will have to perform run-time dispatch should never I to have
side-effects (dynamic language, caveat, caveat...)

So, I do agree that we need a new operator, but I disagree about how it
should be used. I'd suggest:

C<=~=>

This is similar to C<~~> for arguments that are simple value types such
as C or C.

For objects which do not have a C<=~=> operation, C<===> is invoked.

By default, the only objects which will define a C<=~=> operation will
be containers, which will look like:

our Bool multi submethod infix:<=~=> ($a: Container $b) {
[&&] $a >>=~=<< $b;
}

which works for Hashes too, since a Pair is a container, so we'll just
recursively hyperoperate through each of the hash's .kv Pairs, comparing
them, though it might have to sort the Pairs by keys in order to assure
it's comparing apples to apples.

That's it. Just three types of behavior, unlike ~~s massive table of
behavior.

Then, in the table for C<~~>:

$_  $xType of Match ImpliedMatching Code
==  = ==
...
Array   Array arrays are comparablematch if $_ »=~=« $x
...
Any Any   run-time dispatchmatch if infix:<=~=>($_, $x)

The first change is to Array/Array, and this is to minimize surprises
when comparing containers. There might be a special case for containers
that have typed buckets, but I'm not even going to touch that right now.
The second change is to Any/Any, and that's purely a matter of putting
the control in the hands of the caller, not whoever constructed the
caller's data. Anything else is a debugging nightmare.

In general, I would expect that no one would use =~= directly (hence the
ugly, name that's longer than ~~), it's just an implementation detail of
run-time dispatch on ~~

Thoughts?

-- 
Aaron Sherman <[EMAIL PROTECTED]>
Senior Systems Engineer and Toolsmith
"We had some good machines, but they don't work no more." -Shriekback




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

2006-07-12 Thread Jonathan Scott Duff
On Wed, Jul 12, 2006 at 04:16:13PM -0400, Aaron Sherman wrote:
> On Wed, 2006-07-12 at 19:25 +0300, Yuval Kogman wrote:
> > 4. will we have a deep (possibly optimized[1]) equality operator, that
> > *will* return true for @foo = ( [ 1, 2 ], 3 ); @bar = ( [ 1, 2 ], 3 ); 
> > op(@foo, @bar)?
> > Is it going to be easy to make the newbies use that when they mean "it's the
> > same", like they currently expect == and eq to work on "simple" values?
> 
> Isn't that ~~?
> 
> Per S03:
> 
> Array   Array arrays are comparablematch if $_ »~~« $x
> 
> ~~ is really the all-purpose, bake-your-bread, clean-your-floors,
> wax-your-cat operator that you're looking for.

Granted, ~~ will return true in that case.  I think the main problem
is Yuval wants a guarantee that it will return true if and only if
the things on either side have the same deep structure and values.

Currently, ~~ will also return true for structures where this does
not hold.  For example:

@a = ( [ 1, 2] , 3 );
@b = ( sub { return 1 }, sub { return 1 } );
@a ~~ @b;   # true

Why is that true?  By the rules of hyper-operation, it turns into
this:

[1,2] ~~ sub { return 1 }
3 ~~ sub { return 1 }

which is true if these return true values:

sub { return 1 }->([1,2])
sub { return 1 }->(3)

Which they do.

So, smart-match fails as a "deep equality" operator precisely
because it's so smart.

-Scott
-- 
Jonathan Scott Duff
[EMAIL PROTECTED]


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

2006-07-12 Thread Aaron Sherman
On Wed, 2006-07-12 at 19:25 +0300, Yuval Kogman wrote:
> Over at #perl6 we had a short discussion on =:=, ===, and ~~, mostly raised by
> ajs's discussion on Str items and ===.

*wave*

> 1. what is .id on references? Is it related to the memory slot, like refaddr()
> in Perl 5?

That's something I'm not sure of, so I'll let it go, other than to say
that that question should probably avoid the word "memory", see below.

4. will we have a deep (possibly optimized[1]) equality operator, that
*will*

Now, let me handle this one out of order, since I think it's really key:

> return true for @foo = ( [ 1, 2 ], 3 ); @bar = ( [ 1, 2 ], 3 ); op(@foo, 
> @bar)?
> Is it going to be easy to make the newbies use that when they mean "it's the
> same", like they currently expect == and eq to work on "simple" values?

Isn't that ~~?

Per S03:

Array   Array arrays are comparablematch if $_ »~~« $x

~~ is really the all-purpose, bake-your-bread, clean-your-floors,
wax-your-cat operator that you're looking for.

It sounds like pugs is wrong here WRT the spec, since:

( [ 1, 2 ], 3 ) ~~ ( [ 1, 2 ], 3 )

is the same as:

[1,2]~~[1,2] && 3 ~~ 3

which is the same as:

(1~~1 && 2~~2) && 3~~3

which is true. Ain't recursive hyperoperators grand? Of course, I'm
assuming that a comparison hyperoperator in boolean context returns the
[&&] reduction of all of the values... that's an interesting assumption,
isn't it? But, it seems to be the assumption made by S03 under Smart
Matching, so I say it's true. ;)

> 2. is .id *always* a low level type representation of the object's value? It's
> specced that low level typed items have the same ID when they have the same
> value. What about complex types?

It cannot be for complex types or even strings... well, at least it
I not be I we care about performance.

That is, if C<$anything.id> needs to read every byte of $anything, then
an anything that happened to be a Buf containing the 3GB in-memory raw
image from the Hubble is going to really make C<.id> unhappy. I would
hope that C<.id> is an efficient enough operation that === should not
look like a performance bottleneck in my code

> 3. Are these descriptions of the operators correct?
> 
>   ~~ matches the left side to a description on the right side

>   =:= makes sure the objects are actually the same single object (if $x 
> =:= $y
>   and you change $x. then $y. was also changed... is
>   this .id on refs?) Is =:= really eq .id? or more like
>   variable($x).id eq variable($y).id?

>   === makes sure that the values are equivalent ( @foo = ( 1, 2, 3 ); 
> @bar = ( 1,
>   2, 3); @foo === @bar currently works like that, but @foo = ( [ 1, 2 ], 
> 3 );
>   @bar = ( [ 1, 2 ], 3 ); @foo === @bar does not (in pugs). This is not 
> useful
>   because we already have this return false with =:=).


Let me counter-propose a slightly different way of saying that:

~~ as above. I think we all agree on this.

=:= looks in the "symbol table" (caveat dragons) to see if LHS
refers to the same variable as the RHS. Does this dereference?
Probably not, but I'm not sure, based on S03.

=== Compares types and .id values. An implementation of this, as
I interpreted S03, and with some assumptions made, and with some
extra bits filling in the cracks where S03 didn't quite specify
an implementation:

  * A .id method may return C, C or C. ===
returns false for two objects which are not the same
type (with the same traits), and thus the comparison
must always be between identical .id return types.
  * As a special case, however, all "undefined" values (not
objects which have the undefined trait, but true undefs
with no other functionality) are === to each other.
  * Objects are always compared according to their
underlying type, not the polymorphic role which they are
serving at the moment.
  * num, Num and all like values return their num
representation as a .id.
  * int, Int and all like values return their int
representation as a .id.
  * Bool, bool and bit all have a bit representation for .id
  * All other code, objects, references, structures, complex
numbers, etc. are compared strictly on the basis of an
arbitrary C which Perl will generate to represent
their storage, and can be overridden by replacing the
default .id method.

The other way to think about === would be that it tells you if its LHS
*could* be constant-folded onto its RHS (if it were constant for long
enough), where =:= tells you if that has already been done. Only ~~ has
some sort of "deep" semantics, and I think the documentation warns users
s

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

2006-07-12 Thread Yuval Kogman
Jedai and I went through some of pugs current implementations. Here's a list of
what we expect the operators to return and what they currently do.

This does not exactly agree with S03 right now, but is our opinion.

Force into a type before comparing values:

42 == 42 - true, same numeric value

"42" == 42 - true, same numeric value

"42" == "42" - true, same numeric value

" 42 " == "42.0" - true, same numeric value

" 42 " eq "42.0" - false, different string value

4 eq "4" - true, same string value

Well typed value comparison:

42 === 42 - true, the same type

"42" === 42 - false, not the same type

"42" === "42" - true, the same type

" 42 " === "42.0" - false, different value in "natural" type (string 
values)

(1, 2, 3) === (1, 2, 3) - true, same value

([1, 2 ], 3 ) === ([1, 2 ], 3) - true, same value - BROKEN (actually 
false,
since refs are not the same). S03 thinks this is actually OK.

[1, 2, 3] === [1, 2, 3] - true, same value, (S03 says that this is 
actually
broken, because references should not be the same (we disagree))

my @foo = (1, 2, 3); my @bar = @foo; @foo === @bar - true, same value.

my @foo = ([1, 2], 3); my @bar = @foo; @bar === @foo - true, same value 
-
BROKEN (S03 actually agrees with us here, since the ref is the same in 
this
case)

Slot/container equality (this is actually up to debate, but this is what we
would expect if it was refaddr($x) == refaddr($y)):

[ 1, 2, 3 ] =:= [ 1, 2, 3 ] - false, different containers - BROKEN
(actually true)

my $foo = [ 1, 2, 3 ]; $foo =:= $foo - true, same container

my $foo = [ 1, 2, 3 ]; my $bar := $foo; $bar =:= $foo - true, same 
container

my $foo = [ 1, 2, 3 ]; my $bar = $foo; $bar =:= $foo - true, ref to same
container, or false since different container, unsure - currently true

my @foo = (1, 2, 3); my @bar = @foo; @foo =:= @bar - false, container
should be different - BROKEN (actually true)

my @foo = (1, 2, 3); my @bar = @foo; @bar[1] = "moose"; @foo =:= @bar -
false, container should be different. This actually works like we 
expected,
appearantly pugs does some sort of COW

Under := slot semantics the first test should be false, the second should be
true, the third should be true, the fourth should be false, the fifth should be
false, and the sixth should be false.


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



pgpNFsdSOd2Lf.pgp
Description: PGP signature


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

2006-07-12 Thread Yuval Kogman
If we do have deep value equality checks, then "default" == and eq
are probably:

sub &infix:<==> ( $x, $y ) {
+$x === +$y;
}

sub &infix: ( $x, $y ) {
~$x === ~$y;
}

So that the compare-as-sometype behavior is retained from perl 5
without introducing new complexity to the objects being compared as
strings/numbers.

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



pgpefrROP9pJ6.pgp
Description: PGP signature


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

2006-07-12 Thread Yuval Kogman
Over at #perl6 we had a short discussion on =:=, ===, and ~~, mostly raised by
ajs's discussion on Str items and ===.

After a brief discussion we managed to formulate several questions that we feel
are slightly to totally unresolved.

1. what is .id on references? Is it related to the memory slot, like refaddr()
in Perl 5?

2. is .id *always* a low level type representation of the object's value? It's
specced that low level typed items have the same ID when they have the same
value. What about complex types?

3. Are these descriptions of the operators correct?

~~ matches the left side to a description on the right side

=:= makes sure the objects are actually the same single object (if $x 
=:= $y
and you change $x. then $y. was also changed... is
this .id on refs?) Is =:= really eq .id? or more like
variable($x).id eq variable($y).id?

=== makes sure that the values are equivalent ( @foo = ( 1, 2, 3 ); 
@bar = ( 1,
2, 3); @foo === @bar currently works like that, but @foo = ( [ 1, 2 ], 
3 );
@bar = ( [ 1, 2 ], 3 ); @foo === @bar does not (in pugs). This is not 
useful
because we already have this return false with =:=).

If they are not correct, why is there an overlap between =:=? Why is it hard to
deeply compare values in 2006 without using e.g. Data::Compare?

4. will we have a deep (possibly optimized[1]) equality operator, that *will*
return true for @foo = ( [ 1, 2 ], 3 ); @bar = ( [ 1, 2 ], 3 ); op(@foo, @bar)?
Is it going to be easy to make the newbies use that when they mean "it's the
same", like they currently expect == and eq to work on "simple" values?

5. is there room for a new opperator?

=::= makes sure the memory slot  is the same (might be different
for simple values). refaddr($x) == refaddr($y) in Perl 5

=:= makes sure that .ids are the same, and is useful if the .id
method is meaningful for an object. A bit like Test::More::is(
$x, $y ) but without the diagnosis in Perl 5, or abusing eq if
the object doesn't overload stringification.

=== makes sure the values are the same even if they are
copies/clones/whatever. Data::Compare in Perl 5. A bit like what
people overload == for in Perl 5 right now (which confuses
"numerical" equality with "true" equality, so we want to phase
that out).

~~ makes sure the value on the right side describes the value on
the left side. Reminiscient of Test::Deep::cmp_deeply, with all
the various matching magic.

Thanks,

[1] It could, of course, be just =:= && === inside, and it could optimize
arrays to check length first, and it could cache checksums and it could do
whatever - please don't bring this up as a performance issue, it is one of
correctness and ergonomics that must be resolved first.

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



pgpI98L8HHVih.pgp
Description: PGP signature