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.
>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
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.
>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. -- Dan
--------------------------------------"it's like this"------------------- Dan Sugalski even samurai d...@sidhe.org have teddy bears and even teddy bears get drunk
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.
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.
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: >>>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.
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);
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.
>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.
-- Dan
--------------------------------------"it's like this"------------------- Dan Sugalski even samurai d...@sidhe.org have teddy bears and even teddy bears get drunk
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.)
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.
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!".
>>>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!".
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. -- Dan
--------------------------------------"it's like this"------------------- Dan Sugalski even samurai d...@sidhe.org have teddy bears and even teddy bears get drunk
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.
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.
>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) -- Dan
--------------------------------------"it's like this"------------------- Dan Sugalski even samurai d...@sidhe.org have teddy bears and even teddy bears get drunk