I am wondering how the references to hash elements are planned to be done? The call to set_ must somehow be delayed until the time is right.
$foo = \$hash{key};
$$foo = "bar";
$has{key} is now "bar"
I don't see how the current vtable setup will allow for this in a tied situation, or will a tied hash just return a hashelement pmc type that will do the call later on?
On another note, is there going to be a PMC flag for tainted data?
Arthur
ps, please respond to both ponie-dev and perl6-internals
> I am wondering how the references to hash elements are planned to be > done? The call to set_ must somehow be delayed until the time is right.
I would have thought that a hash element would itself be a PMC rather than an immediate value, so a reference to that should be treated just like any other reference to a PMC.
-- Ever wake up feeling like a null pointer? -Allan Pratt
Arthur Bergman <s...@nanisky.com> wrote: > Hi, > I am wondering how the references to hash elements are planned to be > done? The call to set_ must somehow be delayed until the time is right. > $foo = \$hash{key}; > $$foo = "bar"; > $has{key} is now "bar"
There was some discussion WRT that issue months ago. Currently the implementation is wrong IMHO. When $hash{key} doesn't exist a new PerlUndef is returned (which is fine) but it should be stored in the hash too, so that assigning to $foo does The Rigth Thing. (Parrot aggregates have reference semantics, so ...)
> On another note, is there going to be a PMC flag for tainted data?
I can imagine, that these get a different vtable which propagates taintness on.
> Arthur Bergman: >> I am wondering how the references to hash elements are planned to be >> done? The call to set_ must somehow be delayed until the time is >> right.
> I would have thought that a hash element would itself be a PMC rather > than an immediate value, so a reference to that should be treated just > like any other reference to a PMC.
But there's a semantic difference between a "reference to a hash element" and a "reference to something which happens to have come out of a hash". Consider:
Examples 1 and 2 should be identical in terms of what $a and $b contain; in particular, modifying $b doesn't affect the hash in example 2. In example 3, $b contains something different (a hash element reference), and assigning to it does change the hash. (That is, assuming we have hash element references of this sort.) That is to say, reference-to-hash-element-for-key(bar) is not the same as reference-to(hash-element-for-key(bar)).
> But there's a semantic difference between a "reference to a hash > element" and a "reference to something which happens to have come out > of a hash".
True, but irrelevant. :)
> $a = $hash{bar};
Here you used the copy constructor before taking the reference. It might look like an assignment operator, but it isn't. You're better off thinking that assignment doesn't exist. It's a copy constructor. It makes the PMC referred to by $a a copy of the PMC in $hash{bar}. Their values may be "equal" but they're two different PMCs.
> $b = \$hash{bar};
Here you didn't make a copy before taking the reference. No copy, only one PMC. It all works.
-- BITTERNESS: Never be Afraid to Share Your Dreams with the World, Because there's Nothing the World Loves More Than The Taste of Really Sweet Dreams http://www.despair.com
> Here you used the copy constructor before taking the reference. It might look > like an assignment operator, but it isn't. You're better off thinking that > assignment doesn't exist. It's a copy constructor. It makes the PMC referred > to by $a a copy of the PMC in $hash{bar}. Their values may be "equal" but > they're two different PMCs.
> > $b = \$hash{bar};
> Here you didn't make a copy before taking the reference. No copy, only one > PMC. It all works.
Indeed, and this separate PMC is probably the best way to think about it, since we have in Perl 6:
$a := %hash{bar};
The operator C<:=> is just like a PMC C<set> as opposed to an C<assign>. If, after this statement, one says:
$a = "baz";
One should expect that C<%hash{bar}> would turn into "baz";
> I would have thought that a hash element would itself be a PMC rather > than an immediate value, so a reference to that should be treated just > like any other reference to a PMC.
But this does not hold true if the hash element is in fact conjured up by a call to STORE
> >I would have thought that a hash element would itself be a PMC rather > >than an immediate value, so a reference to that should be treated just > >like any other reference to a PMC.
> But this does not hold true if the hash element is in fact conjured up > by a call to STORE
Ahh, touché. Well, it wouldn't be so hard to write a Proxy pmc which is constructed with an aggregate and a key, and delegates its assignments and fetches to the aggregate itself.
>I am wondering how the references to hash elements are planned to be >done? The call to set_ must somehow be delayed until the time is >right.
Nope, actually they don't have to be. Simon was correct here. Accessing an element of an aggregate returns the PMC pointer of the thing in that slot. If the aggregate itself does Magic Things when something is fetched out of it, the PMC it returns should be one that does the appropriate slot-specific Magic Thing when accessed.
Assuming,for all the future examples, that %foo is a Magic Hash (and we're using Perl 6 syntax), this:
%foo{bar}
should return a PMC (which is then discarded) that would give you whatever value you'd get from the bar slot of the %foo hash.
Since assignment is really copying, this:
$baz = %foo{bar};
fetches a PMC that does magic things out of %foo, extracts the value (presumably non-magic) out of it, and assigns that value to $baz. (Which itself might have Magic on it, but we're not going there right now) At the end of the statement the Magic PMC goes away. (give or take a bit with DOD runs)
This, on the other hand:
$baz = \%foo{bar};
gets the magic PMC out of %foo, then takes a reference to it. That reference goes into $baz, and the magic PMC fails to go away.
Now, what happens when you fetch the value out of that referred-to magic PMC? Well... that depends. Probably the identical same thing that would happen in the assign case, but whoever writes the class for %foo that builds the magic PMCs that get returned needs to do the right thing and put enough state information into the pmc to return the data properly.
It would, however, *also* be perfectly appropriate to have the value returned from %foo{bar} to *not* be magic, and in fact be a plain old PMC, in which case multiple accesses to it will return the same static data.
Depends on how the class wants to handle things, really. -- Dan
--------------------------------------"it's like this"------------------- Dan Sugalski even samurai d...@sidhe.org have teddy bears and even teddy bears get drunk
[ apologies for the duplicate email message from my last post--mail client problems... ]
On Jan 6, 2004, at 11:50 AM, Simon Cozens wrote:
> Jeff Clites: >> $a = $hash{bar};
> Here you used the copy constructor before taking the reference. It > might look > like an assignment operator, but it isn't. You're better off thinking > that > assignment doesn't exist. It's a copy constructor. It makes the PMC > referred > to by $a a copy of the PMC in $hash{bar}. Their values may be "equal" > but > they're two different PMCs.
But here what I'm copying is the _contents_ of the hash slot--so I'm copying a PerlString PMC, for instance.
>> $b = \$hash{bar};
> Here you didn't make a copy before taking the reference. No copy, only > one > PMC. It all works.
And here I'm not making a copy, but also the thing I'm taking a reference to is not the same thing I copied above. Here, it's a reference to a hash slot.
So maybe the way to think about it is:
$a = $hash{bar}; #This finds the hash slot, pulls out its contents, and copies that contents into $a.
$b = \$hash{bar}; #This finds the hash slot, takes a reference to it, and places that reference in $b.
So the first case involves copying a string, and the second involves creating a reference to a hash slot. In particular, if the hash is initially empty, the first case should end up with undef in $a (so nothing actually copied, if undef is a singleton), but $b would (presumably) still contain a real reference (to a hash slot which doesn't contain anything yet), which would create a hash entry if you "$$b = 'goo'". And that reference-to-a-hash-slot is probably a separate special PMC (it needs to keep track of the hash and key, and work even if the hash is empty).
>> I am wondering how the references to hash elements are planned to be >> done? The call to set_ must somehow be delayed until the time is >> right.
>> $foo = \$hash{key};
>> $$foo = "bar";
>> $has{key} is now "bar"
> There was some discussion WRT that issue months ago. Currently the > implementation is wrong IMHO. When $hash{key} doesn't exist a new > PerlUndef is returned (which is fine) but it should be stored in the > hash too, so that assigning to $foo does The Rigth Thing. > (Parrot aggregates have reference semantics, so ...)
This may have been discussed previously, but I would think that reading a hash should never auto-vivify elements. (That would be contrary to the Perl5 semantics, at least.) You may need to return a special reference-style PMC which knows how to get back to the original hash if you assign to it, but the hash itself shouldn't grow entries.
> But here what I'm copying is the _contents_ of the hash slot.
True, but irrelevant. :)
> And here I'm not making a copy, but also the thing I'm taking a > reference to is not the same thing I copied above. Here, it's a > reference to a hash slot.
No, it isn't. It's a reference to a PMC. The fact that that PMC happens to be pointed to by a hash key is incidental. It's still just another PMC. No special case at all.
-- emacs: Terminal type "emacs" is not powerful enough to run Emacs.
> Jeff Clites: >> But here what I'm copying is the _contents_ of the hash slot.
> True, but irrelevant. :)
>> And here I'm not making a copy, but also the thing I'm taking a >> reference to is not the same thing I copied above. Here, it's a >> reference to a hash slot.
> No, it isn't. It's a reference to a PMC. The fact that that PMC happens > to be pointed to by a hash key is incidental. It's still just another > PMC. > No special case at all.
Oh, I see what you are saying. I was misinterpreting what \$hash{bar} is supposed to do. (I was thinking there was supposed to be some new way to reference a hash slot, such that assigning to the reference [or dereferencing and assigning] would be equivalent to using $hash{bar} as an l-value.)
(But saying something is a PMC doesn't clarify anything--basically everything ends up being a PMC. PerlStrings are PMCs, hashes are PMCs; we have reference PMCs.... If we had a reference-to-a-hash-slot, that would be a PMC also probably. So your original post threw me off track when you referred to "a PMC rather than an immediate value".)
Arthur Bergman <s...@nanisky.com> wrote: > Hi, > I am wondering how the references to hash elements are planned to be > done? The call to set_ must somehow be delayed until the time is right.
Here is a pointer to the last discussion on that topic:
Date: Thu, 21 Aug 2003 17:50:00 +0200 From: Leopold Toetsch <l.toet...@nextra.at> Subject: PerlHash.get_pmc_keyed of non existing key
>>>I am wondering how the references to hash elements are planned to be >>>done? The call to set_ must somehow be delayed until the time is right.
>>>$foo = \$hash{key};
>>>$$foo = "bar";
>>>$has{key} is now "bar"
>>There was some discussion WRT that issue months ago. Currently the >>implementation is wrong IMHO. When $hash{key} doesn't exist a new >>PerlUndef is returned (which is fine) but it should be stored in the >>hash too, so that assigning to $foo does The Rigth Thing. >>(Parrot aggregates have reference semantics, so ...)
>This may have been discussed previously, but I would think that >reading a hash should never auto-vivify elements.
This is entirely a matter of opinion and data design -- both options are reasonable, and would depend entirely on the definitions imposed by the language (if they're core data elements) or the class author (if they're not). -- Dan
--------------------------------------"it's like this"------------------- Dan Sugalski even samurai d...@sidhe.org have teddy bears and even teddy bears get drunk
Dan Sugalski <d...@sidhe.org> wrote: > This is entirely a matter of opinion and data design ...
Yep, that's it. The current behavior additionally is inconsistent. Retrieving a reference (that is Parrot) out of a non-existant hash key gives and unrelated new PerlUndef, when assigning to that, nothing happens.
When you get a ref by an existing key, you can happily change data inside the hash.
I've refered to the subject of the former thread, there are examples.
So what will/should Parrot provide, to solve that?
IMHO we are additionally lacking vtable methods to achieve the HLL value assign behavior: We only have references inside our aggregates. That doesn't matter per se, you can always clone the PMCs before storing, or you store only newly created PMCs, that's ok, but in the case of retrieving a reference or a value from an hash with an unexisting key, it would matter, the one does autovifiy the latter doesn't.
Paul Johnson <p...@pjcj.net> wrote: > Leopold Toetsch said:
>> IMHO we are additionally lacking vtable methods to achieve the HLL value >> assign behavior: We only have references inside our aggregates. That >> doesn't matter per se, you can always clone the PMCs before storing, or >> you store only newly created PMCs, that's ok, but in the case of >> retrieving a reference or a value from an hash with an unexisting key, >> it would matter, the one does autovifiy the latter doesn't. > I wonder whether this message from Larry might be useful? > http://www.mail-archive.com/perl6-langu...@perl.org/msg14525.html
Simon Cozens <si...@simon-cozens.org> writes: > Arthur Bergman: >> I am wondering how the references to hash elements are planned to be >> done? The call to set_ must somehow be delayed until the time is right.
> I would have thought that a hash element would itself be a PMC rather > than an immediate value, so a reference to that should be treated just > like any other reference to a PMC.
I believe the correct name for this is 'Pair' isn't it?