Hi :-),
Nice proposal but I have few questions and remarks.
My first question is how to delete symbols? I don't know if it is useful
or not. We should discuss about that. Is `unset(:foo)` enough? How are
they handled by the GC?
Another question is: where are we able to use symbols? Is it allowed to
write `const FOO = :bar` for example? Or in a default argument value:
`public function f ( $x = :foo ) { … }`?
What kind of (arithmetical) operations are allowed on symbols?
You proposed to represent symbols as integers. Could it create
conflicts? For example: `$foo = [0 => 'bar', :baz => 'qux']`. What
happens if `:baz` is set to 0?
Finally, if my memory is good, a few months ago, some patches were
updating “constant strings” performances by representing them as
“buffers”/“constants” internally, no? Maybe I'm wrong, but it could be a
middle-way solution if it is not yet implemented (especially since we
have strings dereferencing, implementation could be ease).
My two cents :-).
Best regards.
On 05/01/13 15:07, Nikita Nefedov wrote:
I know I shouldn't write "Ruby" in the subject of a letter for
php-internals ML, but... Just wanted to ask, is anybody interested in
this feature in PHP?
You can read about it here:
http://www.randomhacks.net/articles/2007/01/20/13-ways-of-looking-at-a-ruby-symbol
It can be implemented in PHP as a HashTable where key would be strings
and values would be unique identifiers (just incrementing long, can be
tracked with nNextFreeElement).
How it would work in userland?
If it would be proposal, I would divide it on two different
(competitive) proposals:
First, we could implement it so symbol expression would return an
associated integer.
(note that symbols are most often used as hash keys in ruby so my
examples are relying on it)
Example:
$foo = array();
$foo[:bar] = "qwerty";
var_dump($foo);
// array(1) {
// [0] =>
// string(6) "qwerty"
//}
var_dump(:bar); // int(0)
var_dump(:some_new_symbol); // int(1)
This is the easiest way, and I can implement it. But, it would be hard
to debug.
The second way - we can implement it as a new variable type, and the
main thing is that arrays will be able to take variables of symbol
type as keys, I know it sounds scary but it's not so hard actually.
I will drop the part about new variable type, the main thing is how
HashTables could work with symbols as keys.
We could change the type of nKeyLength (in Bucket) to signed integer
(now it's unsigned, I don't think we will miss something from that)
and use it as a flag: if it's -1 (less than zero) - then we know the
symbol was used as a key, there will be filled bucket.h member with a
symbol identifier.
That way the above code will evaluate so:
$foo = array();
$foo[:bar] = "qwerty";
var_dump($foo);
// array(1) {
// [:bar] =>
// string(6) "qwerty"
//}
var_dump(:bar); // symbol(:bar)
var_dump(:some_new_symbol); // symbol(:some_new_symbol)
To make it clear, when retrieving an element by symbol from array,
these steps will be needed:
1. Get symbol identifier (ulong)
2. Get elements from array where bucket.h equals to this identifier
3. Iterate over those elements and find the one that has nKeyLength == -1
(actually we will iterate over pNext/pLast elements)
What symbols can give:
1. More convenient way to use it almost everywhere as a replacement
for strings and sometimes for constants. There's a lot of code that
uses arrays as a parameter-stores. For example, here's how you usually
define a form in Symfony2:
$builder
->add('title', 'text', array(
'label' => 'Album title'
))
->add('title_alias', 'text', array(
'label' => 'Album alias',
'required' => false,
'property_path' => 'properties.titleAlias'
))
->add('comment', 'text', array(
'label' => 'Comment',
'required' => false,
'property_path' => 'properties.comment'
))
->add('labels', 'text', array(
'label' => 'Musical labels',
'required' => false,
'property_path' => 'properties.labels'
))
->add('language', 'text', array(
'required' => false,
'property_path' => 'properties.language'
))
It could be improved this way:
$builder
->add('title', :text, array(
:label => 'Album title'
))
->add('title_alias', :text, array(
:label => 'Album alias',
:required => false,
:property_path => 'properties.titleAlias'
))
->add('comment', :text, array(
:label => 'Comment',
:required => false,
:property_path => 'properties.comment'
))
->add('labels', :text, array(
:label => 'Musical labels',
:required => false,
:property_path => 'properties.labels'
))
->add('language', :text, array(
:required => false,
:property_path => 'properties.language'
))
2. Memory usage reduction. AFAIK, there's a lot of cases like the
above and the use of symbols would affect on memory usage significantly.
3. Memory leaks. Symbols can't be just garbage collected as, for
example zvals, it's not possible. But we can do it for every request,
so I don't think it would be problem.
4. Autocompletion from IDEs.
PS I don't want to call it "proposal", despite the fact that this is
actually a proposal, I'm just not sure it can go as a proposal.
--
Ivan Enderlin
Developer of Hoa
http://hoa.42/ or http://hoa-project.net/
PhD. student at DISC/Femto-ST (Vesontio) and INRIA (Cassis)
http://disc.univ-fcomte.fr/ and http://www.inria.fr/
Member of HTML and WebApps Working Group of W3C
http://w3.org/
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php