| Ruby doesn't have symbols because of AST or VM details. Ruby has symbols in all probability because Lisp and Smalltalk have symbols. It could get most of the same practical upside of symbols from interned strings - the important thing is being able to compare using pointer equality and look up hash tables without needing to walk a string. What symbols at the type level do is ensure that these string-like things have already been interned, that is, de-duplicated, when they hit lookup points like member access. But the implementation could do something very similar behind the scenes by setting a bit on interned string values. Besides, symbols aren't enough for the more advanced dynamic language optimization techniques like you see in V8. |
If your strings are immutable and interned, they are as good as symbols; this is why Python does not have symbols.
ECMASript introduced symbols because JavaScript strings, while immutable, are not necessarily interned. Symbols are much cheaper to compare for equality: you only need to compare the pointers / ids, not actual string bytes.
Lisp has symbols for the same reason: Lisp strings are vectors, which are also mutable.