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:
- Get symbol identifier (ulong)
- Get elements from array where bucket.h equals to this identifier
- Iterate over those elements and find the one that has nKeyLength == -1
(actually we will iterate over pNext/pLast elements)
What symbols can give:
- 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'
)) - Memory usage reduction. AFAIK, there's a lot of cases like the above
and the use of symbols would affect on memory usage significantly. - 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. - 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.
Sounds like it could make some sense. However, I've got a question..
array(
'label' => 'Comment',
'required' => false,
'property_path' => 'properties.comment'
)
is actually equivalent to
array(
'label' => 'Comment',
'property_path' => 'properties.comment',
'required' => false,
)
(Notice the change in keys order. As long as we just use those arrays as
hash maps, we notice no differences).
With symbols, which act as aliases for integer array keys, the situation
could be different, right? Or excuse me if I don't get what symbols are (I
don't know much about Ruby)
Cheers,
Victor
2013/1/5 Nikita Nefedov inefedor@gmail.com
array(
'label' => 'Comment',
'required' => false,
'property_path' => 'properties.comment'
)
On Sat, 05 Jan 2013 10:27:01 -0000, Crocodile crocodile2u@gmail.com
wrote:
Sounds like it could make some sense. However, I've got a question..
array(
'label' => 'Comment',
'required' => false,
'property_path' => 'properties.comment'
)is actually equivalent to
array(
'label' => 'Comment',
'property_path' => 'properties.comment',
'required' => false,
)(Notice the change in keys order. As long as we just use those arrays
as hash maps, we notice no differences).With symbols, which act as aliases for integer array keys, the
situation could be different, right? Or excuse me if I don't get what
symbols are (I don't >know much about Ruby)Cheers,
Victor2013/1/5 Nikita Nefedov inefedor@gmail.com
array(
'label' => 'Comment',
'required' => false,
'property_path' => 'properties.comment'
)
Hi,
PHP arrays are always ordered (they actually are doubly-linked lists and
hash tables at the same time), so there won't be any change in ordering
behavior.
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.
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-symbolIt 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:
- Get symbol identifier (ulong)
- Get elements from array where bucket.h equals to this identifier
- Iterate over those elements and find the one that has nKeyLength == -1
(actually we will iterate over pNext/pLast elements)What symbols can give:
- 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'
))- Memory usage reduction. AFAIK, there's a lot of cases like the
above and the use of symbols would affect on memory usage significantly.- 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.- 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/
If symbols could use the sign bit or otherwise distinguish from typical integer keys one would have some hope of meaningful debugging output. I don't think it makes sense to mix integer keys and symbol keys but being able to differentiate them for debugging purposes would be great. However since php arrays are sparse anyway is there much of a win from integer keys in the first place?
Sent from my iPhone
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.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-symbolIt 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:
- Get symbol identifier (ulong)
- Get elements from array where bucket.h equals to this identifier
- Iterate over those elements and find the one that has nKeyLength == -1
(actually we will iterate over pNext/pLast elements)What symbols can give:
- 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'
))- Memory usage reduction. AFAIK, there's a lot of cases like the above and the use of symbols would affect on memory usage significantly.
- 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.
- 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/
What symbols can give:
- 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'
))- Memory usage reduction. AFAIK, there's a lot of cases like the above
and the use of symbols would affect on memory usage significantly.- 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.- Autocompletion from IDEs.
Hi Nikita!
I don't quite understand what those symbols would actually be good for. If
it's just for saving exactly one character for array keys (:foo vs "foo"),
then this isn't worth it. If this is about memory savings, then I don't
think it will help at all. PHP uses interned strings, so all those "label"
etc strings in your above example actually use the same string value. The
hash for those strings is also precomputed, so symbol don't have a
performance advantage either. Regarding your fourth point, autocompletion
is available for string array keys at least in PhpStorm and I guess also in
other IDEs.
So, I don't yet really get what the point behind the symbols is.
Thanks,
Nikita
[snip]
If this is about memory savings, then I don't
think it will help at all. PHP uses interned strings, so all those "label"
etc strings in your above example actually use the same string value. The
hash for those strings is also precomputed, so symbol don't have a
performance advantage either.
That's what I refered in my previous mail. Thanks Nikita (Popov) for the
clarification.
Best regards.
--
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/
On Sat, 05 Jan 2013 12:21:26 -0000, Nikita Popov nikita.ppv@gmail.com
wrote:
On Sat, Jan 5, 2013 at 3:07 PM, Nikita Nefedov inefedor@gmail.com
wrote:What symbols can give:
- 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'
))- Memory usage reduction. AFAIK, there's a lot of cases like the above
and the use of symbols would affect on >>memory usage significantly.- 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.- Autocompletion from IDEs.
Hi Nikita!
I don't quite understand what those symbols would actually be good for.
If it's just for saving exactly one >character for array keys (:foo vs
"foo"), then this isn't worth it. If this is about memory savings, then
I don't >think it will help at all. PHP uses interned strings, so all
those "label" etc strings in your above example >actually use the same
string value. The hash for those strings is also precomputed, so symbol
don't have a >performance advantage either. Regarding your fourth point,
autocompletion is available for string array keys at >least in PhpStorm
and I guess also in other IDEs.So, I don't yet really get what the point behind the symbols is.
Thanks,
Nikita
Hi, yes, you are right about interned strings, I didn't know it.
Actually my personal opinion is that strings should be used to store data
(as values), not to retrieve it (not as keys). But strings are more
developer-friendly than anything else (because you don't need to define
new constant or new enumerable member for adding new parameter on
receiving side, and you always see what this parameter is about). So you
can see Symbols as enumerable that don't need to be initialized. There's
actually no technical reason behind that.
Though there would be a little speed-up because with Symbols array's
Buckets will keep numeric key, so instead of memcmp you will need to just
compare two longs when retrieving element.
Actually this is looks a little bad now, AFAIK this is what happens when
you trying to receive value from array by string key:
Calling zend_new_interned_string_int for interning or getting already
interned same string, receiving pointer to the stored string from it:
Hash the string (O(n))
Retrieve bucket from arBuckets
Find needed bucket by iterating over all retrieved buckets (over *pLast)
and comparing its keys with memcmp
If found - return pointer to string, else create new bucket...
Now that we have an interned string, we can try to retrieve value from
array with string:
Hash the string again (O(n))
Retrieve bucket by hash fro arBuckets
And again memcmp used for comparing strings
This could be improved with Symbols, so that you won't need hash string
twice and use memcmp.
BTW do we really need a doubly linked list for interned strings
(pListLast, pListNext) and all the extra members from HashTable/Bucket
that needed for arrays? I know this is offtopic and these structs are used
everywhere in PHP (because of DRY), but there are some places like this or
class tables where we don't need arrays (PHP's arrays) functionality.
**
Though there would be a little speed-up because with Symbols array's
Buckets will keep numeric key, so instead of memcmp you will need to just
compare two longs when retrieving element.
Before memcmping the array keys PHP will first compare the pointers. For
interned strings the pointers will be the same so the memcmp is not done.
See http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_hash.c#950.
Actually this is looks a little bad now, AFAIK this is what happens when
you trying to receive value from array by string key:
- Calling zend_new_interned_string_int for interning or getting
already interned same string, receiving pointer to the stored string from
it:
- Hash the string (O(n))
- Retrieve bucket from arBuckets
- Find needed bucket by iterating over all retrieved buckets (over
*pLast) and comparing its keys with memcmp- If found - return pointer to string, else create new bucket...
- Now that we have an interned string, we can try to retrieve value
from array with string:
- Hash the string again (O(n))
- Retrieve bucket by hash fro arBuckets
- And again memcmp used for comparing strings
The string interning happens at compile time, so for all practical
purposes it does not matter much how long it takes. At runtime the hash is
already precalculated and the ptrs are the same (see above) so the array
access goes through pretty much the fastest possible code-path. I quickly
tried out how fast they are compared to numeric keys:
http://codepad.viper-7.com/Km9hPz String and integer keys perform pretty
much the same there.
Nikita
On Sat, Jan 5, 2013 at 6:58 PM, Nikita Nefedov inefedor@gmail.com
wrote:**
Though there would be a little speed-up because with Symbols array's
Buckets will keep numeric key, so instead of memcmp you will need to
just
compare two longs when retrieving element.Before memcmping the array keys PHP will first compare the pointers. For
interned strings the pointers will be the same so the memcmp is not done.
See http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_hash.c#950.
My fault, didn't see it in the source...
Hi!
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?
As I understand, :foo is basically an interned string "foo". But in PHP
all constant strings are interned now, so the only thing we gain is
comparison speed. Given that the strings we're talking about is under 10
chars, performance gain from this would be negligible, and symbols
aren't frequently directly compared anyway. So what exactly we're
gaining that is not there in just constant string?
$foo = array();
$foo[:bar] = "qwerty";var_dump($foo);
// array(1) {
// [0] =>
// string(6) "qwerty"
//}
Here's a problem. How we know that :bar is 0? What if we serialized $foo
and later loaded it back - would :bar still be 0? Would :bar be 0 in all
scripts forever - and if not, how would we know where $foo[:bar] is
actually stored when we combine two scripts? I think it can not work
this way since link between :bar and actual hash key should be stable.
I will drop the part about new variable type, the main thing is how
HashTables could work with symbols as keys.
HashTable can accept only string or number as key. As we have seen
before, making number from :bar is very hard to pull off properly. And
if we use string "bar", why not just use string "bar"?
- 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:
How it's more convenient? I don't see any difference.
- Memory usage reduction. AFAIK, there's a lot of cases like the above
and the use of symbols would affect on memory usage significantly.
I don't see any memory usage reduction - you still have to store the
string. Could you explain how memory usage is reduced?
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
On Sat, Jan 5, 2013 at 2:49 PM, Stas Malyshev smalyshev@sugarcrm.comwrote:
Hi!
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?As I understand, :foo is basically an interned string "foo". But in PHP
all constant strings are interned now, so the only thing we gain is
comparison speed. Given that the strings we're talking about is under 10
chars, performance gain from this would be negligible, and symbols
aren't frequently directly compared anyway. So what exactly we're
gaining that is not there in just constant string?$foo = array();
$foo[:bar] = "qwerty";var_dump($foo);
// array(1) {
// [0] =>
// string(6) "qwerty"
//}Here's a problem. How we know that :bar is 0? What if we serialized $foo
and later loaded it back - would :bar still be 0? Would :bar be 0 in all
scripts forever - and if not, how would we know where $foo[:bar] is
actually stored when we combine two scripts? I think it can not work
this way since link between :bar and actual hash key should be stable.I will drop the part about new variable type, the main thing is how
HashTables could work with symbols as keys.HashTable can accept only string or number as key. As we have seen
before, making number from :bar is very hard to pull off properly. And
if we use string "bar", why not just use string "bar"?
- 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:How it's more convenient? I don't see any difference.
- Memory usage reduction. AFAIK, there's a lot of cases like the above
and the use of symbols would affect on memory usage significantly.I don't see any memory usage reduction - you still have to store the
string. Could you explain how memory usage is reduced?--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227--
I'm still a total newb when it comes to Ruby, but as I understand it, a
symbol can be particularly helpful by maximizing code readability without
sacrificing efficiency. As a PHP guy, I tend to think of a Ruby symbol as
a constant that doesn't need to be defined or set. Its value is set
internally and is not relevant in userland except for the fact that it is
unique and unchanging.
For example, in current PHP, let's say I just bought a dog:
<?php
define( 'BROWN', 0x01 );
define( 'BLACK', 0x02 );
define( 'PURPLE', 0x03 );
switch ( $color )
{
case BROWN:
// Brown dog!
break;
case BLACK:
// Black dog!
break;
case PURPLE:
// Purple dog!?
break;
}
?>
Now, if we had symbols, I could get rid of the constants and just do this
instead:
<?php
switch ( $color )
{
case :brown:
// Brown dog!
break;
case :black:
// Black dog!
break;
case :purple:
// Purple dog!?
break;
}
?>
In both cases, we really don't care what the actual values of brown, black,
and purple are. We just want it to be unique so we can reference each of
them in a visually friendly way with minimal performance impact. That's
where I could see a valid use-case for Ruby-like symbols in PHP.
--Kris
In both cases, we really don't care what the actual values of brown, black,
and purple are. We just want it to be unique so we can reference each of
them in a visually friendly way with minimal performance impact. That's
where I could see a valid use-case for Ruby-like symbols in PHP.
What you are describing is just an enum. That's not really what Ruby
symbols are about.
-Rasmus
In both cases, we really don't care what the actual values of brown,
black,
and purple are. We just want it to be unique so we can reference each of
them in a visually friendly way with minimal performance impact. That's
where I could see a valid use-case for Ruby-like symbols in PHP.What you are describing is just an enum. That's not really what Ruby
symbols are about.-Rasmus
Ruby doesn't have native enums. Symbols are often used in Ruby code to
obtain the same functionality, though.
--Kris
On Sat, Jan 5, 2013 at 3:32 PM, Rasmus Lerdorf <rasmus@lerdorf.com
mailto:rasmus@lerdorf.com> wrote:> In both cases, we really don't care what the actual values of brown, black, > and purple are. We just want it to be unique so we can reference each of > them in a visually friendly way with minimal performance impact. That's > where I could see a valid use-case for Ruby-like symbols in PHP. What you are describing is just an enum. That's not really what Ruby symbols are about. -Rasmus
Ruby doesn't have native enums. Symbols are often used in Ruby code to
obtain the same functionality, though.
Right, but if that is the only use you can come up with for them in PHP,
then there are way simpler ways to do it. We already have an enum RFC.
https://wiki.php.net/rfc/enum
-Rasmus
On Sat, Jan 5, 2013 at 3:32 PM, Rasmus Lerdorf <rasmus@lerdorf.com
mailto:rasmus@lerdorf.com> wrote:> In both cases, we really don't care what the actual values of brown, black, > and purple are. We just want it to be unique so we can reference each of > them in a visually friendly way with minimal performance impact. That's > where I could see a valid use-case for Ruby-like symbols in PHP. What you are describing is just an enum. That's not really what Ruby symbols are about. -Rasmus
Ruby doesn't have native enums. Symbols are often used in Ruby code to
obtain the same functionality, though.Right, but if that is the only use you can come up with for them in PHP,
then there are way simpler ways to do it. We already have an enum RFC.
https://wiki.php.net/rfc/enum-Rasmus
Granted, but other use-cases have already been presented as well.
Obviously the one I suggested would no longer be useful if PHP adopts
enums.
--Kris
Granted, but other use-cases have already been presented as well.
Obviously the one I suggested would no longer be useful if PHP adopts
enums.
Actually, I didn't see any other cases. The fact that we have interned
immutable strings in PHP invalidated all the other cases presented so far.
-Rasmus
I'm still a total newb when it comes to Ruby, but as I understand it, a
symbol can be particularly helpful by maximizing code readability without
sacrificing efficiency. As a PHP guy, I tend to think of a Ruby symbol as
a constant that doesn't need to be defined or set. Its value is set
internally and is not relevant in userland except for the fact that it is
unique and unchanging.For example, in current PHP, let's say I just bought a dog:
<?php
define( 'BROWN', 0x01 );
define( 'BLACK', 0x02 );
define( 'PURPLE', 0x03 );switch ( $color )
{
case BROWN:
// Brown dog!
break;
case BLACK:
// Black dog!
break;
case PURPLE:
// Purple dog!?
break;
}?>
Now, if we had symbols, I could get rid of the constants and just do this
instead:<?php
switch ( $color )
{
case :brown:
// Brown dog!
break;
case :black:
// Black dog!
break;
case :purple:
// Purple dog!?
break;
}?>
In both cases, we really don't care what the actual values of brown, black,
and purple are. We just want it to be unique so we can reference each of
them in a visually friendly way with minimal performance impact. That's
where I could see a valid use-case for Ruby-like symbols in PHP.--Kris
The reason that Ruby needs symbols basically comes down to the fact that
Ruby has mutable strings. I'm not sure how they came up with that idea (I
mean, really, mutable strings? wtf?!), but due to it Ruby needs another
string type that is immutable. That's what symbols are. Symbols are Ruby's
variant of immutable interned strings. PHP doesn't need this because
strings in PHP are immutable by themselves and automatically interned where
reasonable.
Nikita
Hi!
I'm still a total newb when it comes to Ruby, but as I understand it, a
symbol can be particularly helpful by maximizing code readability
without sacrificing efficiency. As a PHP guy, I tend to think of a Ruby
symbol as a constant that doesn't need to be defined or set. Its value
String is a constant that doesn't need to be defined of set.
In both cases, we really don't care what the actual values of brown,
black, and purple are. We just want it to be unique so we can reference
If you don't care what the values are, why have them at all? What's
wrong with just using "brown", etc.?
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227