Ruby Language Design – Why Use Symbols?

computer sciencelanguage-designruby

tl;dr: Would there be a language-agnostic definition of Symbols and a reason to have them in other languages?

So, why did the Ruby creator use the concept of symbols in the language?

I ask this from the perspective of a non-ruby programmer. I've learned lots of other languages, and found in none of them, the need to specify if I was dealing or not with what Ruby calls symbols.

The main question is, does the concept of symbols in Ruby exist for performance, or just something that is needed because of the way the language is written?

Would a program in Ruby be lighter and/or faster than its, let's say, Python or Javascript counterpart? If so, would it be because of symbols?

Since one of Ruby's intent is to be easy to read and write for humans, couldn't have its creators eased the process of coding by implementing those improvements in the interpreter itself (as it might be in other languages)?

Looks like everybody wants to know only what symbols are and how to use them, and not why they are there in the first place.

Best Answer

The creator of Ruby, Yukihiro "Matz" Matsumoto, posted an explanation about how Ruby was influenced by Lisp, Smalltalk, Perl (and Wikipedia says Ada and Eiffel too):

Ruby is a language designed in the following steps:

  • take a simple lisp language (like one prior to CL).
  • remove macros, s-expression.
  • add simple object system (much simpler than CLOS).
  • add blocks, inspired by higher order functions.
  • add methods found in Smalltalk.
  • add functionality found in Perl (in OO way).

So, Ruby was a Lisp originally, in theory.

Let's call it MatzLisp from now on. ;-)

In any compiler, you are going to manage identifiers for functions, variables, named blocks, types, and so on. Typically you store them in the compiler and forget about them in the produced executable, except when you add debugging information.

In Lisp, such symbols are first-class resources, hosted in different packages, which mean you can add fresh symbols at runtime, bind them to different kind of objects. This is useful when meta-programming because you can be sure you won't have naming collisions with other parts of the code.

Also, symbols are interned at read time and can be compared by identity, which is an efficient way to have new kind of values (like numbers, but abstract). This help writing code where you use symbolic values directly, instead of defining your own enum types backed by integers. Also, each symbol can hold additional data. That's how, for example, Emacs/Slime can attach metadata from Emacs right into a symbol's property list.

The notion of symbol is central in Lisp. Have a look for example at PAIP (Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp, Norvig) for detailed examples.

Related Topic