Paul Graham explains Ruby symbols

  • Thread starter Luciano Ramalho
  • Start date
L

Luciano Ramalho

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] http://paulgraham.com/icad.html
 
R

Rick DeNatale

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.
 
B

Bharat Ruparel

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
 
C

Chad Perrin

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.

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.
 
C

Chad Perrin

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.
 
G

Gary Wright

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 Wright
 
G

Gary Wright

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 Wright
 
B

Brian Candler

"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.
 
C

Chad Perrin

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.

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

Chad Perrin

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.

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.
 
C

Chad Perrin

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.

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".
 
D

David A. Black

Hi --

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.


David

--
Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black)
(See what readers are saying! http://www.rubypal.com/r4rrevs.pdf)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)
 
M

Martin DeMello

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
 
A

Austin Ziegler

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
 
R

Rick DeNatale

Hi --



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

;-)
 
R

Rick DeNatale

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.

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
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.



That's interesting -- I didn't know that. Thanks for mentioning it.


--
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/
 
R

Rick DeNatale

With an itchy trigger finger.
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.

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

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


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.

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.

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,990
Messages
2,570,211
Members
46,796
Latest member
SteveBreed

Latest Threads

Top