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

PerlHash.get_pmc_keyed of non existing key

0 views
Skip to first unread message

Leopold Toetsch

unread,
Aug 21, 2003, 11:50:00 AM8/21/03
to P6I
IMHO is

$a = \$h{"a"};
print $$a;
$$a = "xxx\n";
$a = $h{"a"};
print $a;

the same as:

new P1, .PerlHash
set P0, P1["a"]
print P0
set P0, "xxx\n"
set P2, P1["a"]
print P2
end

(PMCs have reference semantics[1])
Shouldn't that print "xxx" as perl5 does? I.e. store the returned
PerlUndef in the hash.
And PerlArray too.

leo

[1]
new P1, .PerlHash
new P3, .PerlString
set P3, "yyy\n"
set P1["a"], P3
set P0, P1["a"]
print P0
set P0, "xxx\n"
set P2, P1["a"]
print P2
end
yyy
xxx

Benjamin Goldberg

unread,
Aug 21, 2003, 9:44:51 PM8/21/03
to perl6-i...@perl.org

Leopold Toetsch wrote:
>
> IMHO is
>
> $a = \$h{"a"};
> print $$a;
> $$a = "xxx\n";
> $a = $h{"a"};
> print $a;
>
> the same as:
>
> new P1, .PerlHash
> set P0, P1["a"]
> print P0
> set P0, "xxx\n"
> set P2, P1["a"]
> print P2
> end
>
> (PMCs have reference semantics[1])
> Shouldn't that print "xxx" as perl5 does? I.e. store the returned
> PerlUndef in the hash.

If you'd done:

assign P0, "xxx\n"

Instead of set, then yes. However, "set Px, Py" merely stores Py into
the register Px, without touching the PMC that was in it.

--
$a=24;split//,240513;s/\B/ => /for@@=qw(ac ab bc ba cb ca
);{push(@b,$a),($a-=6)^=1 for 2..$a/6x--$|;print "$@[$a%6
]\n";((6<=($a-=6))?$a+=$_[$a%6]-$a%6:($a=pop @b))&&redo;}

Gordon Henriksen

unread,
Aug 21, 2003, 10:39:11 PM8/21/03
to Leopold Toetsch, perl6-i...@perl.org
On Thursday, August 21, 2003, at 11:50 , Leopold Toetsch wrote:

> IMHO is
>
> $a = \$h{"a"};
> print $$a;
> $$a = "xxx\n";
> $a = $h{"a"};
> print $a;
>
> the same as:
>
> new P1, .PerlHash
> set P0, P1["a"]
> print P0
> set P0, "xxx\n"
> set P2, P1["a"]
> print P2
> end
>
> (PMCs have reference semantics[1])
> Shouldn't that print "xxx" as perl5 does? I.e. store the returned
> PerlUndef in the hash. And PerlArray too.

Isn't that the job of Perl's \ operator?

perl <<'EOT'
my %hash = ();
my $temp = $hash{key};
print 'after $temp = $hash{key}: ', exists $hash{key}? "exists\n" :
"does not exist\n";
$temp = \$hash{key};
print 'after $temp = \$hash{key}: ', exists $hash{key}? "exists\n" :
"does not exist\n";
EOT

Or, better, Perl's lvalue context...

Gordon Henriksen
mali...@mac.com

Leopold Toetsch

unread,
Aug 22, 2003, 4:16:33 AM8/22/03
to Benjamin Goldberg, perl6-i...@perl.org
Benjamin Goldberg <ben.go...@hotpop.com> wrote:
>> (PMCs have reference semantics[1])

I should have started with [1]:

new P1, .PerlHash
# new P3, .PerlString
# set P3, "yyy\n"
# set P1["a"], P3


set P0, P1["a"]
print P0
set P0, "xxx\n"
set P2, P1["a"]
print P2
end

When the hash entry exists (3 comments enabled), there is a different
behavior compared to the non existing case. "set"ting (assigning) the
returned P0 changes the aggregate member or not.

> If you'd done:

> assign P0, "xxx\n"

set P0, "xx" and assign P0, "xx" are the same. As already outlined,
one of these opcodes is obsolete. "set" does assign for I,N,S registers.

> Instead of set, then yes. However, "set Px, Py" merely stores Py into
> the register Px, without touching the PMC that was in it.

There is not set P, P in above code.

So I assume, that the returned PerlUndef should be put into the
aggregate, if there was none before access.

leo

Leopold Toetsch

unread,
Aug 22, 2003, 2:52:51 AM8/22/03
to Gordon Henriksen, perl6-i...@perl.org
Gordon Henriksen wrote:

> (PMCs have reference semantics[1])
>

> Isn't that the job of Perl's \ operator?

Did you read on to [1] too?

leo


Gordon Henriksen

unread,
Aug 22, 2003, 10:07:31 AM8/22/03
to Leopold Toetsch

I read

>>> [1]
>>> new P1, .PerlHash
>>> new P3, .PerlString
>>> set P3, "yyy\n"

>>> set P1["a"], P3
>>> set P0, P1["a"]
>>> print P0
>>> set P0, "xxx\n"
>>> set P2, P1["a"]
>>> print P2
>>> end

>>> yyy
>>> xxx

as equivalent to...

$hash{a} = "yyy\n";
$y := $hash{a}; # Note :=lhs instead of =lhs or =\lhs.
print $y; # yyy
$y = "xxx\n";
print $hash{a}; # xxx

Makes sense.

My point was only that element lookup in an rvalue (get) should be
explicitly non-modifying—only element lookup in an lvalue context (put)
should auto-vivify. But indirect puts like this are also necessary. (The
rhs of := is an l-value. As is the operand to \.)

With that in mind, Perl could construct lvalue operations (those with
auto-vivify) from rvalue operations (without auto-vivify). But the
reverse isn't true. So the no-auto-vivify semantics are the one that
must be preserved. Which contradicts your point that set Pn, Pm[...]
should always auto-vivify to support reference semantics. But, really,
both are significantly needed—$str = $hash{key} and $ref = \$hash{key}
and $str := $hash{key} and $hash{key} := $str and $hash{key} = $str and
$hashB{keyB}{keyC}{keyD} = $hash{key} should all come down to PIR simply
and behave as in Perl 5 (where the construct exists in Perl 5). Element
lookup in an rvalue context should return an anonymous PerlUndef,
probably? In an lvalue context, it should do what you're asking for.

But my reading of [1] is not at all the same as this...

$hash{a} = "yyy\n";
$y = \$hash{a}; # = \ --> Brand new reference PMC!
print $$y; # yyy
$$y = "xxx\n";
print $hash{a}; # xxx

Never mind that there's no PerlReference PMC for $$ to work on, or for \
to return. While Perl 6 could conceivably support reference copying
without a reference-type PMC (using :=), it would be pretty darn
fragile—one = instead of := and the reference is broken. I would not
have translated your original Perl example (with its \) as you did—
actually, I wouldn't be able to translate it at all—\ wants to construct
a PerlReference PMC IMO.

Gordon Henriksen
mali...@mac.com

Nicholas Clark

unread,
Aug 23, 2003, 3:09:57 PM8/23/03
to Leopold Toetsch, Benjamin Goldberg, perl6-i...@perl.org
Having read the whole thread a few times, I think I understand the
question.

On Fri, Aug 22, 2003 at 10:16:33AM +0200, Leopold Toetsch wrote:
> Benjamin Goldberg <ben.go...@hotpop.com> wrote:
> >> (PMCs have reference semantics[1])
>
> I should have started with [1]:
>
> new P1, .PerlHash
> # new P3, .PerlString
> # set P3, "yyy\n"
> # set P1["a"], P3
> set P0, P1["a"]
> print P0
> set P0, "xxx\n"
> set P2, P1["a"]
> print P2
> end
>
> When the hash entry exists (3 comments enabled), there is a different
> behavior compared to the non existing case. "set"ting (assigning) the
> returned P0 changes the aggregate member or not.

Interesting.

> > If you'd done:
>
> > assign P0, "xxx\n"
>
> set P0, "xx" and assign P0, "xx" are the same. As already outlined,
> one of these opcodes is obsolete. "set" does assign for I,N,S registers.

> So I assume, that the returned PerlUndef should be put into the


> aggregate, if there was none before access.

I believe yes, it must, for consistency.
Is there an op to copy the value out of an aggregate, without changing
the aggregate? The (shallow copy) value assignment, needed to implement

$a = $h{"a"};
print $a;
$$a = "xxx\n";
$a = $h{"a"};
print $a;

(ie not \$h{"a"})

Nicholas Clark

Leopold Toetsch

unread,
Aug 24, 2003, 5:08:19 AM8/24/03
to Nicholas Clark, perl6-i...@perl.org
Nicholas Clark wrote:


>>So I assume, that the returned PerlUndef should be put into the
>>aggregate, if there was none before access.
>>
>
> I believe yes, it must, for consistency.
> Is there an op to copy the value out of an aggregate, without changing
> the aggregate? The (shallow copy) value assignment, needed to implement

I think, we need another kind of keyed opcodes that do assign

assign P0, P1[key] # assign in PMC, in PMC, in (INT)?KEY

Same for other LHS types. The LHS has to exist before, and get the value
of the aggregate member, which doesn't get autovivified like set should
do. Its the same as in the "set vs assign" thread.


> Nicholas Clark

leo


0 new messages