Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Comparing Object Identity (was: Re: Stringification of refere nces (Decision, Please?)) [x-adr][x-bayes]

0 views
Skip to first unread message

Garrett Goebel

unread,
Dec 12, 2002, 1:40:52 PM12/12/02
to Larry Wall, Perl 6 Language, sira...@mindspring.com
John Siracusa wrote:
> On 12/12/02 12:55 PM, Larry Wall wrote:
> > As for namespace pollution and classes that use .id in Perl 5, I
> > don't think it's going to be a big problem. Built-in identifiers
> > do not have a required prefix, but they have an optional prefix,
> > which is C<*>. I think we can probably parse
> >
> > $a.*id == $b.*id
> >
> > if you really need to get to Object.id().
>
> That'll only work out if everyone always writes it as "*id".
> If not, my Perl 6 objects that override "id()" won't work correctly
> with any other classes or functions that simply call "id" and
> expect it to really be "*id"

yes...

So we'll _have_ to write $obj.*id when we mean $obj->UNIVERSAL::id;

I'm not sure I understand what Larry means by "most-global"... Do you mean
outer-most scope, root-of-method-inheritence, or both?

And what of the case we someone does want to explicitly override a "builtin"
method like UNIVERSAL::can? What is the Perl6 equivalent to:

*UNIVERSAL::can = sub { print qq{hello\n} };
sub foo {};
print main->can('foo')";

And what will:

main.*can('foo')

result in?


Larry Wall wrote:
>
> I'd almost be tempted to argue that if push comes to shove, it's
> the list splat star that gets shoved.

Don't you suspect the list splat will be more common than most-global?

Larry Wall

unread,
Dec 12, 2002, 4:01:09 PM12/12/02
to Perl 6 Language
On Thu, Dec 12, 2002 at 12:40:52PM -0600, Garrett Goebel wrote:
: John Siracusa wrote:
: > On 12/12/02 12:55 PM, Larry Wall wrote:
: > > As for namespace pollution and classes that use .id in Perl 5, I
: > > don't think it's going to be a big problem. Built-in identifiers
: > > do not have a required prefix, but they have an optional prefix,
: > > which is C<*>. I think we can probably parse
: > >
: > > $a.*id == $b.*id
: > >
: > > if you really need to get to Object.id().
: >
: > That'll only work out if everyone always writes it as "*id".
: > If not, my Perl 6 objects that override "id()" won't work correctly
: > with any other classes or functions that simply call "id" and
: > expect it to really be "*id"
:
: yes...
:
: So we'll _have_ to write $obj.*id when we mean $obj->UNIVERSAL::id;

If you wish to be precise, yes. But $a.id eq $b.id should work for most any
class that uses the the term "id" in the typical fashion.

: I'm not sure I understand what Larry means by "most-global"... Do you mean


: outer-most scope, root-of-method-inheritence, or both?

It's context dependent, just as the meaning of an identifier is context dependent.
In this case, it means root-of-method-inheritance, that is, Object. (That is
tne new name of UNIVERSAL.) So $a.*id is short for $a.Object::id. But $*foo
is short for $Global::foo or some such.

: And what of the case we someone does want to explicitly override a "builtin"


: method like UNIVERSAL::can? What is the Perl6 equivalent to:
:
: *UNIVERSAL::can = sub { print qq{hello\n} };
: sub foo {};
: print main->can('foo')";

Any of:

method Object::can ($meth) { print qq[hello\n] }

or

&*can := method ($meth) { print qq[hello\n] };

or

&Object::can ::= sub ($object, $method) { print qq[hello\n] };

Hmm. Those don't really stand out enough. Maybe we should go with
OBJECT:: and GLOBAL:: just for a little more visual punch.

: And what will:


:
: main.*can('foo')
:
: result in?

These days it's "Main", not "main". And it's a module, not a class,
so probably it fails, unless someone can think of something useful
for it to mean.

: Larry Wall wrote:
: >
: > I'd almost be tempted to argue that if push comes to shove, it's
: > the list splat star that gets shoved.
:
: Don't you suspect the list splat will be more common than most-global?

That's why I said "almost".

Larry

John Siracusa

unread,
Dec 12, 2002, 4:26:28 PM12/12/02
to Perl 6 Language
On 12/12/02 4:01 PM, Larry Wall wrote:
> On Thu, Dec 12, 2002 at 12:40:52PM -0600, Garrett Goebel wrote:
> : So we'll _have_ to write $obj.*id when we mean $obj->UNIVERSAL::id;
>
> If you wish to be precise, yes. But $a.id eq $b.id should work for most any
> class that uses the the term "id" in the typical fashion.

I still feel like we're talking past each other here. What I was saying is
that, regardless of any admonitions to the contrary, I think people will
still write this:

$a.id == $b.id

and expect it to compare memory addresses. That is not the "typical
fashion" for an object method named "id" to work, IMO.

The need to compare memory addresses is so infrequent that warrants a much
less common and/or longer method name than "id".

-John

Brent Dax

unread,
Dec 12, 2002, 4:50:37 PM12/12/02
to Larry Wall, Perl 6 Language
Larry Wall:
# Hmm. Those don't really stand out enough. Maybe we should go with
# OBJECT:: and GLOBAL:: just for a little more visual punch.

How about CORE:: instead of GLOBAL::? This helps stick with tradition
and minimize the number of reserved packages.

# : And what will:
# :
# : main.*can('foo')
# :
# : result in?
#
# These days it's "Main", not "main". And it's a module, not a
# class, so probably it fails, unless someone can think of
# something useful for it to mean.

I'd hope that Perl would allow me to do something like that to see if
Main::foo exists...

--Brent Dax <bren...@cpan.org>
@roles=map {"Parrot $_"} qw(embedding regexen Configure)

"If you want to propagate an outrageously evil idea, your conclusion
must be brazenly clear, but your proof unintelligible."
--Ayn Rand, explaining how today's philosophies came to be

Dave Whipp

unread,
Dec 12, 2002, 4:41:27 PM12/12/02
to perl6-l...@perl.org
"John Siracusa" <sira...@mindspring.com> wrote:
> memory addresses is so infrequent that warrants a much
> less common and/or longer method name than "id".

Another reason for not making these synonymous:

Is the address of an object constant? Or might it be
remapped during the life of an object. For example,
arrays might move when they grow too big; distributed
objects may move as they transfer onto different hosts;
a persistent object might have a new address when
retrieved from backing-store).

I might want to write code such as:

$remembered_id = $obj.id;

... [ time passes ] ...

if $an_object.id == $remembered_id { ... }

If memory addresses can change over time, then we
need a more fundamental concept to act as the ID!


Dave.


John Siracusa

unread,
Dec 12, 2002, 4:46:17 PM12/12/02
to Perl 6 Language
On 12/12/02 4:41 PM, Dave Whipp wrote:
> "John Siracusa" <sira...@mindspring.com> wrote:
>> memory addresses is so infrequent that warrants a much
>> less common and/or longer method name than "id".
>
> Another reason for not making these synonymous:
>
> [...]

> If memory addresses can change over time, then we
> need a more fundamental concept to act as the ID!

Heh, it seems like you're supporting my position, but you're really not :)

Whatever the "this is the same object" value actually is, I don't think it
deserves to live under the method name "id".

-John

Brent Dax

unread,
Dec 12, 2002, 5:03:33 PM12/12/02
to Dave Whipp, perl6-l...@perl.org
Dave Whipp:
# Is the address of an object constant? Or might it be
# remapped during the life of an object. For example,
# arrays might move when they grow too big; distributed
# objects may move as they transfer onto different hosts;
# a persistent object might have a new address when
# retrieved from backing-store).

Under all systems I can think of, the memory address of an object's
header is constant. The data may move, but the header stays constant.
This is to minimize the insanity of pointer chasing in C.

Dave Whipp

unread,
Dec 12, 2002, 5:08:07 PM12/12/02
to perl6-l...@perl.org
"Brent Dax" <bren...@cpan.org> wrote in message
news:00f901c2a22a$50417b30$6501a8c0@deepblue...

> Under all systems I can think of, the memory address of an object's
> header is constant. The data may move, but the header stays constant.
> This is to minimize the insanity of pointer chasing in C.

The address may be constant for the life of the process: but some
objects persist a bit longer. These cases can probably be covered
by a C<.guid> method. Is this method a member of C<Object>,
or only of C<PersistantObject>?

Dave.


Austin Hastings

unread,
Dec 12, 2002, 5:11:32 PM12/12/02
to Brent Dax, Dave Whipp, perl6-l...@perl.org
--- Brent Dax <bren...@cpan.org> wrote:
> Dave Whipp:
> # Is the address of an object constant? Or might it be
> # remapped during the life of an object. For example,
> # arrays might move when they grow too big; distributed
> # objects may move as they transfer onto different hosts;
> # a persistent object might have a new address when
> # retrieved from backing-store).
>
> Under all systems I can think of, the memory address of an object's
> header is constant. The data may move, but the header stays
> constant.

The '.id as memory address' scheme fails for any attempt to use
id persistence (NOT object persistence, but ID persistence).

That is, '.id-as-addr' is only useful for "compare these two
currently-in-memory objects", as opposed to "have I EVER seen this
object", or "have I EVER-this-session seen this object", since
recording the .id of the object in a cache doesn't preclude the object
being GC'd when all other references go away.

So the value of the current .id isn't much of an ID.

Which does not remove the value of being able to quickly and easily say
"is this current-runtime-object the same as that one?" It just suggests
that the name .id isn't very well chosen.

Other questions, like "how do I generate a persistence-unique id?",
also beg for .id as a non-reserved name (unless we propose to add
macaddr and threadsafe timestamp as components of the standard .id --
not always a bad thing, but not a single opcode anymore...)

=Austin

Michael Lazzaro

unread,
Dec 12, 2002, 5:17:16 PM12/12/02
to Dave Whipp, perl6-l...@perl.org

On Thursday, December 12, 2002, at 01:41 PM, Dave Whipp wrote:
> I might want to write code such as:
>
> $remembered_id = $obj.id;
>
> ... [ time passes ] ...
>
> if $an_object.id == $remembered_id { ... }

I think if you do this, you're probably in a world of hurt. We'd have
to assure that no object id's are *ever* reused -- so mem addresses are
out, since the same address may be used for different things at
different points in time. It would literally have to be a unique
serialnum attached to every single object in the process' lifespan.
And if it were to work correctly for persistent objs, it'd have to be
unique even among all perl invocations. Eeew!

Whatever's behind 'id' is probably a meaningless blob with only one
use: to determine if two vars, $obj1 and $obj2, are in fact bound to
the same thing. You can't (meaningfully) store them for use elsewhere.

Anything else seems to imply icky overhead, yes?

MikeL

Dan Sugalski

unread,
Dec 12, 2002, 5:24:22 PM12/12/02
to Michael Lazzaro, Dave Whipp, perl6-l...@perl.org
At 2:17 PM -0800 12/12/02, Michael Lazzaro wrote:
>On Thursday, December 12, 2002, at 01:41 PM, Dave Whipp wrote:
>>I might want to write code such as:
>>
>> $remembered_id = $obj.id;
>>
>> ... [ time passes ] ...
>>
>> if $an_object.id == $remembered_id { ... }
>
>I think if you do this, you're probably in a world of hurt. We'd
>have to assure that no object id's are *ever* reused -- so mem
>addresses are out, since the same address may be used for different
>things at different points in time.

There'll definitely be memory address reuse. If .id returns the
current object's memory address, it shouldn't be cached any place, as
otherwise you'll find things going bang with some regularity.
--
Dan

--------------------------------------"it's like this"-------------------
Dan Sugalski even samurai
d...@sidhe.org have teddy bears and even
teddy bears get drunk

Dave Whipp

unread,
Dec 12, 2002, 5:42:49 PM12/12/02
to perl6-l...@perl.org
"Dan Sugalski" <d...@sidhe.org> wrote in message
news:a05200f00ba1ebb73c6d2@[63.120.19.221]...

> There'll definitely be memory address reuse. If .id returns the
> current object's memory address, it shouldn't be cached any place, as
> otherwise you'll find things going bang with some regularity.

In a multi-threaded environment, even a simple

$a.id == $b.id

may have significant time between the two lookups. If we are
going to rely on addresses for id comparison, then we need to
mandate that the address is constant for the life of the object.
Brent indicated that he could think of no reason for the "header
address" to change: but that isn't strong enough. We need a cast-
iron guarantee. Otherwise we can't compare identity using .id.


Dave.


Dan Sugalski

unread,
Dec 12, 2002, 5:52:23 PM12/12/02
to perl6-l...@perl.org
At 2:42 PM -0800 12/12/02, Dave Whipp wrote:
>"Dan Sugalski" <d...@sidhe.org> wrote in message
>news:a05200f00ba1ebb73c6d2@[63.120.19.221]...
>> There'll definitely be memory address reuse. If .id returns the
>> current object's memory address, it shouldn't be cached any place, as
>> otherwise you'll find things going bang with some regularity.
>
>In a multi-threaded environment, even a simple
>
> $a.id == $b.id
>
>may have significant time between the two lookups.

No, that's not a problem, since neither $a nor $b can possibly go
anywhere, as they're both being referenced. The GC is aggressive, but
we do wait until a variable is at least dead before reaping it.

Larry Wall

unread,
Dec 12, 2002, 8:07:21 PM12/12/02
to Perl 6 Language
On Thu, Dec 12, 2002 at 01:50:37PM -0800, Brent Dax wrote:
: Larry Wall:

: # Hmm. Those don't really stand out enough. Maybe we should go with
: # OBJECT:: and GLOBAL:: just for a little more visual punch.
:
: How about CORE:: instead of GLOBAL::? This helps stick with tradition
: and minimize the number of reserved packages.

I don't like the Perl 5 tradition on top-level namespaces.

First of all, nobody really knows what core means anymore. Is it
just the built-in opcodes? Is it the functions that come with the
distribution? Neither of those map onto Perl 5 concept of CORE::
anymore. So Perl 6 doesn't have a CORE:: anymore. What used to
be in CORE goes into "*", whever that means.

Second, in Perl 5 there are two global namespaces apart from CORE::.
If you say $::foo, you get $main::foo. If you say $STDIN, you
get some other namespace that has no name in Perl 5. In Perl 6,
the latter truly global namespace is combined with CORE to get what
"main" was trying to be in Perl 5. The former "main" namespace is
no longer intended to be used for globals, and the $::foo syntax is
no longer supported for that purpose. The translator will translate
$::foo to $Main::foo.

So $*IN really is considered to be in the global namespace, not
in the core namespace. You might argue that "stdin" is "core" in
some sense, but all global names go into "*", not just built-ins.
This includes all user-defined package names. So the real name of
package Foo is GLOBAL::Foo. It's not Main::Foo, nor is it CORE::Foo.
It's short name isn't ::Foo, but *Foo. And you can just call it Foo
because the search for identifiers ends in GLOBAL (except for methods,
for which the search ends in OBJECT).

: # : And what will:


: # :
: # : main.*can('foo')
: # :
: # : result in?
: #
: # These days it's "Main", not "main". And it's a module, not a
: # class, so probably it fails, unless someone can think of
: # something useful for it to mean.
:
: I'd hope that Perl would allow me to do something like that to see if
: Main::foo exists...

Ordinarily you'd test for subs with one of

exists &Main::foo
&Main::foo.exists

As to whether .can should work for that, it should depend on whether
it's possible to invoke "foo" as a method in Main. This may or may
not be the same thing as having a "sub" declaration named "foo".
Certainly classes will distinguish subs from methods. It may be
that modules will too, and you'd have to write "package Main" to
get Perl to confuse them like Perl 5 does. But that's not decided yet.

It's not clear what .can should return for a multimethod, either.
You'd have be able to return results like: "yes int can mult, but
only if the second argument is an int or num". Basically, .can
has a bad syntax. We need a modifier on an ordinary multimethod
or subroutine call that says, "Go through all the motions of calling
this, but don't really." To do that kind of almost-dispatch you often
need the actual arguments, or something resembling them. One is tempted
to say that taking a reference to a function call with arguments
does something like this:

\&Main::foo(1,3)

The reference could be bound to the dispatch list, or be false if nothing
matched.

Except that syntax currently means something else, and doesn't work
for method calls. Maybe it's a good place for a question mark:

&Main::foo?(1,3)
$foo.bar?(3)

and maybe even

$x +? $y

It's vaguely possible this should be unified with currying if the
construct actually returns a reference with prebound arguments.

It's also possible that it's not visible enough, and we should say
splashy like:

can { &Main::foo(1,3) }
can { $foo.bar(3) }
can { $a + $y }

Exactly how much can-{} should do without doing anything is left as
an exercise for the reader. What would it do with this:

can { $a + $y + snort() }

I suppose one could set up a transactional structure in which "can"
actually does the side effects hypothetically, with the option of
committing later. Sort of what a "try" block would like to be when
it grows up...

Larry

James Mastros

unread,
Dec 12, 2002, 9:31:38 PM12/12/02
to Larry Wall, Perl 6 Language
On 12/12/2002 4:01 PM, Larry Wall wrote:
> On Thu, Dec 12, 2002 at 12:40:52PM -0600, Garrett Goebel wrote:
> : And what will:
> :
> : main.*can('foo')
> :
> : result in?
>
> These days it's "Main", not "main". And it's a module, not a class,
> so probably it fails, unless someone can think of something useful
> for it to mean.
It would, logicaly, mean that the class Module has a method "foo" if
true -- applying can on an object tells you if the class of that object
can do somthing, and Main is an object of class Module... right?
(%Main:: is a hash, but Main (bareword) is an object, no?)

-=- James Mastros

James Mastros

unread,
Dec 12, 2002, 9:39:18 PM12/12/02
to Larry Wall, Perl 6 Language
On 12/12/2002 8:07 PM, Larry Wall wrote:
> Ordinarily you'd test for subs with one of
>
> exists &Main::foo
> &Main::foo.exists
I thought that was now spelt exists %Main::{&foo} -- that the symbol
tables were now just plain hashes? (And what's the methody syntax for
testing for hashkey existance -- %hash{key}.exists should get the key
element of hash, then run it's exists method, logicly. Is it
%hash.exists('key')?

> I suppose one could set up a transactional structure in which "can"
> actually does the side effects hypothetically, with the option of
> committing later. Sort of what a "try" block would like to be when
> it grows up...

Or hypothetical variables in a non-regex context...

-=- James Mastros

James Mastros

unread,
Dec 12, 2002, 9:55:38 PM12/12/02
to perl6-l...@perl.org, Dan Sugalski, Michael Lazzaro, Dave Whipp
On 12/12/2002 5:24 PM, Dan Sugalski wrote:
> At 2:17 PM -0800 12/12/02, Michael Lazzaro wrote:
>> On Thursday, December 12, 2002, at 01:41 PM, Dave Whipp wrote:
>>> I might want to write code such as:
>>> $remembered_id = $obj.id;
>>> ... [ time passes ] ...
>>> if $an_object.id == $remembered_id { ... }
>>
>> I think if you do this, you're probably in a world of hurt. We'd have
>> to assure that no object id's are *ever* reused -- so mem addresses
>> are out, since the same address may be used for different things at
>> different points in time.
>
> There'll definitely be memory address reuse. If .id returns the current
> object's memory address, it shouldn't be cached any place, as otherwise
> you'll find things going bang with some regularity.
And I'd say (but who asked me -- IMHO, of course) that it should be
perfectly valid to write code like the above. (That IDs should be
unique across a process over all time.) If that'd require that an
object's ID be a combination of the header address and a generation
counter, that's OK. It means a serilization point in the allocator, but
I think we'd need one no matter what (Dan?).

-=- James Mastros

Luke Palmer

unread,
Dec 13, 2002, 4:57:23 AM12/13/02
to la...@wall.org, perl6-l...@perl.org
> Date: Thu, 12 Dec 2002 17:07:21 -0800
> From: Larry Wall <la...@wall.org>

>
> It's not clear what .can should return for a multimethod, either.
> You'd have be able to return results like: "yes int can mult, but
> only if the second argument is an int or num". Basically, .can
> has a bad syntax. We need a modifier on an ordinary multimethod
> or subroutine call that says, "Go through all the motions of calling
> this, but don't really." To do that kind of almost-dispatch you often
> need the actual arguments, or something resembling them. One is tempted
> to say that taking a reference to a function call with arguments
> does something like this:
>
> \&Main::foo(1,3)
>
> The reference could be bound to the dispatch list, or be false if nothing
> matched.

Perhaps currying could be our aide:

can(&foo.assuming(1, 3));

The only question is, what happens when not all the arguments are
curried? Perhaps it could return true if the rest of the arguments
matched any multimethod. So:

can(&bar);

Without any currying would be true if bar is a sub, and false if it
isn't. I think that generalizes nicely.

Luke

Luke Palmer

unread,
Dec 13, 2002, 5:09:08 AM12/13/02
to sira...@mindspring.com, perl6-l...@perl.org
> Date: Thu, 12 Dec 2002 16:26:28 -0500
> From: John Siracusa <sira...@mindspring.com>

>
> On 12/12/02 4:01 PM, Larry Wall wrote:
> > On Thu, Dec 12, 2002 at 12:40:52PM -0600, Garrett Goebel wrote:
> > : So we'll _have_ to write $obj.*id when we mean $obj->UNIVERSAL::id;
> >
> > If you wish to be precise, yes. But $a.id eq $b.id should work for most any
> > class that uses the the term "id" in the typical fashion.
>
> I still feel like we're talking past each other here. What I was saying is
> that, regardless of any admonitions to the contrary, I think people will
> still write this:
>
> $a.id == $b.id
>
> and expect it to compare memory addresses.

And presumably, anyone who overrides .id in their own class knows what
they're doing. They, in fact, I<want> statements like that to behave
that way. Junction, by delegation, will override that method to
return a junction of the .ids of its states.

Speaking of which, how do you code delegation?

class Disjunction is Junction {
has @.states is public;
# ...
# Use the class's AUTOLOAD?
method AUTOLOAD($name, *@args) {
any(map { $_.$name.(*@args) } @.states);
}

# Or use some kind of DELEGATE method, taking a curried
# function with only the invocant left blank.
method DELEGATE(&func) {
any(map { $_.&func } @.states);
}
}

I rather like the latter.

Luke

John Siracusa

unread,
Dec 13, 2002, 9:56:15 AM12/13/02
to Perl 6 Language
On 12/13/02 5:09 AM, Luke Palmer wrote:
>> From: John Siracusa <sira...@mindspring.com>
>> On 12/12/02 4:01 PM, Larry Wall wrote:
>>> On Thu, Dec 12, 2002 at 12:40:52PM -0600, Garrett Goebel wrote:
>>> : So we'll _have_ to write $obj.*id when we mean $obj->UNIVERSAL::id;
>>>
>>> If you wish to be precise, yes. But $a.id eq $b.id should work for most any
>>> class that uses the the term "id" in the typical fashion.
>>
>> I still feel like we're talking past each other here. What I was saying is
>> that, regardless of any admonitions to the contrary, I think people will
>> still write this:
>>
>> $a.id == $b.id
>>
>> and expect it to compare memory addresses.
>
> And presumably, anyone who overrides .id in their own class knows what
> they're doing. They, in fact, I<want> statements like that to behave
> that way.

I think you're missing my point. I'm saying that there are many kinds of
objects that naturally want to have an "id" method or attribute that has
nothing whatsoever to do with "this is the same object" comparisons. But if
"id" is chosen as the name of the global "this is the same object" method in
Perl 6, then no one can safely use a method named "id" (overridden or
otherwise) for anything but "this is the same object" comparisons.

I think this is a bad idea because "this is the same object" comparisons are
relatively rare, and do not deserve to be hogging the short, direct method
name of "id".

Example: Instead of getting a user id via $user.id and a product id via
$product.id, Perl 6 programmers will be forced to mark-up their methods
names ($user.uid, $product.pid) and then deal with the differences in any
heterogeneous collection:

# Too bad the method named "id" is taken by a value that
# you're rarely interested in, huh :P
for @users, @products, @transactions, @mixed -> $thing
{
print $thing.type, " id ";

given $thing.type
{
when 'user' { print $thing.uid }
when 'process' { print $thing.pid }
when 'transaction' { print $thing.tid }
...
}

print "\n";
}

As opposed to:

# Ah, blessed sanity...
for @users, @products, @transactions, @mixed -> $thing
{
print $thing.type, " id ", $thing.id, "\n";
}

(Yes, you could just decide that all your objects will use "oid" or
something else, but that would be another symptom of the problem: Perl 6 is
forcing you to (slightly) obfuscate your code. Your first thought was to
simply use the well understood name "id" like you always have, but you're
out of luck.)

Using the method/attribute named "id" for "this is the same object"
comparisons is just plain bad Huffman coding. The "this is the same object"
method/attribute should have a name that reflects the relative rarity of its
use.

-John

Michael Lazzaro

unread,
Dec 13, 2002, 12:32:02 PM12/13/02
to sira...@mindspring.com, Perl 6 Language

On Friday, December 13, 2002, at 06:56 AM, John Siracusa wrote:
> I'm saying that there are many kinds of objects that naturally want to
> have an "id" method or attribute that has nothing whatsoever to do
> with "this is the same object" comparisons. But if "id" is chosen as
> the name of the global "this is the same object" method in Perl 6,
> then no one can safely use a method named "id" (overridden or
> otherwise) for anything but "this is the same object" comparisons.

I agree 100%. I use .id *often* in my coding. Or more accurately, I
must connect regularly with database tables that have 'id' as a field I
need to extract. :-( (And postgresql uses 'oid' as a globally unique
id.)

I think this is one (rare) case where an UPPERCASE or unusual name
might not be a bad idea, so it will BRING ATTENTION to the fact that
you're using a unusual method.

$obj.ID;
$obj.IDENTITY;

If don't think we'll have much of a chance at teaching people to
_always_ use ($obj.*id == $obj.*id) instead of ($obj.id == $obj.id).

MikeL

Michael Lazzaro

unread,
Dec 13, 2002, 12:44:07 PM12/13/02
to James Mastros, perl6-l...@perl.org, Dan Sugalski, Dave Whipp

On Thursday, December 12, 2002, at 06:55 PM, James Mastros wrote:
> And I'd say (but who asked me -- IMHO, of course) that it should be
> perfectly valid to write code like the above. (That IDs should be
> unique across a process over all time.) If that'd require that an
> object's ID be a combination of the header address and a generation
> counter, that's OK. It means a serilization point in the allocator,
> but I think we'd need one no matter what (Dan?).

I'm more worried about storing them than creating them. The good thing
about using memaddresses is that they're free; you don't need to store
a separate ID in each and every object you ever create, on the off
chance that something will want to use it.

Having an actual internal ID associated with every object would mean
you'd have to store all those IDs, which could get very big very fast.
I think the odds of you wanting a truly unique ID for any given class
are so low that we'd probably be better off leaving it as a DIY project.

MikeL

Brent Dax

unread,
Dec 13, 2002, 12:58:34 PM12/13/02
to Michael Lazzaro, James Mastros, perl6-l...@perl.org, Dan Sugalski, Dave Whipp
Michael Lazzaro:
# On Thursday, December 12, 2002, at 06:55 PM, James Mastros wrote:
# > And I'd say (but who asked me -- IMHO, of course) that it should be
# > perfectly valid to write code like the above. (That IDs should be
# > unique across a process over all time.) If that'd require that an
# > object's ID be a combination of the header address and a generation
# > counter, that's OK. It means a serilization point in the
# allocator,
# > but I think we'd need one no matter what (Dan?).
#
# I'm more worried about storing them than creating them. The
# good thing
# about using memaddresses is that they're free; you don't need
# to store
# a separate ID in each and every object you ever create, on the off
# chance that something will want to use it.

Generating the Ids on request (i.e. the first time you call .id) would
help, but it would still mean having a slot for the information.

Honestly, I think a unique-across-the-object's-lifetime ID is probably
fine for many purposes. Perhaps we could have a sort of weak reference
that would null itself out when its referent was destroyed, if this is a
problem. (Don't know how that would work with the whole immutable hash
keys thing, though...)

John Siracusa

unread,
Dec 13, 2002, 12:45:50 PM12/13/02
to Perl 6 Language
On 12/13/02 12:44 PM, Michael Lazzaro wrote:
> On Thursday, December 12, 2002, at 06:55 PM, James Mastros wrote:
>> And I'd say (but who asked me -- IMHO, of course) that it should be
>> perfectly valid to write code like the above. (That IDs should be
>> unique across a process over all time.) If that'd require that an
>> object's ID be a combination of the header address and a generation
>> counter, that's OK. It means a serilization point in the allocator,
>> but I think we'd need one no matter what (Dan?).
>
> I'm more worried about storing them than creating them. The good thing
> about using memaddresses is that they're free; you don't need to store
> a separate ID in each and every object you ever create, on the off
> chance that something will want to use it.
>
> Having an actual internal ID associated with every object would mean
> you'd have to store all those IDs, which could get very big very fast.

You could always just autovivify them. Since most objects will never have
their "UUID"s accessed, the overhead should be very small.

> I think the odds of you wanting a truly unique ID for any given class
> are so low that we'd probably be better off leaving it as a DIY project.

I think it's important enough to be in the "core", if only to prevent
fragmentation in the world of object persistence.

-John

Dave Storrs

unread,
Dec 12, 2002, 10:06:45 PM12/12/02
to Perl 6 Language

Dave Storrs

unread,
Dec 13, 2002, 10:27:47 AM12/13/02
to Perl 6 Language
On Fri, Dec 13, 2002 at 09:56:15AM -0500, John Siracusa wrote:

> Using the method/attribute named "id" for "this is the same object"
> comparisons is just plain bad Huffman coding. The "this is the same object"
> method/attribute should have a name that reflects the relative rarity of its
> use.

FWIW, I have agreed with John throughout this entire thread, but I
felt that he was stating things quite clearly and I didn't have
anything further to add. I just want to chime in so he doesn't feel
like a lone voice in the wilderness.

--Dks

Buddha Buck

unread,
Dec 13, 2002, 1:49:00 PM12/13/02
to Michael Lazzaro, sira...@mindspring.com, Perl 6 Language
Michael Lazzaro wrote:

> I think this is one (rare) case where an UPPERCASE or unusual name might
> not be a bad idea, so it will BRING ATTENTION to the fact that you're
> using a unusual method.
>
> $obj.ID;
> $obj.IDENTITY;
>
> If don't think we'll have much of a chance at teaching people to
> _always_ use ($obj.*id == $obj.*id) instead of ($obj.id == $obj.id).

I agree.

My understanding of what Larry was proposing would have the majority of
cases where people would want to use $obj.*id, $obj.id would work as
well. If that is the case, there is no incentive for the majority of
programmers to be careful enough to use the longer form $obj.*id instead
of the shorter $obj.id form. Especially when explaining what the * in
*id does has to be done.

I feel that, in cases were $obj.id would have a natural interpretation
in the class meaning something other than an object-specific ID,
developers would be bit too often by careless use of $obj.id when
$obj.*id is needed.

>
> MikeL
>
>

Austin Hastings

unread,
Dec 13, 2002, 5:25:07 PM12/13/02
to Michael Lazzaro, James Mastros, perl6-l...@perl.org, Dan Sugalski, Dave Whipp

--- Michael Lazzaro <mlaz...@cognitivity.com> wrote:
>
> I'm more worried about storing them than creating them. The good
> thing
> about using memaddresses is that they're free; you don't need to
> store
> a separate ID in each and every object you ever create, on the off
> chance that something will want to use it.
>
> Having an actual internal ID associated with every object would mean
> you'd have to store all those IDs, which could get very big very
> fast.
> I think the odds of you wanting a truly unique ID for any given class
>
> are so low that we'd probably be better off leaving it as a DIY
> project.

Not necessarily. People who don't know any better can use .memaddr (or
some other unique-internally method that needs only one opcode). People
who use .id are either going to be paying too-high a price for their
simple comparisons, or are going to want to pay the price.

The information itself could be attached as a property, so every object
doesn't have to pay the 16 bytes of overhead.

=Austin

Garrett Goebel

unread,
Dec 13, 2002, 5:41:21 PM12/13/02
to Austin_...@yahoo.com, Michael Lazzaro, James Mastros, perl6-l...@perl.org, Dan Sugalski, Dave Whipp
Michael Lazzaro wrote:
>
> I'm more worried about storing them than creating them.
> The good thing about using memaddresses is that they're
> free;

An UUID could be free up until the point where you request it.


> I think the odds of you wanting a truly unique ID for any
> given class are so low that we'd probably be better off
> leaving it as a DIY project.

I thought we wanted to be able to guarantee a unique identifier across the
life of the object? -Objects may outlive processes... I'd rather trust the
implementation than DIY'ers.


--
Garrett Goebel
IS Development Specialist

ScriptPro Direct: 913.403.5261
5828 Reeds Road Main: 913.384.1008
Mission, KS 66202 Fax: 913.384.2180
www.scriptpro.com gar...@scriptpro.com

Dan Sugalski

unread,
Dec 14, 2002, 11:16:45 AM12/14/02
to James Mastros, perl6-l...@perl.org, Michael Lazzaro, Dave Whipp
At 9:55 PM -0500 12/12/02, James Mastros wrote:
>On 12/12/2002 5:24 PM, Dan Sugalski wrote:
>>At 2:17 PM -0800 12/12/02, Michael Lazzaro wrote:
>>>On Thursday, December 12, 2002, at 01:41 PM, Dave Whipp wrote:
>>>>I might want to write code such as:
>>>> $remembered_id = $obj.id;
>>>> ... [ time passes ] ...
>>>> if $an_object.id == $remembered_id { ... }
>>>
>>>I think if you do this, you're probably in a world of hurt. We'd
>>>have to assure that no object id's are *ever* reused -- so mem
>>>addresses are out, since the same address may be used for
>>>different things at different points in time.
>>
>>There'll definitely be memory address reuse. If .id returns the
>>current object's memory address, it shouldn't be cached any place,
>>as otherwise you'll find things going bang with some regularity.
>And I'd say (but who asked me -- IMHO, of course) that it should be
>perfectly valid to write code like the above.

As long as valid!=correct, sure.

> (That IDs should be unique across a process over all time.) If
>that'd require that an object's ID be a combination of the header
>address and a generation counter, that's OK. It means a
>serilization point in the allocator, but I think we'd need one no
>matter what (Dan?).

That's going to be expensive, and that's a bad idea. If you want an
expensive and long-lived variable tracking facility, build one and
add it on later. The base version should be fast, and sufficient for
the common case.

Dave Storrs

unread,
Dec 13, 2002, 1:31:39 PM12/13/02
to Perl 6 Language
On Fri, Dec 13, 2002 at 09:32:02AM -0800, Michael Lazzaro wrote:
>
> $obj.ID;
> $obj.IDENTITY;

FWIW, I favor the latter.

--Dks

Aaron Crane

unread,
Dec 16, 2002, 7:19:42 AM12/16/02
to Perl 6 Language
Piers Cawley writes:
> I found myself mulling over:
>
> $obj.is($other_obj);
>
> Which seems to work reasonably well, and I'd be rather surprised if it
> clashed with anything with different semantics...

I quite like it. It also has the advantage of disallowing the equivalent
of:

my $stored_identity = $obj.id;
# Time passes...
if ($other_obj.id == $stored_identity) {
# Massive breakage ahoy
}

There just isn't any way you can get .is() to compare identities at different
times.

--
Aaron Crane * GBdirect Ltd.
http://training.gbdirect.co.uk/courses/perl/

Piers Cawley

unread,
Dec 16, 2002, 7:14:52 AM12/16/02
to Perl 6 Language
Dave Storrs <dst...@megazone.bigpanda.com> writes:

I found myself mulling over:

Piers Cawley

unread,
Dec 16, 2002, 1:49:59 PM12/16/02
to Perl 6 Language
Aaron Crane <aar...@gbdirect.co.uk> writes:

> Piers Cawley writes:
>> I found myself mulling over:
>>
>> $obj.is($other_obj);
>>
>> Which seems to work reasonably well, and I'd be rather surprised if it
>> clashed with anything with different semantics...
>
> I quite like it. It also has the advantage of disallowing the equivalent
> of:
>
> my $stored_identity = $obj.id;
> # Time passes...
> if ($other_obj.id == $stored_identity) {
> # Massive breakage ahoy
> }

Ah, sorry, I thought that went without saying. So I didn't say
it. That's actually the problem that led me to come up with .is in
the first place.

> There just isn't any way you can get .is() to compare identities at
> different times.

Indeed. I'm definitely liking it the more I think about it. Someone
will be along to say 'but I use C<is> in *all* my classes!' soon,
mark my words.

Dave Whipp

unread,
Dec 16, 2002, 3:48:45 PM12/16/02
to perl6-l...@perl.org
"Piers Cawley" <pdca...@bofh.org.uk> wrote :

> I found myself mulling over:
>
> $obj.is($other_obj);
>
> Which seems to work reasonably well, and I'd be rather surprised if
> it clashed with anything with different semantics...

My only problem with it is the lack of symmetry. Is there any reason why
an adverb syntax can't work:

$a eq : ID $b # yes, I would want to generalize that

This infix style might separate the operands visually. So perhaps

eq:ID($a, $b)


Dave.


Piers Cawley

unread,
Dec 16, 2002, 4:23:58 PM12/16/02
to Dave Whipp, perl6-l...@perl.org
"Dave Whipp" <david...@fast-chip.com> writes:

> "Piers Cawley" <pdca...@bofh.org.uk> wrote :
>> I found myself mulling over:
>>
>> $obj.is($other_obj);
>>
>> Which seems to work reasonably well, and I'd be rather surprised if
>> it clashed with anything with different semantics...
>
> My only problem with it is the lack of symmetry. Is there any reason why
> an adverb syntax can't work:
>
> $a eq : ID $b # yes, I would want to generalize that

I started off thinking 'well, you could just define an 'is' operator'
and then realised we already have one. Hmm. Personally i don't have a
problem with not having an operator for this particular
functionality, I reckon it 'belongs' as a message...

Dave Whipp

unread,
Dec 16, 2002, 4:35:34 PM12/16/02
to perl6-l...@perl.org
"Piers Cawley" <pdca...@bofh.org.uk> wrote :

> > $a eq : ID $b # yes, I would want to generalize that
>
> I started off thinking 'well, you could just define an 'is' operator'
> and then realised we already have one. Hmm. Personally i don't have a
> problem with not having an operator for this particular
> functionality, I reckon it 'belongs' as a message...


I've been thinking about my initial suggestions, and the rx modifiers
came to mind:

I can imagine writing:

$a eq:i $b # compare, case insensitive
$a eq:w $b # compare, ignore whitespace differences
$a eq:ID $b # compare identities

I think that the modifier concept is too useful to be limited to the
rx// operator. But there is the issue of passing parameters to
modifiers. I could live with a restriction that forces me to use
the prefix (cf infix) form of the modified operator.


Dave.


Austin Hastings

unread,
Dec 16, 2002, 5:20:25 PM12/16/02
to Dave Whipp, perl6-l...@perl.org
--- Dave Whipp <david...@fast-chip.com> wrote:
> I can imagine writing:
>
> $a eq:i $b # compare, case insensitive
> $a eq:w $b # compare, ignore whitespace differences
> $a eq:ID $b # compare identities
>
> I think that the modifier concept is too useful to be limited to the
> rx// operator. But there is the issue of passing parameters to
> modifiers. I could live with a restriction that forces me to use
> the prefix (cf infix) form of the modified operator.

Woo-hoo! Adverbs! This is cool.

Going one step farther,

$a eq:$funcptr $b

or

$a eq:numerically $b
$a eq:soundex $b
$a eq:case_insensitive

So that an overridden eq could check itself (?) for properties...

=Austin

0 new messages