Paul Graham explains Ruby symbols

Paul Graham offers this excellent explanation for the symbol type:

“Symbols are effectively pointers to strings stored in a hash table.
So you can test equality by comparing a pointer, instead of comparing
each character.” [1]

Of course, he’s talking about symbols in Lisp, but what he says
applies equally well to Ruby and Smalltalk.

Cheers,

Luciano

[1] Revenge of the Nerds

On 3/6/07, Luciano R. [email protected] wrote:

Paul Graham offers this excellent explanation for the symbol type:

“Symbols are effectively pointers to strings stored in a hash table.
So you can test equality by comparing a pointer, instead of comparing
each character.” [1]

Of course, he’s talking about symbols in Lisp, but what he says
applies equally well to Ruby and Smalltalk.

I find this a little too implementation-centric a description.

The key aspect of symbols is that two symbols are identical if they are
equal.
The fact that there may (or may not be) a hash table used to ensure
this is irelevant.

And that description really misses the boat as far as Lisp is
concerned. Lisp symbols aren’t strings, they are really names to which
three (separate) things can be bound, a value (which can be any Lisp
object), a function, and a property list. Actually the name is also
one of the slots in a symbol.
Note that in Lisp the value of a Symbol is separate from it’s name,
and two Symbols can have the same value, they just can’t have the same
name.

So in Lisp a symbol is more like an entry in the table of global names.

Symbols in Ruby and Smalltalk are more alike than Symbols in Lisp.

Smalltalk and Ruby symbols have unique ‘values’ which are also their
‘names’.

Most Smalltalk implementations make Symbol a subclass of String,
although I’m pretty sure that we didn’t require this when we wrote the
X3J20 ANSI Smalltalk spec (We didn’t require much if any particular
inheritance hierarchy). Ruby does not treat Symbols as Strings,
although one can obtain an instance of either from an instance of the
other.

Not long ago Matz experimented with the idea of making Symbol a
subclass of String in 1.9, but this appears to have been dropped in
more recent versions.

I think of symbols is immutable strings that are useful only in
referring to some values? Seems like a nice way for using pointers
without all the warps?
Bharat

On Thu, Mar 08, 2007 at 04:21:10AM +0900, Bharat R. wrote:

I think of symbols is immutable strings that are useful only in
referring to some values? Seems like a nice way for using pointers
without all the warps?

Symbols are what they are. If you need to think of them with some
metaphor,
try this (google cache because it seems that the site is down):

http://72.14.209.104/search?q=cache%3An1xKIHxuk6UJ%3Ahttp%3A%2F%2Fwww.randomhacks.net%2Farticles%2F2007%2F01%2F20%2F13-ways-of-looking-at-a-ruby-symbol

Bharat
–Greg

On 3/7/07, Gregory S. [email protected] wrote:

Bharat
–Greg

Nice indeed but for a simple mind as mine #3 just works well!

Nice. Thanks.

On Thu, Mar 08, 2007 at 04:21:10AM +0900, Bharat R. wrote:

I think of symbols is immutable strings that are useful only in
referring to some values? Seems like a nice way for using pointers
without all the warps?

“Immutable strings” doesn’t work so well, since a string literal is
“immutable” anyway. You might differentiate by mentioning that the
string is fleeting and the symbol persistent, perhaps. A string literal
only exists as long as the interpreter is evaluating – whether for
assignment, for printing to standard out, or whatever else it may be
doing with it. You might also differentiate by pointing out that string
literals are not necessarily unique, while symbols are – duplicate
string literals may be stored in several different variables at once.
In fact, several copies of a given string literal might all be stored in
the same array. A symbol, meanwhile, is unique – and everything that
looks like a copy is actually making reference to the same thing under
the hood.

This is where you start getting into implementation, though, which some
Rubyists consider verboten as a means of defining symbols when
discussing it within the context of the language.

On Thu, Mar 08, 2007 at 02:17:13AM +0900, Rick DeNatale wrote:

I find this a little too implementation-centric a description.
Unfortunately, there’s no way to differentiate a string literal from a
symbol in a definitive manner without brushing up against
implementation. At least, I haven’t seen such a thing yet.

The key aspect of symbols is that two symbols are identical if they are
equal.
The fact that there may (or may not be) a hash table used to ensure
this is irelevant.

Ahh . . . but think about how they’re “equal”. They’re equal because of
the manner in which they’re implemented. If you want to separate the
concept of symbols from the implementation to some degree, you might
explain as little of implementation as possible while still getting the
point across, then say that “this could change so that symbols still
behave the same way but are implemented somewhat differently, but this
is how it’s done right now”.

How exactly, other than the difference between : and ‘’, do you
differentiate a string literal from a symbol without discussing
implementation? I don’t much see a way to do it.

Obviously, a symbol is different in easily explained ways from string
variables, without having to drag implementation into it. Things aren’t
quite so clear-cut between symbols and string literals, though.

Not long ago Matz experimented with the idea of making Symbol a
subclass of String in 1.9, but this appears to have been dropped in
more recent versions.

That’s interesting – I didn’t know that. Thanks for mentioning it.

On Mar 8, 2007, at 12:41 AM, Chad P. wrote:

Obviously, a symbol is different in easily explained ways from string
variables, without having to drag implementation into it. Things
aren’t
quite so clear-cut between symbols and string literals, though.

I’m not sure that the problem you are describing has anything to do with
symbols. Anyone learning Ruby is going to have to understand the
difference between “1”, 1, 1.0, /1/, and :1. Symbol literals
aren’t really special in this regard.

Gary W.

On Thu, Mar 08, 2007 at 02:46:43PM +0900, Chad P. wrote:

On Thu, Mar 08, 2007 at 04:21:10AM +0900, Bharat R. wrote:

I think of symbols is immutable strings that are useful only in
referring to some values? Seems like a nice way for using pointers
without all the warps?

“Immutable strings” doesn’t work so well, since a string literal is
“immutable” anyway.

Well maybe that’s technically right, in the sense that the source code
itself is immutable. However, every time a string literal is ‘executed’
a
new, mutable string object is instantiated:

5.times { puts “hello”.object_id }

So there’s no way in practice to make use of the ‘immutable’ property
you
describe, because every String object your program sees is mutable.

5.times {
a = “hello”
a << “!” # changed it
}

Here’s where I’d say a symbol is different:

5.times {
a = :hello
puts a.object_id # same every time round
a << “!” # fails (symbol has no mutating methods)
}

Regards,

Brian.

On Thu, Mar 08, 2007 at 02:55:34PM +0900, Gary W. wrote:

And a single symbol can be represented by several different literals:

:alpha, :‘alpha’, :“alpha”

So you have to be careful about talking about unique literals.

True – I fudged the facts a little bit. I should have done that
differently.

On Thu, Mar 08, 2007 at 04:02:02PM +0900, Brian C. wrote:

itself is immutable. However, every time a string literal is ‘executed’ a
new, mutable string object is instantiated:

5.times { puts “hello”.object_id }

So there’s no way in practice to make use of the ‘immutable’ property you
describe, because every String object your program sees is mutable.

True – which brings it back to the “strings are fleeting” thing.

Thus, the comment in my previous email about symbols being kind of like
string literals, except that they are persistent. Because strings are
fleeting, they’re actually different incidences of a string every time
they’re evaluated.

On Thu, Mar 08, 2007 at 02:48:48PM +0900, Gary W. wrote:

aren’t really special in this regard.
Umm . . . I don’t see how any of that has anything to do with whether or
not some reference to implementation details is necessary for a
meaningful explanation of the difference between :bob and “bob”.

On Mar 8, 2007, at 12:46 AM, Chad P. wrote:

You might also differentiate by pointing out that string
literals are not necessarily unique, while symbols are – duplicate
string literals may be stored in several different variables at once.

This doesn’t sound right to me. String literals are part of the
source code. They aren’t stored in variables at all (let’s just
agree to ignore eval for the moment).

And a single symbol can be represented by several different literals:

:alpha, :‘alpha’, :“alpha”

So you have to be careful about talking about unique literals.

Gary W.

Hi –

On 3/8/07, Gary W. [email protected] wrote:

aren’t really special in this regard.
I’ll add yet another way of thinking about symbols, namely that they
are very integer-like. All of the immutable, unique, immediate-value
stuff is not so much a modification of how strings behave as a rather
exact replication of how integers behave.

David

On 3/7/07, Gregory S. [email protected] wrote:

On Thu, Mar 08, 2007 at 04:21:10AM +0900, Bharat R. wrote:

I think of symbols is immutable strings that are useful only in
referring to some values? Seems like a nice way for using pointers
without all the warps?
Symbols are what they are. If you need to think of them with some metaphor,
try this (google cache because it seems that the site is down):

I think that this is an awful article (and said as such in the
comments). There are much better descriptions of symbols out there
that don’t impute magic to symbol objects.

-austin

On 3/8/07, David A. Black [email protected] wrote:

I’ll add yet another way of thinking about symbols, namely that they
are very integer-like. All of the immutable, unique, immediate-value
stuff is not so much a modification of how strings behave as a rather
exact replication of how integers behave.

I like to use this analogy too. An integer has a string
representation, which is what is embedded in the code as a literal.
This string representation is not actually the integer, but every
integer corresponds to a unique string of digits, and if you use the
same string twice in your code, you’re referring to the same integer.

martin

On 3/8/07, David A. Black [email protected] wrote:

I’m not sure that the problem you are describing has anything to do with
symbols. Anyone learning Ruby is going to have to understand the
difference between “1”, 1, 1.0, /1/, and :1. Symbol literals
aren’t really special in this regard.

I’ll add yet another way of thinking about symbols, namely that they
are very integer-like. All of the immutable, unique, immediate-value
stuff is not so much a modification of how strings behave as a rather
exact replication of how integers behave.

As Obi-wan Kenobi would say, “that’s (only) true from a certain point of
view.”

irb(main):002:0> :a + :b
NoMethodError: undefined method `+’ for :a:Symbol
from (irb):2

:wink:

Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

On 3/8/07, Rick DeNatale [email protected] wrote:

With an itchy trigger finger.

applies equally well to Ruby and Smalltalk.
arg.object_id == arg.to_sym.object_id rescue false
end

is_symbol?(:a) => true
is_symbol?(“a”) => false
is_symbol?([:a, :b]) => false

concept of symbols from the implementation to some degree, you might
explain as little of implementation as possible while still getting the
point across, then say that “this could change so that symbols still
behave the same way but are implemented somewhat differently, but this
is how it’s done right now”.

Or you can turn this around and say that the equality-identity
relationship is what’s essential and that one way of implementing this
requirement is to intern using a hash table.

How exactly, other than the difference between : and ‘’, do you
differentiate a string literal from a symbol without discussing
implementation? I don’t much see a way to do it.

The same way you can describe the properties of other objects without
regard to implementation. For example we can understand how integers
work without having to going into the details of how they are
represented.

Obviously, a symbol is different in easily explained ways from string
variables, without having to drag implementation into it. Things aren’t
quite so clear-cut between symbols and string literals, though.

I’m not sure that I get your distinction between string variables and
string literals. It’s really a matter of the differences between
string OBJECTs and symbol OBJECTs.


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

On 3/8/07, Chad P. [email protected] wrote:

I find this a little too implementation-centric a description.

Unfortunately, there’s no way to differentiate a string literal from a
symbol in a definitive manner without brushing up against
implementation. At least, I haven’t seen such a thing yet.

lets see

def is_symbol?(arg)
arg.object_id == arg.to_sym.object_id rescue false
end

concept of symbols from the implementation to some degree, you might
variables, without having to drag implementation into it. Things aren’t

CCD CopyWrite Chad P. [ http://ccd.apotheon.org ]
“It’s just incredible that a trillion-synapse computer could actually
spend Saturday afternoon watching a football game.” - Marvin Minsky


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

IPMS/USA Region 12 Coordinator
http://ipmsr12.denhaven2.com/

Visit the Project Mercury Wiki Site
http://www.mercuryspacecraft.com/