Getting Over Symbols

When I was first learning Ruby, symbols were a bit of a mystery.
I understand them now, and in hindsight, I don’t really understand
why they were so confusing. In teaching other people about Ruby and
in reading ruby-talk it is quite clear that symbols are an early
stumbling block for learning Ruby. I’d take an educated guess that
people learning Rails (or any other Ruby framework) struggle with
trying to understand if symbols are a magic feature of the framework
or the language or something else.

My question to the list is, why? What is it about Symbols that
creates such confusion? I’m getting ready to prepare a two-hour
“Intro to Ruby” seminar and I’d like to find an approach to Symbols
that cuts through the confusion.

One thought that I’ve had is that Ruby’s reflection capabilities
expose the names of various internal structures (classes, methods,
modules, constants) in a way that is quite foreign to many programmers.
For example, in C you don’t have any runtime access to the symbol table
so you would never see a value that could be mapped to a function like
‘printf’, ‘scanf’, or ‘main’ unless the programmer took the trouble to
construct an explicit symbol table (mapping strings to function
pointers,
for example). An explicit table isn’t much of a mystery.

When you switch to a language like Ruby, Smalltalk, and certainly the
entire family of Lisp languages you are now in an environment where the
data structures of the language runtime are exposed to the programmer.
For a while, the novice will struggle because their mental model of
a runtime environment just doesn’t match their new reality and symbols
just happen to be the bridge between the two worlds. One of the first
features of Ruby that many people learn are the ‘attr*’ methods. Right
off the bat, the novice is exposed to the mappings from strings to
symbols to methods.

Do folks coming from the Lisp/Scheme world have trouble with symbols or
do they absorb symbols right away because they already struggled with
the concept when learning about atoms?

Thoughts?

Gary W.

On Dec 4, 2005, at 1:07 PM, [email protected] wrote:

I’d take an educated guess that
people learning Rails (or any other Ruby framework) struggle with
trying to understand if symbols are a magic feature of the framework
or the language or something else.

It’s my opinion that Rails complicates this issue quite a bit, with
it’s prevalent use of it’s HashWithIndifferentAccess. Sadly, I think
this creates more gotchas than it solves. (I’m not trying to bash
Rails here, just making an observation.)

My question to the list is, why? What is it about Symbols that
creates such confusion? I’m getting ready to prepare a two-hour
“Intro to Ruby” seminar and I’d like to find an approach to Symbols
that cuts through the confusion.

I always introduce it as an immutable String. That seems to suck the
magic out of in.

James Edward G. II

Hi –

On Mon, 5 Dec 2005 [email protected] wrote:

creates such confusion? I’m getting ready to prepare a two-hour
“Intro to Ruby” seminar and I’d like to find an approach to Symbols
that cuts through the confusion.

I’ve seen Symbol confusion in the following forms:

  1. Confusion between Symbol objects and symbols in the sense of
    identifiers in a Ruby program. This code:

x = 1

may result in :x being put in the symbol table, but the x in that
expression is not a Symbol object. I don’t think this distinction is
always clear to people.

  1. Overuse of symbols. This kind of thing:

methods.each do |m| something.send(m.intern) end

is almost certainly pointless, in terms of efficiency. I think symbols
have a kind of mystique – as if there’s something sort of sloppy or
substandard or laughably high-level about using strings where you could
use symbols. In fact, the methods that take strings or symbols as
arguments are usually well-engineered to handle either.

  1. Over-emphasis on the symbol table and its meaning. Maybe I
    under-emphasize it in my own thinking… but I’ve never seen any
    practical
    reason to think of symbols in terms of a table, even if one exists
    internally. I can’t call to mind any case where the data structures
    involved in the interpreter’s handling of symbols would make any
    difference to me. All I need to know is that symbols are immediate,
    immutable, and fast.

I’m not campaigning against understanding the interpreter. But from the
user side – which is where we are when we use Ruby – symbols are still
an abstraction. When I do “send(:meth)”, I’m not manipulating the
symbol
table as a table. The table-ness is an implementation detail. Symbol
objects are part of Ruby.

  1. Conflation of symbols and methods. Sort of along the same lines:
    :meth
    is no closer to the method you get when you do method(:meth) than “meth”
    is. It may be closer internally, but in practical terms, it isn’t. You
    can’t do: :meth += “2” and change the name of “meth” to “meth2”. The
    symbol is the ending point, not the starting point.

One thought that I’ve had is that Ruby’s reflection capabilities expose
the names of various internal structures (classes, methods, modules,
constants) in a way that is quite foreign to many programmers. For
example, in C you don’t have any runtime access to the symbol table so
you would never see a value that could be mapped to a function like
‘printf’, ‘scanf’, or ‘main’ unless the programmer took the trouble to
construct an explicit symbol table (mapping strings to function
pointers, for example). An explicit table isn’t much of a mystery.

To my knowledge there’s no programmatic access to the underlying symbol
table in Ruby. (Am I wrong about this? Have I missed all the
table-manipulating fun? :slight_smile:

When you switch to a language like Ruby, Smalltalk, and certainly the
entire family of Lisp languages you are now in an environment where the
data structures of the language runtime are exposed to the programmer.
For a while, the novice will struggle because their mental model of
a runtime environment just doesn’t match their new reality and symbols
just happen to be the bridge between the two worlds. One of the first
features of Ruby that many people learn are the ‘attr*’ methods. Right
off the bat, the novice is exposed to the mappings from strings to
symbols to methods.

Again, I think that from the programmer’s perspective, you can map from
strings to methods just as easily:

attr_reader :a
attr_reader “a”
attr_reader :a.to_s
attr_reader “a”.to_sym

Obviously the first one is the common case, and the first two are the
only
useful ones. But conceptually, I think of strings and symbols, in such
cases, as equidistant from the underlying method – except for the hint
that symbols are faster.

David
__
David A. Black
[email protected]

“Ruby for Rails”, forthcoming from Manning Publications, April 2006!

On Sun, 04 Dec 2005 19:17:36 -0000, James Edward G. II
[email protected] wrote:

On Dec 4, 2005, at 1:07 PM, [email protected] wrote:

My question to the list is, why? What is it about Symbols that
creates such confusion? I’m getting ready to prepare a two-hour
“Intro to Ruby” seminar and I’d like to find an approach to Symbols
that cuts through the confusion.

I always introduce it as an immutable String. That seems to suck the
magic out of in.

It took your describing it so before I saw that symbols aren’t nearly as
complex as they sound. It’s the connotations of the word ‘symbol’ I
guess…

To my knowledge there’s no programmatic access to the underlying
symbol
table in Ruby. (Am I wrong about this? Have I missed all the
table-manipulating fun? :slight_smile:

When you define an instance method you are adding an entry to the
method table for the class. The key for this table is a symbol so
you might be implicitly adding an entry into the internal table
of all symbols (maintained by the Symbol class). When you call
method(“puts”) or send(“puts”) you are looking up an entry in the
method table. When you call remove_method(“puts”) you are deleting
the entry in the method table. Same situation for constants (which
implicitly
means Modules and Classes). This is what I meant by symbol table.

Again, I think that from the programmer’s perspective, you can map
from
strings to methods just as easily:

attr_reader :a
attr_reader “a”
attr_reader :a.to_s
attr_reader “a”.to_sym

Yes, it is this mapping from strings/symbols to methods that is novel
for many programmers. I think it is the novelty of this built-in
mapping ability that gets confused with the abstract-data-type aspect
of Symbols.

On Dec 4, 2005, at 3:44 PM, David A. Black wrote:

In other words, you don’t address the table as a tabular data
structure
programmatically.

Agreed, but in a static language (yes, I know that is a fuzzy
term) even the implicit manipulation that we were both talking
about doesn’t exist or is severely limited.

Very interesting post to a newbie like me. Coming from a “C” family of
languages, you just broadened my understanding of Ruby. Until now I
failed to see the importance of exposing the runtime data structures of
the language. Java/.NET allow it to some extent with their Reflection
capabilities. Unlike Ruby (and probably Lisp family of languages) the
reflection capablities of these platforms are limited. I guess this is
by design.

The : (colon) notation doesn’t help eithrr. Given the other prefixes
like @ and @@ and $ my original instinct was to think it was something
like that. Of course, I soon realized it was more like ’ or ", but
non-bracketing.

T.

Hi –

On Mon, 5 Dec 2005 [email protected] wrote:

method table. When you call remove_method(“puts”) you are deleting
the entry in the method table. Same situation for constants (which
implicitly
means Modules and Classes). This is what I meant by symbol table.

I understand – but what I meant was, there’s no situation where you
directly do:

the_symbol_table << :sym, method(:x) # homemade ‘alias’

or

the_symbol_table.each_row do { … }

In other words, you don’t address the table as a tabular data structure
programmatically.

for many programmers. I think it is the novelty of this built-in
mapping ability that gets confused with the abstract-data-type aspect
of Symbols.

I would separate the concerns. The reflection/metaprogramming stuff in
Ruby isn’t really about the Symbol class. So you could, as JEG3
suggests,
describe them principally as an immutable (and quickly resolvable)
string
variant.

David
__
David A. Black
[email protected]

“Ruby for Rails”, forthcoming from Manning Publications, April 2006!

On 12/4/05, James Edward G. II [email protected] wrote:

I always introduce it as an immutable String. That seems to suck the
magic out of in.

Interesting. I always think of them as a Number with an arbitrary
value.

foo[:bar] = “baz”

is somewhat related to:

#define BAR = 1
foo[BAR] = “baz”

Viele Grü�e,
Levin

On Dec 4, 2005, at 2:07 PM, [email protected] wrote:

My question to the list is, why? What is it about Symbols that
creates such confusion?

Speak of the devil…

In [ruby-talk:168838] [email protected] writes:

On 12/4/05, David A. Black [email protected] wrote:

I understand – but what I meant was, there’s no situation where you
directly do:

[snip]

the_symbol_table.each_row do { … }

Hi David,

No, but you could do Symbols.all_symbols.each do {} :wink:

Regards,

Sean

On 04/12/05, David A. Black [email protected] wrote:

[snip interesting on topic stuff]

as JEG3 suggests,

Ah, have they finally released the new version? Where can I find the
changelog?

cheers,

Brian

[snip]

David
__
David A. Black
[email protected]

“Ruby for Rails”, forthcoming from Manning Publications, April 2006!


http://ruby.brian-schroeder.de/

Stringed instrument chords: http://chordlist.brian-schroeder.de/

gwtmp01 wrote:

When I was first learning Ruby, symbols were a bit of a mystery.
I understand them now, and in hindsight, I don’t really understand
why they were so confusing. In teaching other people about Ruby and
in reading ruby-talk it is quite clear that symbols are an early
stumbling block for learning Ruby. I’d take an educated guess that
people learning Rails (or any other Ruby framework) struggle with
trying to understand if symbols are a magic feature of the framework
or the language or something else.

My question to the list is, why? What is it about Symbols that
creates such confusion? I’m getting ready to prepare a two-hour
“Intro to Ruby” seminar and I’d like to find an approach to Symbols
that cuts through the confusion.

The most common confusion I have seen is the mistaken understanding
that Symbols are variables (or references to variables) instead of
values; things like :x = ‘foo’ and x = ‘bar’; quux = :x.

Secondly, there is the occasional issue of confusing them with
pointers, probably because of their use to access methods and
such.

Once the other hurdles are cleared, the difference between Strings
and Symbols is a bit hazy.

One thought that I’ve had is that Ruby’s reflection capabilities
expose the names of various internal structures (classes, methods,
modules, constants) in a way that is quite foreign to many programmers.
For example, in C you don’t have any runtime access to the symbol table
so you would never see a value that could be mapped to a function like
‘printf’, ‘scanf’, or ‘main’ unless the programmer took the trouble to
construct an explicit symbol table (mapping strings to function
pointers,
for example). An explicit table isn’t much of a mystery.

When you switch to a language like Ruby, Smalltalk, and certainly the
entire family of Lisp languages you are now in an environment where the
data structures of the language runtime are exposed to the programmer.
For a while, the novice will struggle because their mental model of
a runtime environment just doesn’t match their new reality and symbols
just happen to be the bridge between the two worlds. One of the first
features of Ruby that many people learn are the ‘attr*’ methods. Right
off the bat, the novice is exposed to the mappings from strings to
symbols to methods.

Do folks coming from the Lisp/Scheme world have trouble with symbols or
do they absorb symbols right away because they already struggled with
the concept when learning about atoms?

Thoughts?

Gary W.

E