identity tests and comparing two references

15 views
Skip to first unread message

Darren Duncan

unread,
Apr 1, 2005, 2:46:22 AM4/1/05
to perl6-l...@perl.org
As I continue porting code to Perl 6, I found something else that the
synopsis don't seem to explain clearly.

What I want to be able to do is compare two references to see if they
point to the same thing, in this case an object, but in other cases
perhaps some other type of thing.

In synopsis 3, under the 'Binding' section, the =:= operator
description is vague to the point that I don't know whether it
applies to my problem or not. All I know for sure is that '$x =:=
$y' will return true if previously '$y := $x', and I think that is a
different situation than my pair of references.

In Perl 5, a standard string compare just so happened to work for
comparing two object refs, but that was inelegant. In Perl 6 I need
something better than comparing stringified ('eq') or numified ('==')
versions of the objects.

The ref compare should have its own operator.

Now I seem to remember reading somewhere that '===' will do what I
want, but I'm now having trouble finding any mention of it.

So, what is the operator for reference comparison?

Thank you. -- Darren Duncan

Sam Vilain

unread,
Apr 1, 2005, 2:56:11 AM4/1/05
to Darren Duncan, perl6-l...@perl.org
Darren Duncan wrote:
> Now I seem to remember reading somewhere that '===' will do what I want,
> but I'm now having trouble finding any mention of it.
> So, what is the operator for reference comparison?

As someone who wrote a tool that uses refaddr() and 0+ in Perl 5 to
achieve the same thing, I agree with the need for such an operator.

I think that =:= compares *lexical* identity is fairly clearly spelled
out in S03. However, we need a way to compare *value* /identity/ (not
equality or equivalence), without being subject to overloading etc.

Of course, actually comparing two `ref' or `Ref' objects for pointing
to the same place is achieved via `==' (or, if === is used, ${$ref1} ===
${$ref2} or the P6 equivalent :) )

Sam.

Aaron Sherman

unread,
Apr 1, 2005, 8:04:22 AM4/1/05
to Darren Duncan, Perl6 Language List
On Thu, 2005-03-31 at 23:46 -0800, Darren Duncan wrote:

> What I want to be able to do is compare two references to see if they
> point to the same thing, in this case an object, but in other cases
> perhaps some other type of thing.

Let's be clear about the difference between P5 and P6 here. In P5, an
object was actually a reference with special magic that indicated that
it was also tied to a package.

In P6, an object is a data-type. It's not a reference, and any member
payload is attached directly to the variable.

So, comparing references to objects isn't all that common in P6, though
it could certainly happen.

Now, back to the concept of identity comparison... I would expect that
you could do this:

$ref1 ~~ $ref2

The table in S4 doesn't have an entry for "Any ~~ Reference", but my
guess is that that's just an oversight, as it seems to fit into the flow
nicely.

More generally, I see no direct way to tell if two values have the same
storage (the same PMC in Parrot), so you might have to do something
P5ish:

\$a ~~ \$b


Luke Palmer

unread,
Apr 1, 2005, 10:39:52 AM4/1/05
to Sam Vilain, Darren Duncan, perl6-l...@perl.org
Sam Vilain writes:
> Darren Duncan wrote:
> >Now I seem to remember reading somewhere that '===' will do what I want,
> >but I'm now having trouble finding any mention of it.
> >So, what is the operator for reference comparison?
>
> As someone who wrote a tool that uses refaddr() and 0+ in Perl 5 to
> achieve the same thing, I agree with the need for such an operator.
>
> I think that =:= compares *lexical* identity is fairly clearly spelled
> out in S03. However, we need a way to compare *value* /identity/ (not
> equality or equivalence), without being subject to overloading etc.

I'm pretty sure that =:= does what you want. If you have two scalar
references, you might have to spell it like this:

$$x =:= $$y

And binding can't be overloaded[1], so you don't have to worry about
that.

Luke

[1] Or maybe it can, but like the prefix & operator in C++, only people
who really know what they're doing will overload it.

Larry Wall

unread,
Apr 1, 2005, 10:37:43 AM4/1/05
to perl6-l...@perl.org
On Thu, Mar 31, 2005 at 11:46:22PM -0800, Darren Duncan wrote:
: So, what is the operator for reference comparison?

The =:= operator is almost certainly what you want here.

Larry

Larry Wall

unread,
Apr 1, 2005, 10:46:02 AM4/1/05
to Perl6 Language List
: On Thu, 2005-03-31 at 23:46 -0800, Darren Duncan wrote:

On Fri, Apr 01, 2005 at 08:04:22AM -0500, Aaron Sherman wrote:
:
: > What I want to be able to do is compare two references to see if they
: > point to the same thing, in this case an object, but in other cases
: > perhaps some other type of thing.
:
: Let's be clear about the difference between P5 and P6 here. In P5, an
: object was actually a reference with special magic that indicated that
: it was also tied to a package.
:
: In P6, an object is a data-type. It's not a reference, and any member
: payload is attached directly to the variable.

Well, it's still a reference, but we try to smudge the distinction in P6.

: So, comparing references to objects isn't all that common in P6, though


: it could certainly happen.
:
: Now, back to the concept of identity comparison... I would expect that
: you could do this:
:
: $ref1 ~~ $ref2

No, ~~ will deref any explicit references and smart match against
what is referenced. That's part of the intentional smudging.

: The table in S4 doesn't have an entry for "Any ~~ Reference", but my


: guess is that that's just an oversight, as it seems to fit into the flow
: nicely.

That would be going back to the P5 way of thinking. The ~~ operator
doesn't try to guess whether the user meant references to refer to
themselves or their referent. It always assumes the referent. Note
that when you say

@foo ~~ @bar

it's actually passing two array references to ~~, for instance, since
they're in scalar context.

: More generally, I see no direct way to tell if two values have the same


: storage (the same PMC in Parrot), so you might have to do something
: P5ish:
:
: \$a ~~ \$b

Wouldn't work. Ends up doing the same as $a ~~ $b.

Anyway, that's what =:= is there for.

Larry

Larry Wall

unread,
Apr 1, 2005, 10:47:54 AM4/1/05
to perl6-l...@perl.org
On Fri, Apr 01, 2005 at 08:39:52AM -0700, Luke Palmer wrote:
: I'm pretty sure that =:= does what you want. If you have two scalar

: references, you might have to spell it like this:
:
: $$x =:= $$y

Unnecessary, I think. I want

$x =:= @y

to tell me whether the reference in $x is to the same array as @y.

Larry

Aaron Sherman

unread,
Apr 1, 2005, 11:44:13 AM4/1/05
to Larry Wall, Perl6 Language List
On Fri, 2005-04-01 at 10:46, Larry Wall wrote:
> On Fri, Apr 01, 2005 at 08:04:22AM -0500, Aaron Sherman wrote:

> : In P6, an object is a data-type. It's not a reference, and any member
> : payload is attached directly to the variable.
>
> Well, it's still a reference, but we try to smudge the distinction in P6.

Hrm... ok, I'm a bit confused, probably because I'm thinking in terms of
Parrot.

In Parrot, an object PMC is not a reference, it's of some object type
and contains fields directly in the PMC for any member data. There's
also a vtable which tells you everything you need to know about its
methods.

So you're saying that P6 will only manipulate Parrot-level object PMCs
via references? If so, sorry, I just didn't realize that.

--
Aaron Sherman <a...@ajs.com>
Senior Systems Engineer and Toolsmith
"It's the sound of a satellite saying, 'get me down!'" -Shriekback


Juerd

unread,
Apr 1, 2005, 3:35:37 PM4/1/05
to perl6-l...@perl.org
Larry Wall skribis 2005-04-01 7:47 (-0800):

> : $$x =:= $$y
> Unnecessary, I think. I want
> $x =:= @y
> to tell me whether the reference in $x is to the same array as @y.

But

my $foo;
my $bar := $foo;
my $baz = \$foo;

$foo :=: $bar; # true
$foo :=: $baz; # also true?!

$bar = 1; # updates $foo
$baz = 2; # does not update $foo

IMO, :=: should not auto(de)reference.


Juerd
--
http://convolution.nl/maak_juerd_blij.html
http://convolution.nl/make_juerd_happy.html
http://convolution.nl/gajigu_juerd_n.html

Darren Duncan

unread,
Apr 1, 2005, 3:28:46 PM4/1/05
to perl6-l...@perl.org

Thanks to everyone for their answers. Last night I started coding
with =:= by default since it was the best self-documenting option I
could see, then lacking a definitive answer. From what I've read of
your responses, this seems to have been the right choice. So I will
assume that =:= is the definitive answer until the official docs
decide to unambiguously say otherwise. -- Darren Duncan

Juerd

unread,
Apr 1, 2005, 3:38:47 PM4/1/05
to perl6-l...@perl.org
Juerd skribis 2005-04-01 22:35 (+0200):

> $foo :=: $bar; # true
> $foo :=: $baz; # also true?!
> IMO, :=: should not auto(de)reference.

s:g/:=:/=:=/

Thomas Sandlaß

unread,
Apr 1, 2005, 4:37:29 PM4/1/05
to perl6-l...@perl.org
Juerd wrote (with substitution applied):
> IMO, =:= should not auto(de)reference.

So you expect $bar to contain value 2 and detach from $foo?
How would one then reach the value in $foo? With $$baz?
And for longer chains of referene with a corresponding number
of $ on the front? But IIRC that was obviated in Perl6.
--
TSa (Thomas Sandlaß)

Juerd

unread,
Apr 1, 2005, 5:20:46 PM4/1/05
to Thomas Sandlaß, perl6-l...@perl.org
Thomas Sandlaß skribis 2005-04-01 23:37 (+0200):

> Juerd wrote (with substitution applied):
> >IMO, =:= should not auto(de)reference.
> So you expect $bar to contain value 2 and detach from $foo?

No. But if you said $baz instead of $bar, then yes.

> How would one then reach the value in $foo? With $$baz?

Assuming you did mean $baz in the previous line, yes.

> And for longer chains of referene with a corresponding number
> of $ on the front? But IIRC that was obviated in Perl6.

Exactly.

Because an array in scalar context is automatically referenced, and an
arrayref in array context is automatically dereferenced, that implicity
can exist. But a reference IS a scalar, and having scalars reference or
dereference in scalar context automatically is madness. And if we're
saying that an array is a scalar as much as a string or a number is,
then why are values mutable, do scalars not have three different sigils
and do things automatically convert without the intervention of lists?

If =:= tests variable sameness, then it should do that literally in
order to both be useful and look like :=. For reference equality you can
still use \FOO == \BAR (I assume).

Thomas Sandlaß

unread,
Apr 1, 2005, 6:17:28 PM4/1/05
to perl6-l...@perl.org
HaloO Juerd,

you wrote:
> Thomas Sandlaß skribis 2005-04-01 23:37 (+0200):

>>So you expect $bar to contain value 2 and detach from $foo?
>
> No. But if you said $baz instead of $bar, then yes.

Ohh sorry, I mis-read your mail as talking about chains of
references: $baz to $bar to $foo to 2. The last step could
also be direct storage. Then my question was if an assignment
is forwarded along this chain or if a ref is somehow manipulating
it's target directly. Consider:

my $one = 1;
my $two := $one;
my $three = \$two; # same as := ? was actually your question, or not?
my $four := three;
my $five = 5;

$four = 4; # $one == 4 now?
$$four := $five;

say $three; # prints 5?


> then why are values mutable, do scalars not have three different sigils
> and do things automatically convert without the intervention of lists?

Values are immutable in the abstract. That means 3 is always 3. Only variables
change (reference to) value, hence the name. An object that is not referenced
and objects that just reference each other are garbage collected! For simple
values the reference is optimised into direct storage if possible. These two
things are the implementation of conceptually immutable values.

By introducing a finite

subtype Example of Array where { is shape(0..9) of Bool };

you have 1024 possible immutable values which could be pre-allocated
and then referenced as needed. For less restricted types you get so many
possible values that other implementation strategies are needed :)
Calling a method through a variable conceptually produces a new value
of the object type in question which in turn is implemented by changing
the object in place for practical reasons.


> If =:= tests variable sameness, then it should do that literally in
> order to both be useful and look like :=. For reference equality you can
> still use \FOO == \BAR (I assume).

In my view of the world =:= checks for identity of values. Equality could
hold for non-identical objects. E.g. a complex number object with imaginary
part 0 could be considered equal to a real number with the value of the
real part of the complex number:

my Complex $complex = (3.2, 0);
my Num $real = 3.2;

$complex =:= $real # false
$complex == $real # true

The above would of course be implemented by installing apropriate multis
for &infix:<==> from the Complex class. Overloading =:= OTOH will be hardly
necessary nor usefull.
--
TSa (Thomas Sandlaß)

James Mastros

unread,
Apr 1, 2005, 3:48:17 PM4/1/05
to perl6-l...@perl.org

$x = 42;
$a = \$x but false;
$b = \$y but blue;

$a =:= $b ???

If it's true, then the =:= operator is pretty useless -- two things that
are =:= to each-other can have very different semantics. If it's not,
then there needs to be some other way to tell. $$a =:= $$b feels sane
to me. So does $a == $b.

I generally don't like it when things half-smudge important differences.
Either there should be no difference between a reference and a
referent, or there should be. We shouldn't try to hide important
truths. (This is why I don't like CGI.pm's HTML generation, for example
-- it makes you feel like you don't need to know HTML, when you do.)

-=- James Mastros

Thomas Sandlaß

unread,
Apr 1, 2005, 7:17:13 PM4/1/05
to perl6-l...@perl.org
James Mastros wrote:
> $x = 42;
> $a = \$x but false;
> $b = \$y but blue;

Assuming you meant \$x in the last row we are dealing with three values:
42 but true
42 but false
42 but blue

Which are not identical but equal. The first value is not necessarily
implemented that way because the boolean value can be calculated on demand.
And $a and $b none the less manage to change the value in $x when new
values are assigned to them, and these can be retrieved via $x. If you meant
true not blue in the last line than $b =:= $x.


> $a =:= $b ???
>
> If it's true, then the =:= operator is pretty useless -- two things that
> are =:= to each-other can have very different semantics. If it's not,
> then there needs to be some other way to tell. $$a =:= $$b feels sane
> to me. So does $a == $b.

I think =:= shall supersede the $ chains in front of refs by always
dereferencing through to value level and accumulating traits while doing
so. Usually you don't even know how many levels of indirection there are.


> I generally don't like it when things half-smudge important differences.

Me neither.
--
TSa (Thomas Sandlaß)

Juerd

unread,
Apr 2, 2005, 4:06:01 AM4/2/05
to Thomas Sandlaß, perl6-l...@perl.org
Thomas Sandlaß skribis 2005-04-02 1:17 (+0200):

> my $one = 1;
> my $two := $one;
> my $three = \$two; # same as := ? was actually your question, or not?

No, that was not my question. I deliberately used binding and
assignment, for there to be an important difference, which I think =:=
should reflect. It should be true if both variables are the same thing,
without looking at the values. In other words: FOO =:= BAR should really
do \FOO == \BAR, with the \ applied symmetrically, so that if BAR is
only a reference to FOO, the outcome is false, for \FOO != \\BAR.

> my $four := three;

Assuming you meant $three instead of three.

> my $five = 5;
> $four = 4; # $one == 4 now?

No, $four (and thus $three, which it is bound to) is now 4. $three is a
reference, which is a value, which is now *replaced* with the new value.

> $$four := $five;

Cannot dereference a number. I'm assuming autovivification will continue
to not work on non-undef values.

> Values are immutable in the abstract. That means 3 is always 3.

Is that so? Are we going to walk the path of inefficiency where $foo++
is really actually literally just $foo = $foo + 1, throwing away the old
variable, assigning a new one?

And will Perl 6 reference values rather than their containers, that is:
will \$foo differ when $foo gets a new value, just as in Python id(foo)
changes after foo += 1?

I certainly hope we still have mutable values by design and
implementation. Clear separation of names, containers and values is what
makes me like how Perl works. Being able to operate on the value without
doing anything to the container is a source of great efficiency in a
language in which things like string substitution are used almost every
other line.

> >If =:= tests variable sameness, then it should do that literally in
> >order to both be useful and look like :=. For reference equality you can
> >still use \FOO == \BAR (I assume).
> In my view of the world =:= checks for identity of values.

Is your view of the world like Python or like Perl 5?

Values have no identity in Perl 5. Containers (variables, named or
anonymous) do. That also means that even though $foo = 5 and $bar = 5,
\$foo != \$bar. In Python, with foo = 5 and bar = 5, that means id(foo)
== id(bar), but I don't like that at all.

Juerd

unread,
Apr 2, 2005, 4:10:10 AM4/2/05
to James Mastros, perl6-l...@perl.org
James Mastros skribis 2005-04-01 22:48 (+0200):

> $x = 42;
> $a = \$x but false;
> $b = \$y but blue;
> $a =:= $b ???

Even without the buts, that is:

$x = 42;
$a = \$x;
$b = \$x;

I strongly believe that $a =:= $b must be false. Assignment copies! $a
=:= $b should be true only if $a and $b are the same variable
themselves, as can be accomplished by a simple $a = $b or by passing $b
as an argument to a closure somehow, like in given $a -> $b { ... }.

If =:= has nothing to do with :=, it shouldn't look like it that much.
If it tests reference equality, possibly referencing non-references, it
should be spelled =\= instead, although I really question the practical
use of such operator.

Larry Wall

unread,
Apr 2, 2005, 12:33:54 PM4/2/05
to perl6-l...@perl.org
On Sat, Apr 02, 2005 at 11:06:01AM +0200, Juerd wrote:
: Is your view of the world like Python or like Perl 5?

Them's fightin' words. :-)

: Values have no identity in Perl 5.

That's slightly not true, insofar as Perl 5 distinguishes hash keys
by value (albeit filtered through stringification).

: Containers (variables, named or


: anonymous) do. That also means that even though $foo = 5 and $bar = 5,
: \$foo != \$bar. In Python, with foo = 5 and bar = 5, that means id(foo)
: == id(bar), but I don't like that at all.

On the other hand, it would be nice to have an operator that tells
you if two things would be considered the same hash thing if handed
to a hash of shape(Any). That's how I think of =:=. If that's more
like Python and less like Perl 5, I don't care. I'm trying to make
Perl 6 like Perl 6, not like anything else.

Objects are by default unique, but any particular class of objects
(including value types) is allowed to define its own idea of
uniqueness. Unique identity is precisely what we're looking for
in a hash key, whether we stringify it or not.

Larry

Thomas Sandlaß

unread,
Apr 4, 2005, 12:50:11 PM4/4/05
to perl6-l...@perl.org
Juerd wrote:
>>my $four := three;
>
> Assuming you meant $three instead of three.

Indeed. Sorry.


>>my $five = 5;
>>$four = 4; # $one == 4 now?
>
> No, $four (and thus $three, which it is bound to) is now 4. $three is a
> reference, which is a value, which is now *replaced* with the new value.

OK. Then you need to define the behaviour of referential values.
In particular what does &infix<=><Scalar of Ref of Ref of Int,Int> do?
I get from your remarks that you intend to treat it exactly like
'Scalar of Ref of Any' without dispatching to 'Ref of Int'. That means
creating a new value 'Ref of Int' from the rhs, binding the Scalar and the
Ref to it or some such.


> Is that so? Are we going to walk the path of inefficiency where $foo++
> is really actually literally just $foo = $foo + 1, throwing away the old
> variable, assigning a new one?

Heck, no! The $foo++ means &postfix:<++>( $foo ) the second is
&infix:<=><Any>( &infix:<+><Any,Int>( $foo, 1 ) ) either dispatched
at runtime or optimized at compile if possible. How efficient that
is compared to each other I don't know.


> And will Perl 6 reference values rather than their containers, that is:
> will \$foo differ when $foo gets a new value, just as in Python id(foo)
> changes after foo += 1?

Depends on the definition of the semantics of 'Ref of Scalar of Any'
versus 'Scalar of Any' versus 'Ref of Any' versus 'Scalar of Ref of Any'.
My question was actually about the language level definition of *chains
of references*!

1) Is the referene creation done with \, := and implicit in scalar context?
Or do \ and := differ? And what's different with ::=?
2) Is derefencing still done with $ chains where you have to know how far
to go? Is $$$$$$$foo still valid Perl 6 syntax?
3) How are Refs dispatched in comparison to Scalars, Arrays and Hashes?

Here is another attempt to pose my question with -> depicting an indirection.
After the declarations with my we have two chains:

$four -> $three -> $two -> $one -> 1
$five -> 5

Now what does $four = 4 mean? Dump the chain from $three downwards
and end up with

$four -> 4
$five -> 5

or go all the way down and just rebind $one and dumping the value 1

$four -> $three -> $two -> $one -> 4
$five -> 5

The next question was about how far down $$four goes and how rebinding
at that level works. If it goes one down and rebinds there we get:

$two -> $one -> 4
$four -> $three -> $five -> 5

BTW, Parrot could collapse chains of reference in a GC run
or as side effect of identity checks.


> I certainly hope we still have mutable values by design and

In my head "mutable value" and "constant variable" sound funny.


> Is your view of the world like Python or like Perl 5?

More like an any-junction of all languages supported by Parrot :)


> Values have no identity in Perl 5. Containers (variables, named or
> anonymous) do. That also means that even though $foo = 5 and $bar = 5,
> \$foo != \$bar. In Python, with foo = 5 and bar = 5, that means id(foo)
> == id(bar), but I don't like that at all.

Once again \$foo != \$bar just means a dispatch to &infix:«!=»<Ref,Ref>
which might need to be different for PerlRef and PythonRef if the latter
exists at all. The difficult thing for the Parrot folks is the mixed case!
The homogenous cases are up to the languages. But for the mixed case some
meta language level has to define semantics or the languages have to adapt
from the inside out by explicit foreign knowlegde.


Regards,
--
TSa (Thomas Sandlaß)

Juerd

unread,
Apr 4, 2005, 2:21:20 PM4/4/05
to Thomas Sandlaß, perl6-l...@perl.org
Thomas Sandlaß skribis 2005-04-04 18:50 (+0200):

> In particular what does &infix<=><Scalar of Ref of Ref of Int,Int> do?

Depends. What does it mean? :)

Specifically, what is &infix, what is <=>?

> 'Scalar of Ref of Any' without dispatching to 'Ref of Int'. That means

References and aliasing should have nothing to do with types, except for
checking. That is, even my Scalar $foo := my Int $bar should let $foo
=:= $bar and \$foo == \$bar.

> 1) Is the referene creation done with \, := and implicit in scalar context?

A reference points to a variable the same way a name does. Only the
level at which these exists is different, but that brings along a lot of
different thinking.

A name is visible in the source, a reference is an unmentioned value.

The difference between

my $foo = \$bar; #1

and

my $foo := $bar; #2

is that in #1, $$foo =:= $bar, and in #2, $foo =:= $bar (assuming =:=
does NOT autoderefence, and this again makes clear why that'd be a bad
idea). In English: in #1, the value of $foo is a reference that points
to the container that is known as $bar, and in #2, $foo itself is the
same thing as $bar, with both names pointing to the same container.

> Or do \ and := differ? And what's different with ::=?

They differ.

::= is like :=, but at compile time rather than runtime. I'm not sure
what the benefit of this is, but I imagine it speeds things up and saves
a few BEGIN blocks.

> 2) Is derefencing still done with $ chains where you have to know how far
> to go? Is $$$$$$$foo still valid Perl 6 syntax?

I should hope so!

> Here is another attempt to pose my question with -> depicting an
> indirection. After the declarations with my we have two chains:

I don't understand how your chains relate to the code you posted before.

> >I certainly hope we still have mutable values by design and
> In my head "mutable value" and "constant variable" sound funny.

Well, in Perl, values and variables have always been exactly the same
thing. That is, $foo is as much a scalar as the thing that is created
for the number 3. The big difference is that "variables" are mutable and
"literal values" are read-only. I would like to avoid the word
"constant" because that, in Perl 5 jargon, is an inlineable subroutine.

We're used to calling scalars that have a name or are explicitly
referenced "variables", and scalars that just are there, like what
subroutines return or what is in source code literally, "values". But in
fact, the value is somewhere INSIDE the scalar.

$foo = $bar; # copies $bar's value to $foo's value
$foo = \$bar; # creates a reference to $bar's scalar and stores it
# in $foo's value
$foo = 3; # copies 3's value (the integer three) to $foo's
# value
$foo = \3; # creates a reference to 3's scalar and stores it in
# $foo's value

After $foo = \3, $$foo is immutable because 3 is immutable. However,
after $bar = 3, $bar is mutable because not the variable 3, but only its
value was copied. The read-only flag, which is part of the scalar, is
left out of the copying process.

(Note that for simplicity's sake, I'm talking of value as a single
thing, while in Perl (at least Perl 5), a scalar can have several values
all at once, the best known being dualvars: string and number. A
scalar's value can be string, number, reference, glob or undef. (Should
you really care, then note that undef itself is a special scalar, which,
would you take away its readonly flag, would just as easily hold the
string "forty-two".))

> Once again \$foo != \$bar just means a dispatch to &infix:«!=»<Ref,Ref>
> which might need to be different for PerlRef and PythonRef if the latter
> exists at all.

I hope variables have the semantics of the language they're used in, and
values are copied to another interpreter's variables as needed.
Otherwise in order to use a library written in, for example, Python, you
would have to know how variables work in that language. Bluntly put,
that'd suck.

Thomas Sandlaß

unread,
Apr 5, 2005, 12:38:43 PM4/5/05
to perl6-l...@perl.org
Juerd wrote:
> Thomas Sandlaß skribis 2005-04-04 18:50 (+0200):
>
>>In particular what does &infix<=><Scalar of Ref of Ref of Int,Int> do?
>
>
> Depends. What does it mean? :)
>
> Specifically, what is &infix, what is <=>?

Ups, a missing : warps this to a completly different meaning!
Comparing a coderef &infix with the comparison operator <=>
to the word list 'Scalar of Ref of Ref of Int,Int'.

I tried to ask what &infix:<=><Scalar of Ref of Ref of Int,Int>
does. This is the assignment infix operator = for 'Scalar of Ref
of Ref of Int' on the lhs and Int on the rhs.

BTW, does the parser have a change to detect this typo?

About the rest of the mail I'll try to rant tomorrow.
--
TSa (Thomas Sandlaß)

Larry Wall

unread,
Apr 5, 2005, 4:15:44 PM4/5/05
to perl6-l...@perl.org
On Tue, Apr 05, 2005 at 06:38:43PM +0200, Thomas Sandlaß wrote:
: Ups, a missing : warps this to a completly different meaning!

: Comparing a coderef &infix with the comparison operator <=>
: to the word list 'Scalar of Ref of Ref of Int,Int'.
:
: I tried to ask what &infix:<=><Scalar of Ref of Ref of Int,Int>
: does. This is the assignment infix operator = for 'Scalar of Ref
: of Ref of Int' on the lhs and Int on the rhs.
:
: BTW, does the parser have a change to detect this typo?

Yes. It should complain that = is not a valid type signature.
Any &foo (or &foo:<...>) followed by <...> should be parsed as a single
term selecting the function that MMD would dispatch to given that
type signature.

Larry

Thomas Sandlaß

unread,
Apr 6, 2005, 10:31:08 AM4/6/05
to perl6-l...@perl.org
Larry Wall wrote:
> Yes. It should complain that = is not a valid type signature.
> Any &foo (or &foo:<...>) followed by <...> should be parsed as a single
> term selecting the function that MMD would dispatch to given that
> type signature.

And I guess it's not allowed to have interspersed whitespace unless
one uses the dot forms? And my interpretation as operator <=> needs
the whitespace OTOH.

&infix <=> <some words> # my interpretation of the typo

&foo .<signature> # OK?

&infix: .<operator> .<signature> # OK?

&infix:<operator> .<signature> # or at least this?

Whitespace before the : is also not allowed, or is it?

&infix : .<operator> .<signature>

The dot forms would allow alignment when dumping a complete multi
with every sig on a seperate line. Or for all infix operators, etc.


Is &foo<$bar> a symbolic access or a syntax error? How about

&foo<$bar> = sub ... # ... here means appropriate def, not the yada op

or just with

&foo<$bar> := sub ...?

Larry Wall

unread,
Apr 6, 2005, 12:38:39 PM4/6/05
to perl6-l...@perl.org
On Wed, Apr 06, 2005 at 10:07:33AM -0600, Luke Palmer wrote:
: Thomas Sandlaß writes:

: > Larry Wall wrote:
: > >Yes. It should complain that = is not a valid type signature.
: > >Any &foo (or &foo:<...>) followed by <...> should be parsed as a single
: > >term selecting the function that MMD would dispatch to given that
: > >type signature.
: >
: > And I guess it's not allowed to have interspersed whitespace unless
: > one uses the dot forms? And my interpretation as operator <=> needs
: > the whitespace OTOH.
: >
: > &infix <=> <some words> # my interpretation of the typo
: >
: > &foo .<signature> # OK?
:
: I'm beginning to think that angle brackets are too overloaded here. The
: qw angles are really growing on me, and now whenever I see angles I see
: a quoting construct. Putting something that's not quoted inside them
: seems like it will be visually confusing (and just thing what vim will
: have to do to tell the difference).

Yes, same here. But it's not an expression either. It's a signature,
and the only other delimiter we have prior art for is (Str $s, Int $i)
in sub declarations. But we can't use bare parens for obvious reasons
that were not obvious enough to keep me from falling into the trap
in at least one Apocalypse. :-)

: We could make it one, so that it's:
:
: &infix:<+>.<Complex Complex>
:
: Instead of with commas, but then you can't attach anything special to
: the types, so I think it's best if we just ditch <> altogether for this
: purpose.
:
: But then what replaces it? The first thing that came to me was just
: to use a method:
:
: &infix:<+>.variant(Complex, Complex);
:
: The method approach has some other advantages, like the ability to add
: another method:
:
: my $code = &infix:<+>.dispatch($a, $b); # what code would we call
: # with $a and $b?
:
: Or we could use square brackets, since square bracketing types just
: selects a type, but doesn't do anything to it. But especially because
: this only applies to multimethods, I like the method approach the best.

But a method *evaluates* its arguments, which you generally don't want
in this case. Sometimes you do, so it's fine to have a method behind
whatever syntax we choose, but it can't very well be the default
without some kind of sig quoting. I think it's time to break out
the colon again and use something like:

&infix:<+>:(Complex, Complex);

or

&foo:(Str,Int)

for ordinary functions. If it gets really popular people might
even start writing:

sub foo :(Str,Int) {...}

Larry

Luke Palmer

unread,
Apr 6, 2005, 12:07:33 PM4/6/05
to Thomas Sandlaß, perl6-l...@perl.org
Thomas Sandlaß writes:
> Larry Wall wrote:
> >Yes. It should complain that = is not a valid type signature.
> >Any &foo (or &foo:<...>) followed by <...> should be parsed as a single
> >term selecting the function that MMD would dispatch to given that
> >type signature.
>
> And I guess it's not allowed to have interspersed whitespace unless
> one uses the dot forms? And my interpretation as operator <=> needs
> the whitespace OTOH.
>
> &infix <=> <some words> # my interpretation of the typo
>
> &foo .<signature> # OK?

I'm beginning to think that angle brackets are too overloaded here. The


qw angles are really growing on me, and now whenever I see angles I see
a quoting construct. Putting something that's not quoted inside them
seems like it will be visually confusing (and just thing what vim will
have to do to tell the difference).

We could make it one, so that it's:

&infix:<+>.<Complex Complex>

Instead of with commas, but then you can't attach anything special to
the types, so I think it's best if we just ditch <> altogether for this
purpose.

But then what replaces it? The first thing that came to me was just
to use a method:

&infix:<+>.variant(Complex, Complex);

The method approach has some other advantages, like the ability to add
another method:

my $code = &infix:<+>.dispatch($a, $b); # what code would we call
# with $a and $b?

Or we could use square brackets, since square bracketing types just
selects a type, but doesn't do anything to it. But especially because
this only applies to multimethods, I like the method approach the best.

Luke

Larry Wall

unread,
Apr 6, 2005, 12:25:23 PM4/6/05
to perl6-l...@perl.org
On Wed, Apr 06, 2005 at 04:31:08PM +0200, Thomas Sandlaß wrote:
: Larry Wall wrote:
: >Yes. It should complain that = is not a valid type signature.
: >Any &foo (or &foo:<...>) followed by <...> should be parsed as a single
: >term selecting the function that MMD would dispatch to given that
: >type signature.
:
: And I guess it's not allowed to have interspersed whitespace unless
: one uses the dot forms? And my interpretation as operator <=> needs
: the whitespace OTOH.
:
: &infix <=> <some words> # my interpretation of the typo

Yes.

: &foo .<signature> # OK?

Yes, unless we take Luke's suggestion.

: &infix: .<operator> .<signature> # OK?

Yes, UWTLS.

: &infix:<operator> .<signature> # or at least this?

Yes, UWTLS.

: Whitespace before the : is also not allowed, or is it?


:
: &infix : .<operator> .<signature>

Not allowed, EIWTLS. :-)

: The dot forms would allow alignment when dumping a complete multi


: with every sig on a seperate line. Or for all infix operators, etc.

Indeed, EIWTLS.

: Is &foo<$bar> a symbolic access or a syntax error? How about

Neither, it would be a siglet that declares a scalar variable where
a simple Scalar would do, I think.

: &foo<$bar> = sub ... # ... here means appropriate def, not the yada op


:
: or just with
:
: &foo<$bar> := sub ...?

I think we should just say "no" at that point.

Larry

Thomas Sandlaß

unread,
Apr 6, 2005, 1:22:48 PM4/6/05
to Larry Wall, perl6-l...@perl.org
HaloO Larry,

you wrote:
> for ordinary functions. If it gets really popular people might
> even start writing:
>
> sub foo :(Str,Int) {...}

I like it, but that could mean it will not become popular :))
And this is also nice:

sub foo :(Str,Int) of Str {...}

Is a closure return type indicated with this siglet syntax, too?

sub foo :(Str,Int) of :(Any) {...}

Will there be an announcement if this syntax becomes official?
BTW, would it be a good idea that you make such decisions known on p6a?
--
TSa (Thomas Sandlaß)

Larry Wall

unread,
Apr 6, 2005, 2:30:35 PM4/6/05
to perl6-l...@perl.org
On Wed, Apr 06, 2005 at 07:22:48PM +0200, Thomas Sandlaß wrote:
: HaloO Larry,

:
: you wrote:
: >for ordinary functions. If it gets really popular people might
: >even start writing:
: >
: > sub foo :(Str,Int) {...}
:
: I like it, but that could mean it will not become popular :))
: And this is also nice:
:
: sub foo :(Str,Int) of Str {...}
:
: Is a closure return type indicated with this siglet syntax, too?
:
: sub foo :(Str,Int) of :(Any) {...}

You would need :() only to group multiple siglets into a single type.
So an Any can stand on its own.

: Will there be an announcement if this syntax becomes official?

Paint it official unless someone can come up with a good counterargument.

: BTW, would it be a good idea that you make such decisions known on p6a?

p6a is for political announcements, not technical. :-)

Things actually become "official" when they get put into synopses.

Unfortunately, I don't have much time to edit synopses much these days.
No billionaires have written me into their will lately (or if they
have, they haven't pegged out yet), so for now I have to earn my
own way out of the financial hole I'm in, and that takes a lot of
time away from Perl. I'm just barely keeping up with the email,
and I'm not getting anything done on the translator. Sorry.

If you want to help, earn a billion dollars and write me into your
will. And then peg out. Nothing personal. :-)

Larry

John Macdonald

unread,
Apr 6, 2005, 3:48:03 PM4/6/05
to perl6-l...@perl.org
On Wed, Apr 06, 2005 at 11:30:35AM -0700, Larry Wall wrote:
> If you want to help, earn a billion dollars and write me into your
> will. And then peg out. Nothing personal. :-)
>
> Larry

Darn. So far, I'm, 0 for 3 on that plan.

However, I promise that item two will follow very shortly in
time from item one. No promises about the delay between items
two and three, though; nor any assurance of my ever achieving
item one (it's failure, in fact, is virtually assured).

--

Larry Wall

unread,
Apr 6, 2005, 2:37:19 PM4/6/05
to perl6-l...@perl.org
On Wed, Apr 06, 2005 at 08:24:23PM +0200, Juerd wrote:
: Larry Wall skribis 2005-04-06 11:10 (-0700):
: > $$ref follow the ref list to the actual object.
:
: my $foo;
: my $bar = \$foo;
: my $quux = \$bar;
: my $xyzzy = \$quux;
:
: How then, with only $xyzzy, do you get $bar? $$xyzzy would follow until
: $foo. I don't like this at all.

You can't get at $bar anyway. You can only get at its thingy. Otherwise
you're talking symbolic refs.

: > $ref.foo() is one of those contexts that forces a deref. The only way
: > to call methods on the Ref itself is through var($ref), or whatever
: > it's called today.
:
: This is weird.

Chains of scalar refs are weird. At least, they're weird to anyone but
a C programmer or a Perl 5 programmer. We're trying to re-Huffmanize
the weirdness of Perl 6.

Larry

Larry Wall

unread,
Apr 6, 2005, 2:10:40 PM4/6/05
to perl6-l...@perl.org
On Mon, Apr 04, 2005 at 06:50:11PM +0200, Thomas Sandlaß wrote:
: Juerd wrote:
: >And will Perl 6 reference values rather than their containers, that is:

: >will \$foo differ when $foo gets a new value, just as in Python id(foo)
: >changes after foo += 1?
:
: Depends on the definition of the semantics of 'Ref of Scalar of Any'
: versus 'Scalar of Any' versus 'Ref of Any' versus 'Scalar of Ref of Any'.
: My question was actually about the language level definition of *chains
: of references*!
:
: 1) Is the referene creation done with \, := and implicit in scalar context?
: Or do \ and := differ? And what's different with ::=?

Taking the questions in reverse order, ::= differs from := only in
forcing immediate evaluation and binding at compile time. I don't
think \ and := differ very much--in fact, at one time aliasing was
going to be done with:

\$foo = \$bar;

But as in many other areas, we've chosen to differentiate operators
rather than overload existing ones. That's why we have =:= as well.

I don't quite understand your first question. The left side of :=
implies reference context, but the right side only implies scalar context,
so @foo and %bar automatically assume \, while $foo does not, but is
assumed to already contain a reference. At least that's how I'm thinking
of it this week.

: 2) Is derefencing still done with $ chains where you have to know how far
: to go?

I think the common case with chains of references is that you either want
the beginning of the chain or the end. So I think we'll probably go
with ref coalescing behavior.

: Is $$$$$$$foo still valid Perl 6 syntax?

Sure, it's just the extra $'s are no-ops. :-)

Basically, we have

$$ref follow the ref list to the actual object.

$ref ignore the fact that this is a ref unless context forces it.

Ordinary scalar and list context never force a deref. Numeric and
string contexts do force a deref, unlike in Perl 5. Also, boolean
context! That's why we say that refs are no longer guaranteed to be
true in Perl 6.

: 3) How are Refs dispatched in comparison to Scalars, Arrays and Hashes?

$ref.foo() is one of those contexts that forces a deref. The only way
to call methods on the Ref itself is through var($ref), or whatever
it's called today.

: Here is another attempt to pose my question with -> depicting an

: indirection.
: After the declarations with my we have two chains:
:
: $four -> $three -> $two -> $one -> 1
: $five -> 5
:
: Now what does $four = 4 mean? Dump the chain from $three downwards
: and end up with
:
: $four -> 4
: $five -> 5

Yes.

: or go all the way down and just rebind $one and dumping the value 1


:
: $four -> $three -> $two -> $one -> 4
: $five -> 5

No.

: The next question was about how far down $$four goes and how rebinding


: at that level works. If it goes one down and rebinds there we get:
:
: $two -> $one -> 4
: $four -> $three -> $five -> 5

$$four goes all the way down to something that is not a ref.

: BTW, Parrot could collapse chains of reference in a GC run


: or as side effect of identity checks.

That would be convenient.

: >I certainly hope we still have mutable values by design and


:
: In my head "mutable value" and "constant variable" sound funny.
:
:
: >Is your view of the world like Python or like Perl 5?
:
: More like an any-junction of all languages supported by Parrot :)

My view is that the current lexical scope is allowed to impose any
view on reality that it chooses. If you want a lexical scope that
always forces != to coerce both sides with +, that's fine. It's just
probably not the default, since we'll rely on MMD to choose standard
Perl semantics where appropriate.

: >Values have no identity in Perl 5. Containers (variables, named or


: >anonymous) do. That also means that even though $foo = 5 and $bar = 5,
: >\$foo != \$bar. In Python, with foo = 5 and bar = 5, that means id(foo)
: >== id(bar), but I don't like that at all.
:
: Once again \$foo != \$bar just means a dispatch to &infix:«!=»<Ref,Ref>
: which might need to be different for PerlRef and PythonRef if the latter
: exists at all. The difficult thing for the Parrot folks is the mixed case!
: The homogenous cases are up to the languages. But for the mixed case some
: meta language level has to define semantics or the languages have to adapt
: from the inside out by explicit foreign knowlegde.

Doubtless there is room to do both, as long as the language gets the
override over global policy. I know Perl probably wants to break
ties by coercing other language's scalars with implicit +, ~, and ?
where the naive Perl programmer would expect it. $a + $b is not going
to do string concatenation in Perl unless *both* strings are foreign,
and then it's probably up to the global policy. And a pretty good
argument can be made for *never* doing string concatenation with +
in Perl. If the global policy is specific enough about semantics, then
it will distinguish concatenation from addition independently of any
language's particular confusions of the operator names, so there ought
to be some circumlocutional way of saying what you really mean that
gets translated to the appropriate method name in the target language
without you having to know what the target language is. If you really
want to dispatch through another language's dispatcher, there's probably
a way to do that explicitly.

Larry

Juerd

unread,
Apr 6, 2005, 2:24:23 PM4/6/05
to perl6-l...@perl.org
Larry Wall skribis 2005-04-06 11:10 (-0700):
> $$ref follow the ref list to the actual object.

my $foo;
my $bar = \$foo;


my $quux = \$bar;
my $xyzzy = \$quux;

How then, with only $xyzzy, do you get $bar? $$xyzzy would follow until
$foo. I don't like this at all.

> $ref.foo() is one of those contexts that forces a deref. The only way


> to call methods on the Ref itself is through var($ref), or whatever
> it's called today.

This is weird.

Austin Hastings

unread,
Apr 6, 2005, 3:36:39 PM4/6/05
to Larry Wall, perl6-l...@perl.org
Larry Wall wrote:

How do you deref 'n' levels in such a chain?

My current project is a n-way merge of some very large {i.e., O(10**8)
records} XML datasets. One way I'm getting performance is by using
scalar reference chains to avoid copies. I am also recasting the type of
some of the objects used, so I need to be able to reach in 'one' level,
as well as 'all' the levels. Currently, I have to know the length of the
chain, but it's a constant at any layer so that's not a problem.

So if $$ref gives the 'all the way down' behavior, how do I get "just
one layer down" dereferencing?

=Austin

Patrick R. Michaud

unread,
Apr 6, 2005, 3:43:55 PM4/6/05