[RFC][VOTE] Objects as Keys

php.internals

Stas Malyshev

11 years ago
Hi! I'd like to initiate a vote on "objects as keys" RFC: https://wiki.php.net/rfc/objkey I know this is a holiday season but it was extensively discussed and I think most people already formed their opinions. I've put the voting period as 3 weeks to have some time for people to vote even with the holidays, etc. The vote includes choice for the name. Vote for either name is counted as the vote for the overall proposal, and 2/3 majority is required as it's a language change. Some more expanded summary of the arguments is here: http://php100.wordpress.com/2014/12/14/objects-as-keys/ in case you're interested.
-- Stas Malyshev smalyshev@gmail.com

Markus Fischer

11 years ago
On 16.12.14 09:34, Stanislav Malyshev wrote:
> I'd like to initiate a vote on "objects as keys" RFC: > https://wiki.php.net/rfc/objkey
Am I right this only covers the transformation into the array. Once it's in it's essential a array compatible key entity (string/integer) so when you var_dump($array) you only get the values of a hash. In other words: it would not be possible to actually get the object from the key, just this string/integer which is supposed to reference it? thanks, - Markus

Andrew Faulds

11 years ago
Hi Markus,
> On 16 Dec 2014, at 10:31, Markus Fischer <markus@fischer.name> wrote: > > On 16.12.14 09:34, Stanislav Malyshev wrote: >> I'd like to initiate a vote on "objects as keys" RFC: >> https://wiki.php.net/rfc/objkey > > Am I right this only covers the transformation into the array. Once it's > in it's essential a array compatible key entity (string/integer) so when > you var_dump($array) you only get the values of a hash. > > In other words: it would not be possible to actually get the object from > the key, just this string/integer which is supposed to reference it?
Exactly. If I were to do this: <?php class Foo { public $foo; function __construct($foo) { $this->foo = $foo; } function __toKey() { return $this->foo; } } $arr = []; $arr[] = new Foo(1); var_dump($arr); I would get this: array(1) { [0]=> int(1) } This is the main problem with the RFC: magic, implicit, one-way data loss (object to integer/string). I was previously in favour of this, but it’d prevent actual indexing by objects in future, and I can’t think of any use cases which aren’t better solved by explicitly converting to a string/integer. Thanks.
-- Andrea Faulds http://ajf.me/

Andrew Faulds

11 years ago
> > On 16 Dec 2014, at 10:52, Andrea Faulds <ajf@ajf.me> wrote: > > Exactly. If I were to do this: > > <?php > class Foo { > public $foo; > function __construct($foo) { > $this->foo = $foo; > } > function __toKey() { > return $this->foo; > } > } > $arr = []; > $arr[] = new Foo(1); > var_dump($arr); > > I would get this: > > array(1) { > [0]=> > int(1) > }
Er, a correction… the example should’ve been something like this: $arr = []; $arr[new Foo(1)] = NULL; Producing this: array(1) { [1]=> NULL } Obviously, it has no effect on values, only keys, sorry!
-- Andrea Faulds http://ajf.me/

Guilherme Blanco

11 years ago
Hi, All I can say is that the lack of this feature is one of the main reasons why Doctrine doesn't fully work with composite keys. With this enhancement it would now become possible to implement a proper IdentityMap. []s, On Dec 16, 2014, at 9:05 AM, Andrea Faulds <ajf@ajf.me> wrote:

Matteo Beccati

11 years ago
Hi Guilherme, On 16/12/2014 12:34, Guilherme Blanco wrote:
> Hi, > > All I can say is that the lack of this feature is one of the main reasons why Doctrine doesn't fully work with composite keys. > With this enhancement it would now become possible to implement a proper IdentityMap.
Are you sure you haven't misinterpreted the RFC? Cheers
-- Matteo Beccati Development & Consulting - http://www.beccati.com/

Matteo Beccati

11 years ago
On 16/12/2014 11:52, Andrea Faulds wrote:
> This is the main problem with the RFC: magic, implicit, one-way data > loss (object to integer/string). > > I was previously in favour of this, but it’d prevent actual indexing > by objects in future, and I can’t think of any use cases which aren’t > better solved by explicitly converting to a string/integer.
That's precisely the same reason why I voted Nay. And I wouldn't have been able to put it down in words better than Andrea did. Cheers
-- Matteo Beccati Development & Consulting - http://www.beccati.com/

Patrick Schaaf

11 years ago
Am 16.12.2014 12:36 schrieb "Matteo Beccati" <php@beccati.com>:
> > On 16/12/2014 11:52, Andrea Faulds wrote: >> >> I was previously in favour of this, but it’d prevent actual indexing >> by objects in future, and I can’t think of any use cases which aren’t >> better solved by explicitly converting to a string/integer. > > That's precisely the same reason why I voted Nay. And I wouldn't have
been able to put it down in words better than Andrea did. That was my thought initially, too. But I think it is wrong. If PHP ever gets around to provide objects-themselves-as-array-keys support, it can easily do that 1) only if the object does not have such a __toKey() method, or 2) if the object has one, but it returns the object itself (which is forbidden now by the RFC) best regards Patrick

Rowan Collins

11 years ago
Patrick Schaaf wrote on 16/12/2014 11:46:
> Am 16.12.2014 12:36 schrieb "Matteo Beccati" <php@beccati.com>: >> On 16/12/2014 11:52, Andrea Faulds wrote: >>> I was previously in favour of this, but it’d prevent actual indexing >>> by objects in future, and I can’t think of any use cases which aren’t >>> better solved by explicitly converting to a string/integer. >> That's precisely the same reason why I voted Nay. And I wouldn't have > been able to put it down in words better than Andrea did. > > That was my thought initially, too. But I think it is wrong. If PHP ever > gets around to provide objects-themselves-as-array-keys support, it can > easily do that > > 1) only if the object does not have such a __toKey() method, or > 2) if the object has one, but it returns the object itself (which is > forbidden now by the RFC)
Hm, that's an interesting thought. My thought had been that an object-as-key would need to specify its hash anyway, so that two objects of the same "value" would be automatically de-duped, just as two strings are. But I guess an internally unique handle for the specific object would also be a reasonable approach for some uses. Perhaps like with Traversable, we could have a set of magic interfaces (although I'm struggling to think of names for them, which may be a bad sign): a) an "abstract" base interface meaning "can be used as $bar in $foo[$bar]"; like Traversable, this would not actually be implementable directly, but be the parent of the following b) an interface for objects which produce a one-way hash to use as the key (as in the current proposal) c) an interface for objects which can themselves be stored as the key, with internally unique handle as identifier d) an interface for objects which can themselves be stored as the key, but with a custom "value" used as the identifier This sounds complex, but wouldn't necessarily be. (c) is just a special case of (d) with an implied default implementation of the value method. And if the structure of the HashTable retained the index/key structure we have now, but with the object pointer as an additional field, the pseudo-code when an object was encountered in array-key context would be: if $obj has interface (a) then . if $obj has interface (c) then . . key := get_internal_identifier($obj) . . else key := $obj->getHash() // this covers (b) and (d) . end . store value against key . if $obj has interface (c) or (d) then store additional pointer to original object else throw error end Importantly, the current proposal could be re-cast as an implementation of interface (b) while neither promising nor ruling out (c) and/or (d).
-- Rowan Collins [IMSoP]

Florian Margaine

11 years ago
Hi, Le 16 déc. 2014 13:45, "Rowan Collins" <rowan.collins@gmail.com> a écrit :
> > Patrick Schaaf wrote on 16/12/2014 11:46: > >> Am 16.12.2014 12:36 schrieb "Matteo Beccati" <php@beccati.com>: >>> >>> On 16/12/2014 11:52, Andrea Faulds wrote: >>>> >>>> I was previously in favour of this, but it’d prevent actual indexing >>>> by objects in future, and I can’t think of any use cases which aren’t >>>> better solved by explicitly converting to a string/integer. >>> >>> That's precisely the same reason why I voted Nay. And I wouldn't have >> >> been able to put it down in words better than Andrea did. >> >> That was my thought initially, too. But I think it is wrong. If PHP ever >> gets around to provide objects-themselves-as-array-keys support, it can >> easily do that >> >> 1) only if the object does not have such a __toKey() method, or >> 2) if the object has one, but it returns the object itself (which is >> forbidden now by the RFC) > > > Hm, that's an interesting thought. My thought had been that an
object-as-key would need to specify its hash anyway, so that two objects of the same "value" would be automatically de-duped, just as two strings are. But I guess an internally unique handle for the specific object would also be a reasonable approach for some uses. Just a random thought: the `__hash` method can just `return spl_object_hash($this);` to have an object id.
> -- > Rowan Collins > [IMSoP] > > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php >
Cheers, Florian Margaine

Stas Malyshev

11 years ago
Hi!
> I was previously in favour of this, but it’d prevent actual indexing
No, of course it won't - if we ever introduce indexing objects (which probably will require rewrite of the HashTable, any takers?) it would be very easy to index any object that does not implement __hash without any BC problem, and convert all those implementing __hash to "return $this" if desired.
> by objects in future, and I can’t think of any use cases which > aren’t better solved by explicitly converting to a string/integer.
There's no implicit conversion, and explicit one is a) inacessible in userspace for anything but string and b) annoying for the same reasons for which __toString exists.
-- Stas Malyshev smalyshev@gmail.com

Rowan Collins

11 years ago
On 16 December 2014 18:14:27 GMT, Stanislav Malyshev <smalyshev@gmail.com> wrote:
>Hi! > >> I was previously in favour of this, but it’d prevent actual indexing > >No, of course it won't - if we ever introduce indexing objects (which >probably will require rewrite of the HashTable, any takers?) it would >be >very easy to index any object that does not implement __hash without >any >BC problem, and convert all those implementing __hash to "return $this" >if desired. > >> by objects in future, and I can’t think of any use cases which >> aren’t better solved by explicitly converting to a string/integer. > >There's no implicit conversion, and explicit one is a) inacessible in >userspace for anything but string and b) annoying for the same reasons >for which __toString exists.
Explicit conversion is trivial, just call whatever method you like. Sure, you can't write (int)$obj, but $obj->toInt() is just as expressive.

Stas Malyshev

11 years ago
Hi!
> Explicit conversion is trivial, just call whatever method you like. > Sure, you can't write (int)$obj, but $obj->toInt() is just as > expressive.
Exactly the same applies to __toString and whole ArrayAccess, yet we still have them. Avoiding boilerplate code helps. Especially if boilterplate code would look like: if(is_object($foo)) { $foo_key = $foo->toInt(); } else { $foo_key = $foo; } $a[$foo] = 1; Doing it each time is annoying.
-- Stas Malyshev smalyshev@gmail.com

Rowan Collins

11 years ago
On 16 December 2014 18:50:06 GMT, Stanislav Malyshev <smalyshev@gmail.com> wrote:
>Hi! > >> Explicit conversion is trivial, just call whatever method you like. >> Sure, you can't write (int)$obj, but $obj->toInt() is just as >> expressive. > >Exactly the same applies to __toString and whole ArrayAccess, yet we >still have them. Avoiding boilerplate code helps. Especially if >boilterplate code would look like: > >if(is_object($foo)) { > $foo_key = $foo->toInt(); >} else { > $foo_key = $foo; >} >$a[$foo] = 1; > >Doing it each time is annoying.
I was just confused by your statement that "explicit conversion is inacessible from userspace". But yeah, I guess with string keys you can just write $a[(string)$foo] and assume/hope it will do something meaningful whatever the type of $foo.

Guilherme Blanco

11 years ago
> On Tue, Dec 16, 2014 at 9:39 AM, Matteo Beccati <php@beccati.com>
wrote:Hi Guilherme,
> >> On 16/12/2014 12:34, Guilherme Blanco wrote: >> Hi, >> All I can say is that the lack of this feature is one of the main
reasons why Doctrine doesn't fully work with composite keys.
>> With this enhancement it would now become possible to implement a proper
IdentityMap.
> >Are you sure you haven't misinterpreted the RFC?
Hi Matteo, I did not. You may think I mentioned IdentityMap as entity map, but I'm talking about entityPersister mapping or resultPointers consumptions that happens inside Doctrine throughout the execution. Entity IdentityMap is enough to use purely spl_object_hash(). We should focus on the main goal here, which is complex structures as keys. As a very complex library developer I do see lots of use cases for this. []s, On Tue, Dec 16, 2014 at 6:52 PM, Rowan Collins <rowan.collins@gmail.com> wrote:
> > On 16 December 2014 18:50:06 GMT, Stanislav Malyshev <smalyshev@gmail.com> > wrote: > >Hi! > > > >> Explicit conversion is trivial, just call whatever method you like. > >> Sure, you can't write (int)$obj, but $obj->toInt() is just as > >> expressive. > > > >Exactly the same applies to __toString and whole ArrayAccess, yet we > >still have them. Avoiding boilerplate code helps. Especially if > >boilterplate code would look like: > > > >if(is_object($foo)) { > > $foo_key = $foo->toInt(); > >} else { > > $foo_key = $foo; > >} > >$a[$foo] = 1; > > > >Doing it each time is annoying. > > I was just confused by your statement that "explicit conversion is > inacessible from userspace". But yeah, I guess with string keys you can > just write $a[(string)$foo] and assume/hope it will do something meaningful > whatever the type of $foo. > > > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >
-- Guilherme Blanco MSN: guilhermeblanco@hotmail.com GTalk: guilhermeblanco Toronto - ON/Canada

Christoph Becker

11 years ago
guilhermeblanco@gmail.com wrote:
> On Tue, Dec 16, 2014 at 9:39 AM, Matteo Beccati <php@beccati.com> > wrote: > >> Are you sure you haven't misinterpreted the RFC? > > I did not. You may think I mentioned IdentityMap as entity map, but I'm > talking about entityPersister mapping or resultPointers consumptions that > happens inside Doctrine throughout the execution. Entity IdentityMap is > enough to use purely spl_object_hash(). We should focus on the main goal > here, which is complex structures as keys. > > As a very complex library developer I do see lots of use cases for this.
AIUI, this RFC is meant to introduce some sugar only. Wouldn't it be possible to have object hashes without __hash(), by introducing a respective interface (maybe "Hashable" or "Identifiable") and requiring the appropriate classes to implement this interface?
-- Christoph M. Becker

Stas Malyshev

11 years ago
Hi!
> AIUI, this RFC is meant to introduce some sugar only. Wouldn't it be
I'm not sure what you mean by "some sugar only". It introduces the capability of using objects in array key context, which was not available until now.
> possible to have object hashes without __hash(), by introducing a > respective interface (maybe "Hashable" or "Identifiable") and requiring > the appropriate classes to implement this interface?
It's possible and essentially the same, replacing magic method (which is how things were done in PHP since forever until now) with interface - which probably would be slower to check, would still require dedicated method name, probably starting with __, and will essentially do the same.
-- Stas Malyshev smalyshev@gmail.com

Derick Rethans

11 years ago
On Tue, 16 Dec 2014, Stanislav Malyshev wrote:
> I'd like to initiate a vote on "objects as keys" RFC: > https://wiki.php.net/rfc/objkey
I wonder why you opened voting on this, before resolving the "Open Issues": Open Issues Should SplFixedArray support object indexes? Should SplObjectStorage support calling __hash for an object if it exists? cheers, Derick

Guilherme Blanco

11 years ago
Hi, Answering the question of Christopher Becker. It is not possible to traverse and get your desired elements. How would you achieve a foreach by key (returning object) without having to store a separate list and track by hash or through an interface? Cheers, On Wed, Dec 17, 2014 at 10:04 AM, Derick Rethans <derick@php.net> wrote:
> > On Tue, 16 Dec 2014, Stanislav Malyshev wrote: > > > I'd like to initiate a vote on "objects as keys" RFC: > > https://wiki.php.net/rfc/objkey > > I wonder why you opened voting on this, before resolving the "Open > Issues": > > Open Issues > > Should SplFixedArray support object indexes? > Should SplObjectStorage support calling __hash for an object if it > exists? > > cheers, > Derick > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >
-- Guilherme Blanco MSN: guilhermeblanco@hotmail.com GTalk: guilhermeblanco Toronto - ON/Canada

Christoph Becker

11 years ago
guilhermeblanco@gmail.com wrote:
> Answering the question of Christopher Becker. It is not possible to > traverse and get your desired elements. > How would you achieve a foreach by key (returning object) without having to > store a separate list and track by hash or through an interface?
AIUI, the RFC proposes that __hash() returns a string or an int, and this value (not the object itself) will be stored and retrieved as key of the array. <https://wiki.php.net/rfc/objkey#proposal>: | Create a new magic method, __hash() which is called when object is | supplied as a hash key, and returns string or integer that is used as | the hash key.
-- Christoph M. Becker

Etienne Kneuss

11 years ago
On Wed Dec 17 2014 at 1:44:13 PM guilhermeblanco@gmail.com < guilhermeblanco@gmail.com> wrote:
> Hi, > > Answering the question of Christopher Becker. It is not possible to > traverse and get your desired elements. > How would you achieve a foreach by key (returning object) without having to > store a separate list and track by hash or through an interface? > >
Which is one of the main problem with this very RFC. What ends up being stored in the array is the hash, not the object. And there is no immediate way of getting the key object back. The user writes: $arr = array($obj => 2); but key($arr) returns the hash only. As I said in the original discussion: this RFC is actually about having an implicit call to __hash() whenever an object is used as an array key. You can achieve exactly the same in userland with an explicit call. I would rather wait (maybe indefinitely) to have a proper implementation of objects as keys than have this compromise. Best,

Stas Malyshev

11 years ago
Hi!
> As I said in the original discussion: this RFC is actually about having > an implicit call to __hash() whenever an object is used as an array key. > You can achieve exactly the same in userland with an explicit call.
It's like nobody have ever seen __toString before... Of course you can do that 10-line boilerplate that Rowan outlined. The whole point of this RFC is so you don't have to do the boilerplate.
> I would rather wait (maybe indefinitely) to have a proper implementation > of objects as keys than have this compromise.
I have hard time to understand this - it's like somebody offering to give you $100, with no conditions, and you say "no, I'd rather wait for somebody giving me a billion dollars, until then I won't take the $100". Having object as keys does not contradict this RFC in any way - though the probability of it happening in PHP 7 is pretty much nil so you'd have to wait at least several years, but most probably - forever. So you pretty much choosing to have nothing over having something with no upside at all. Why?
-- Stas Malyshev smalyshev@gmail.com

Levi Morrison

11 years ago
This RFC proposes that we store the hash of an object instead of the actual object. That's simply not useful to me and likely prevents us from adding support for objects as keys in the future should we want it. In addition, it adds yet another behavior to arrays which do so many things already. I would much rather have structures that focus on narrow responsibilities and do that well, such as an improved Map structure instead of SplObjectStorage. This isn't some pie-in-the-sky wishing, either; I've been working on this for years now in my spare time.

Stas Malyshev

11 years ago
Hi!
> This RFC proposes that we store the hash of an object instead of the > actual object. That's simply not useful to me
Fair enough, but this is not only about what is useful personally to you.
> and likely prevents us > from adding support for objects as keys in the future should we want
No it does not. It was already explained several times. If it is ever introduced, it can be used for objects that do not explicitly request functionality in this RFC by enabling __hash() with no BC issues, since this RFC only affects classes that explicitly ask for this specific functionality. So if you, according to the above, would never use __hash, absolutely nothing would prevent you from using objects as keys if it ever happens (which it probably won't in the next 2-3 years).
> In addition, it adds yet another behavior to arrays which do so many > things already. I would much rather have structures that focus on
It's exactly the same behavior, just available for select objects now. Arrays don't do anything new, they still store key/value pairs, objects do something new to enable you doing more things with value objects.
> I would much rather have structures that focus on
narrow responsibilities and do that well, such as an improved Map structure instead of SplObjectStorage Nothing in this RFC prevents you from having such structures. In fact, this RFC would enable more convenient handling of such structures, providing common method for requesting the programmable hash value of the object - a feature which most languages have, but PHP does not.
-- Stas Malyshev smalyshev@gmail.com

Levi Morrison

11 years ago
>> and likely prevents us >> from adding support for objects as keys in the future should we want > > No it does not. It was already explained several times. If it is ever > introduced, it can be used for objects that do not explicitly request > functionality in this RFC by enabling __hash() with no BC issues, since > this RFC only affects classes that explicitly ask for this specific > functionality. So if you, according to the above, would never use > __hash, absolutely nothing would prevent you from using objects as keys > if it ever happens (which it probably won't in the next 2-3 years).
Just because you say it doesn't affect it doesn't mean it doesn't. I think it would be quite silly to support storing hashes and/or storing objects and to me that blocks the latter since you are proposing the former.
> Nothing in this RFC prevents you from having such structures. In fact, > this RFC would enable more convenient handling of such structures, > providing common method for requesting the programmable hash value of > the object - a feature which most languages have, but PHP does not.
Programmable hashes of objects should be external to the object anyway because eventually someone wants to store the same object in a different way in two different structures.

Stas Malyshev

11 years ago
Hi!
> Just because you say it doesn't affect it doesn't mean it doesn't. I > think it would be quite silly to support storing hashes and/or storing > objects and to me that blocks the latter since you are proposing the > former.
I don't know why you think it's "quite silly" to have both scalar and object keys, as that's exactly what would you need to implement with you want object keys - scalar keys are not going to go anywhere. So your assumption that this RFC somehow blocks objects as keys is still wrong.
> Programmable hashes of objects should be external to the object anyway > because eventually someone wants to store the same object in a > different way in two different structures.
That is the requirement that no language I can think of implements - Java, Python, Ruby, C# all have programmatic hash method, and none of them changes it for different structures.
-- Stas Malyshev smalyshev@gmail.com

Levi Morrison

11 years ago
>> Programmable hashes of objects should be external to the object anyway >> because eventually someone wants to store the same object in a >> different way in two different structures. > > That is the requirement that no language I can think of implements - > Java, Python, Ruby, C# all have programmatic hash method, and none of > them changes it for different structures.
C++ commonly does this. You pass a "hash function" as a template or constructor argument and use that for the structure. Additionally, this allows you to easily support types that don't natively provide internal hashing functions (such as objects from a third party library). In this case, doing it like Java, C# et al is an example of most languages getting it wrong, not them getting it right.

Rowan Collins

11 years ago
On 17/12/2014 17:03, Stanislav Malyshev wrote:
> Hi! > >> As I said in the original discussion: this RFC is actually about having >> an implicit call to __hash() whenever an object is used as an array key. >> You can achieve exactly the same in userland with an explicit call. > It's like nobody have ever seen __toString before... Of course you can > do that 10-line boilerplate that Rowan outlined. The whole point of this > RFC is so you don't have to do the boilerplate.
Just to clarify, I in no way wanted to say that reducing that boilerplate was not a good thing. I was responding to the concept that this allows things which weren't previously possible. I definitely think syntactic sugar can be a good thing, and can see the advantage of this proposal.
>> I would rather wait (maybe indefinitely) to have a proper implementation >> of objects as keys than have this compromise. > I have hard time to understand this - it's like somebody offering to > give you $100, with no conditions, and you say "no, I'd rather wait for > somebody giving me a billion dollars, until then I won't take the $100". > Having object as keys does not contradict this RFC in any way - though > the probability of it happening in PHP 7 is pretty much nil so you'd > have to wait at least several years, but most probably - forever. So you > pretty much choosing to have nothing over having something with no > upside at all. Why?
Yes, there are versions of objects-as-keys which are compatible with this proposal; however, there are also versions which are not. For instance, without this proposal we could implement something so that *for any object*, $foo[$obj] = 42 stores the object as the key. If this RFC is already in place, then any object which uses __hash (or whatever name we give it) to return a scalar key cannot also be used in that way. That may not be a big deal - the creator of the object can choose which behaviour to use - but the creator of the containing structure couldn't, which might be a nuisance. I guess the other way in which it reduces the chance of a more "complete" solution is a psychological one - once this is in there, the number of cases that need object-as-key support will be even lower, leaving those that aren't served by this version less likely to be approached. I'm on the fence on this one. For one thing, I think it might be interesting to explore whether real objects as keys is actually as difficult as some people are assuming. I can naively imagine a few ways it could be implemented that seem in my mind to have minimal impact on any array that doesn't use it, but haven't yet seen anyone seriously discuss any possible approaches.
-- Rowan Collins [IMSoP]

Rowan Collins

11 years ago
On 17/12/2014 22:05, Rowan Collins wrote:
> For one thing, I think it might be interesting to explore whether real > objects as keys is actually as difficult as some people are assuming. > I can naively imagine a few ways it could be implemented that seem in > my mind to have minimal impact on any array that doesn't use it, but > haven't yet seen anyone seriously discuss any possible approaches.
In fact, to expand on this, I'm going to stick my neck out and tell everyone my crackpot theory, which someone who actually understands the engine will probably demolish in 5 seconds flat, but makes sense in my mind. :P The implementation of arrays could remain the same, with a single pointer to a second "shadow" HashTable, which would only be initialised when an object was actually added as a key. Thus the memory overhead would be reserving a single pointer per array (not per item), and the execution overhead (for any existing array usage) would be a single if(shadowPointer) check in a few key places. The idea would be that the object would still be hashed - e.g. by default with spl_object_hash, but with __hash if set - and that key would be stored in the normal way. However, an extra entry would be added to the shadow array, as though you had also called $shadow[ $obj->__hash() ] = $obj. We might want to do something tricksy to the key, like adding a null byte at the beginning, to make it less likely for a scalar key and an object hash to collide. This would also allow further short-cutting in lookups, since if the first byte was not \0, there would be no chance of a match in the shadow array. (If it was \0, there might still not be a shadow object, because null-prefixed strings are actually valid scalar keys, but this seems unlikely to be a common occurrence.) Whenever an array key is taken as *input* (e.g. $foo[$bar], array_key_exists()), the hash function would be called (much as in the current RFC), and the corresponding value could be returned directly - the shadow table would not need to be touched, so performance would be identical to that of the current proposal. A lookup in the shadow array would need to happen only when writing to the array, and when a key was being given as *output* (e.g. foreach ( $a as $k => $v ), array_search(), key()). This would happen at the speed of normal random access, and scale with the number of objects used as keys, not the number of items in the main array. Like I say, I'm sure this is full of holes, and I'll leave it there before I get too far down a dead end, but I thought it might be a more productive line of thought than "this will probably never happen". Regards,
-- Rowan Collins [IMSoP]

Guilherme Blanco

11 years ago
Hi, I originally considered you could retrieve the object key, but if it is not possible by this RFC, I will switch my vote to no. By storing hash one way it introduces a huge wtf to the language. Cheers, On Dec 17, 2014 8:40 PM, "Rowan Collins" <rowan.collins@gmail.com> wrote:

Rowan Collins

11 years ago
guilhermeblanco@gmail.com wrote on 17/12/2014 12:43:
> Answering the question of Christopher Becker. It is not possible to > traverse and get your desired elements. > How would you achieve a foreach by key (returning object) without having to > store a separate list and track by hash or through an interface?
SplObjectStorage supports that mechanism, although it's not the most intuitive design. See this comment in the manual: http://php.net/manual/en/class.splobjectstorage.php#114059 As others have pointed out, this proposal does *not* support that usage, because the hash function is one-way, and you cannot get back the object based only on the calculated key. All it does is reduce the boilerplate needed for hashing an object to produce a suitable array key.

Stas Malyshev

11 years ago
Hi!
> I wonder why you opened voting on this, before resolving the "Open > Issues": > > Open Issues > > Should SplFixedArray support object indexes? > Should SplObjectStorage support calling __hash for an object if it exists?
These issues are not part of the RFC's target, they are possible improvements to SPL *if* the RFC is accepted. I don't want to spend time on them if it is not. If it is, then we can see how to improve SPL classes to support it, but it's a different questions from the main RFC. I just mentioned it in order to not forget these things need to be discussed if the RFC is accepted.
-- Stas Malyshev smalyshev@gmail.com

Rowan Collins

11 years ago
On 17/12/2014 16:58, Stanislav Malyshev wrote:
> Hi! > >> I wonder why you opened voting on this, before resolving the "Open >> Issues": >> >> Open Issues >> >> Should SplFixedArray support object indexes? >> Should SplObjectStorage support calling __hash for an object if it exists? > These issues are not part of the RFC's target, they are possible > improvements to SPL *if* the RFC is accepted. I don't want to spend time > on them if it is not. If it is, then we can see how to improve SPL > classes to support it, but it's a different questions from the main RFC. > I just mentioned it in order to not forget these things need to be > discussed if the RFC is accepted. >
That makes sense. They should probably have gone under "Future Scope" rather than "Open Issues" in that case, looking at the wording on the template, but not a big deal.
-- Rowan Collins [IMSoP]

Leigh

11 years ago
On 16 December 2014 at 08:34, Stanislav Malyshev <smalyshev@gmail.com> wrote:
> Hi! > > I'd like to initiate a vote on "objects as keys" RFC: > https://wiki.php.net/rfc/objkey > > I know this is a holiday season but it was extensively discussed and I > think most people already formed their opinions. I've put the voting > period as 3 weeks to have some time for people to vote even with the > holidays, etc. > > The vote includes choice for the name. Vote for either name is counted > as the vote for the overall proposal, and 2/3 majority is required as > it's a language change. > > Some more expanded summary of the arguments is here: > http://php100.wordpress.com/2014/12/14/objects-as-keys/ in case you're > interested.
I've not read the whole email thread, but I have read the RFC, sorry if I missed something in the emails. I've voted no, I really don't see any benefit to automatically calling a magic method for a key, this is a kind of unintuitive magic for me. For objects as keys to be useful (in my opinion), a foreach loop or array_search must be able to return the object as the key component. The RFC doesn't offer a way to retrieve the original object from the stored hash, indeed without a refcount++ the object may not even exist any more. I honestly like the idea of "objects as keys", but this RFC doesn't offer that.

Pascal MARTIN

11 years ago
On 16/12/2014 09:34, Stanislav Malyshev wrote:
> I'd like to initiate a vote on "objects as keys" RFC: > https://wiki.php.net/rfc/objkey
Hi, After discussing this RFC with other members of AFUP, we would probably be +1 on the idea of being able to really use objects as keys. But, considering this RFC doesn't go all the way to "objects as keys" (especially on the "using foreach doesn't get you the object back" part), we ended up on the -1 side.
-- Pascal MARTIN, AFUP - French UG http://php-internals.afup.org/