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

[RFC] How are compound keys with a PerlHash intended to work?

17 views
Skip to first unread message

Leopold Toetsch

unread,
Sep 13, 2002, 3:51:45 AM9/13/02
to P6I
Let's first compare with a PerlArray:
(following snippet is from an imcc test file, in PASM syntax)

new P1, .PerlArray
new P0, .PerlArray
set P1[0], P0
set P0[1], 2
set I0, P1[0;1]
print I0 => 2

i.e. "P1[0;.." returns an array PMC, which, indexed by key_next, gives
the final result, which is @a[0][1] in perl6 - DWIM.

This is functional with variables as keys too.

set I0, 1
set I1, 1
set I2, P1[I0;I1]
print I2 => 2


The same system with a PerlHash doesn't:

new P2, .PerlHash
set P2["a"], P1 # P1 from above
set I0, P2["a";0;1] => DWIM = 2, but isn't:
"PerlHash does not support compound keys!"

So the question arises to the syntax gurus, should it work like this?

and is a perl6 %h{"a"}[0][1] a PASM P2["a";0;1]?

Implementation notes:
- the hash will be indexed by the first key component (a string)
- when the key has no key_next then old behaviour
- when there is a key_next: return the _keyed vtable method of the

found hash_entry with key_next as key.

So this should then behave like above with arrays.

Comments welcome
leo

Dan Sugalski

unread,
Sep 13, 2002, 5:05:49 AM9/13/02
to Leopold Toetsch, P6I
At 9:51 AM +0200 9/13/02, Leopold Toetsch wrote:
>The same system with a PerlHash doesn't:

[Snip]

>So the question arises to the syntax gurus, should it work like this?

Yes.

>and is a perl6 %h{"a"}[0][1] a PASM P2["a";0;1]?

Yes.
--
Dan

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

Leopold Toetsch

unread,
Sep 13, 2002, 6:42:36 AM9/13/02
to Dan Sugalski, P6I
Dan Sugalski wrote:

> At 9:51 AM +0200 9/13/02, Leopold Toetsch wrote:
>
>> and is a perl6 %h{"a"}[0][1] a PASM P2["a";0;1]?
>
> Yes.

Fine, thought so too, thanks for your quick answer.

I have already a patch for it, I'll make an entry in t/pmc/perlhash.t too.

_But_:

What about all these bogus additional vtable methods of e.g. PerlHash,
that are currently implemented, or have dummy function bodies?

My proposal:

- get rid of them, _all_. If one wants multiply two hashes, he can
implement a _meaningful_ method. Add and subtract could be useful, but
not with the current implementation.

- get_string returns "PerlHash[0xpmcaddr]"

- let the default.pmc, where all these non existent methods will end,
through an appropriate execption.

- if any pmc needs a functionality from current default.pmc, then:
- copy default.pmc to defaultscalar.pmc
- and let these PMCs inherit from this class.

(default.pmc works now similar to PerlUndef, but tries to do something
meaningful, e.g. get_integer, but all classes I looked at do have there
own get_integer.)

- default.pmc shoud be number #0 in the PMC enumeration, so that an
lookup of a non existant PMC class will return 0 (as it doese now) but -
this class is not valid.

- default.pmc could be renamed to invalid.pmc, to make clear, what the
intent is.

leo

Dan Sugalski

unread,
Sep 14, 2002, 8:51:17 AM9/14/02
to Leopold Toetsch, P6I
At 12:42 PM +0200 9/13/02, Leopold Toetsch wrote:
>
>_But_:
>
>What about all these bogus additional vtable methods of e.g.
>PerlHash, that are currently implemented, or have dummy function
>bodies?

Toss them. I have one more overhaul for vtables, and we may well go
entirely multimethod for them soon.

Graham Barr

unread,
Sep 15, 2002, 4:27:22 AM9/15/02
to Dan Sugalski, Leopold Toetsch, P6I
On Fri, Sep 13, 2002 at 11:05:49AM +0200, Dan Sugalski wrote:
> At 9:51 AM +0200 9/13/02, Leopold Toetsch wrote:
> >The same system with a PerlHash doesn't:
>
> [Snip]
>
> >So the question arises to the syntax gurus, should it work like this?
>
> Yes.
>
> >and is a perl6 %h{"a"}[0][1] a PASM P2["a";0;1]?
>
> Yes.

There is one thing that has been bugging me since I read this. Where
is the type checking done ?

In Perl if element %h{"a"} contained a hash reference, Perl would complain.
But I dont see anything in the parrot code to allow parrot todo such a test.

Graham.

Leopold Toetsch

unread,
Sep 15, 2002, 5:44:24 AM9/15/02
to Dan Sugalski, P6I
Dan Sugalski wrote:

> At 12:42 PM +0200 9/13/02, Leopold Toetsch wrote:
>
>>
>> _But_:
>>
>> What about all these bogus additional vtable methods of e.g. PerlHash,
>> that are currently implemented, or have dummy function bodies?
>
>
> Toss them. I have one more overhaul for vtables, and we may well go
> entirely multimethod for them soon.


Thanks, patch for perlhash is in, which is a first step for classes cleanup.


What about the rest of my proposal:

All e.g. in perlhash unimplemented vtable functions are handled by
default.pmc (or invalid.pmc), which should _IMHO_ through an exception
with a meanigful text like: "class <class> tried to call illegal funtion
<func> at <pc>".

And default.pmc should be the PMC class #0 in the enum, stating, it's
illegal to use this class.

AFAIK does no class inherit something useful from default.pmc now, the
most useful thing to inherit, would be above error checking.

leo

Leopold Toetsch

unread,
Sep 15, 2002, 6:22:23 AM9/15/02
to Graham Barr, Dan Sugalski, P6I
Graham Barr wrote:


The type check is done implicitely. Whatever %h{"a"} contains, it's
either the final result (in case of a simple hash) or it's a PMC of some
type.
Here is the relevant part of perlhash: get_integer_keyed()

// hash entry is an int? ok finito.
if (entry->type == enum_hash_int)
return entry->val.int_val;

// no, hash contains a PMC
if (entry->type == enum_hash_pmc) {
PMC* nextkey;
nextkey = key_next(INTERP, key);
valpmc = entry->val.pmc_val;

// single key
// get the integer from this PMC
if (!nextkey)
return valpmc->vtable->get_integer(INTERP, valpmc);

// compound (chained key), %h{"a"}[0]...
return valpmc->vtable->get_integer_keyed(INTERP, valpmc, nextkey);

Call the vtable method get_integer_keyed of %h{"a"} with the argument of
the next key.
If this PMC now doesn't know, what todo with get_integer_keyed, the
default implementation through's an exception ("Subscript on something,
that's not an aggregate")

So whatever is in %h{"a"} must be the right thing to resolve the next
key until the final result of these compound keys is found.

In above example %h{"a"}[0] (P0["a";0]) stops with the error "Not a
string!" for your case, when %h{"a"} contains a hash PMC.

> Graham.


leo


Dan Sugalski

unread,
Sep 15, 2002, 7:30:38 AM9/15/02
to Graham Barr, Leopold Toetsch, P6I
At 9:27 AM +0100 9/15/02, Graham Barr wrote:
>On Fri, Sep 13, 2002 at 11:05:49AM +0200, Dan Sugalski wrote:
>> At 9:51 AM +0200 9/13/02, Leopold Toetsch wrote:
>> >The same system with a PerlHash doesn't:
>>
>> [Snip]
>>
>> >So the question arises to the syntax gurus, should it work like this?
>>
>> Yes.
>>
>> >and is a perl6 %h{"a"}[0][1] a PASM P2["a";0;1]?
>>
>> Yes.
>
>There is one thing that has been bugging me since I read this. Where
>is the type checking done ?

On lookup. The aggregate being queried by key is responsible for
complaining if the key its passed is something that it doesn't like.

Ken Fox

unread,
Sep 15, 2002, 9:40:52 AM9/15/02
to Dan Sugalski, Graham Barr, Leopold Toetsch, P6I
Dan Sugalski wrote:
> At 9:27 AM +0100 9/15/02, Graham Barr wrote:
>> There is one thing that has been bugging me since I read this. Where
>> is the type checking done ?
>
> On lookup. The aggregate being queried by key is responsible for
> complaining if the key its passed is something that it doesn't like.

If %h{"a"}[0][1] is a PASM P2["a";0;1], then what is %h{"a"}{0}{1}?

It can't be the same thing, because then we lose the distinction
between hash and array lookups. (I think this is where the type
checking confusion is.)

- Ken

Steve Fink

unread,
Sep 15, 2002, 6:18:54 PM9/15/02
to Leopold Toetsch, Dan Sugalski, P6I
On Sun, Sep 15, 2002 at 11:44:24AM +0200, Leopold Toetsch wrote:
> What about the rest of my proposal:
>
> All e.g. in perlhash unimplemented vtable functions are handled by
> default.pmc (or invalid.pmc), which should _IMHO_ through an exception
> with a meanigful text like: "class <class> tried to call illegal funtion
> <func> at <pc>".

Dan already okayed this a while back. I was supposed to be doing it,
but my tuit shipment was confiscated due to heightened airport
security. So go right ahead (please!). The conclusion of the
discussion the last time this was brought up was that you don't even
need to keep the unused default implementations around; we can
resurrect them from CVS if we ever need them.

Leopold Toetsch

unread,
Sep 16, 2002, 3:03:55 AM9/16/02
to Ken Fox, Dan Sugalski, Graham Barr, P6I
Ken Fox wrote:

> Dan Sugalski wrote:

>> On lookup. The aggregate being queried by key is responsible for
>> complaining if the key its passed is something that it doesn't like.
>
>
> If %h{"a"}[0][1] is a PASM P2["a";0;1], then what is %h{"a"}{0}{1}?
>
> It can't be the same thing, because then we lose the distinction
> between hash and array lookups. (I think this is where the type
> checking confusion is.)


In PASM they look the same. But as Dan stated, and as tried to show in
my answer to Graham, the lookup succeeds only if the nested PMCs are all
of the correct type. This works now because an array doesn't support a
string as key, while a perlhash doesn't support an int as key.

So the wrong types will produce either "Not a string!" or "Not an integer!".


> - Ken

leo

Dan Sugalski

unread,
Sep 18, 2002, 4:15:20 AM9/18/02
to Leopold Toetsch, Ken Fox, Graham Barr, P6I

I've been thinking that we do need to have an extra flag to note
whether a key element should be taken as an array or hash lookup
element. The integer 1 isn't quite enough, since someone may have
done a %foo{1} and we only have that in as an integer key.

Graham Barr

unread,
Sep 18, 2002, 6:25:59 AM9/18/02
to Dan Sugalski, Leopold Toetsch, Ken Fox, P6I
On Wed, Sep 18, 2002 at 10:15:20AM +0200, Dan Sugalski wrote:
> I've been thinking that we do need to have an extra flag to note
> whether a key element should be taken as an array or hash lookup
> element. The integer 1 isn't quite enough, since someone may have
> done a %foo{1} and we only have that in as an integer key.

I agree. Using integer key == array and string key == hash is not
enough imo. What about a hash that is index by object, not a string.
What about an array that is index by strings ? ie

my @array is indexed('a'..'z');

So if parrot wants to provide a method for compound keys, then the
HL should be able to specify what type it is expecting each level
to be.

But the question also exists how this flag should be used/checked.

For example, does the op use it to test the PMC type before calling
the method to fetch the contents, or does it just pass it to the
method and let the PMC do what it wants with it.

I would suggest it gets passed to the method as an argument. That
would allow a PMC to be written that does not care how it is accessed.
But it would also allow the PMC class to do something different
depending on how it is accessed.

Graham.

Leopold Toetsch

unread,
Sep 18, 2002, 4:54:40 AM9/18/02
to Dan Sugalski, Ken Fox, Graham Barr, P6I
Dan Sugalski wrote:

> At 9:03 AM +0200 9/16/02, Leopold Toetsch wrote:

>> In PASM they look the same. But as Dan stated, and as tried to show in
>> my answer to Graham, the lookup succeeds only if the nested PMCs are
>> all of the correct type. This works now because an array doesn't
>> support a string as key, while a perlhash doesn't support an int as key.
>>
>> So the wrong types will produce either "Not a string!" or "Not an
>> integer!".
>
>
> I've been thinking that we do need to have an extra flag to note whether
> a key element should be taken as an array or hash lookup element. The
> integer 1 isn't quite enough, since someone may have done a %foo{1} and
> we only have that in as an integer key.

There are IMHO 2 solutions for this:
- the HL takes care of this, so imcc sees: _HV_foo["1"]
- assembler/imcc takes care of this: P0[1] => array, P0{1} => hash and
generates a string key for the latter.

leo

Dan Sugalski

unread,
Sep 18, 2002, 10:38:06 AM9/18/02
to Graham Barr, Leopold Toetsch, Ken Fox, P6I
At 11:25 AM +0100 9/18/02, Graham Barr wrote:
>On Wed, Sep 18, 2002 at 10:15:20AM +0200, Dan Sugalski wrote:
>> I've been thinking that we do need to have an extra flag to note
>> whether a key element should be taken as an array or hash lookup
>> element. The integer 1 isn't quite enough, since someone may have
>> done a %foo{1} and we only have that in as an integer key.
>
>I agree. Using integer key == array and string key == hash is not
>enough imo. What about a hash that is index by object, not a string.
>What about an array that is index by strings ? ie
>
> my @array is indexed('a'..'z');
>
>So if parrot wants to provide a method for compound keys, then the
>HL should be able to specify what type it is expecting each level
>to be.
>
>But the question also exists how this flag should be used/checked.

The variable itself is responsible for checking at runtime, though we
can and will do compile-time checking when we can. Since it's a flag
in the key, it's passed into the variable's vtable method, and there
to check if it chooses. (Which it ought, in most cases)

0 new messages