It tells a reader of the code that this term is arbitrary but significant, probably represents an enmeshment with another part of the code, and will not be displayed to any user. When seeing a new term in code that is a lot of the things you're going to need to figure out about it anyway. It's a very valuable & practical signal.
If you need to mutate or concat or interpolate or capitalize or any other string operation it, it probably shouldn't be a symbol anymore, or shouldn't have been to start with.
That's the opposite of reality. Symbols are necessitated by PL semantics, which is why languages which don't have those problematic string semantics tend to not bother with symbols.
> It tells a reader of the code that this term is arbitrary but significant
That you can do that with symbols is not why they exist (you can need to associate additional semantics with pretty much any first or third-party type after all, that's why the newtype pattern is so popular in modern statically typed languages).
And it's not like you need formal symbols to do it in the first place. For instance like an other nearby commenter in Python I do that by using single and double-quoted strings, having taken up that habit from Erlang (where symbols are single quoted and strings are double quoted).
I mean we don't need any of this shit. Go take a long bath and then write some assembly I don't care. Symbols are a useful tool in some languages, for the reasons I described. That you're creating ad hoc quoting conventions to recover part of the functionality of this feature in languages that don't have it is a pretty strong signal I'm correct! Opposite of reality my ass lol.
Oh my bad, great counterpoint.
> The semantics are entirely different!
They're not. A symbol is an arbitrary identifier, which can be used to point to system elements (e.g. classes, methods, etc...). These are all things you can do just fine with immutable interned strings. Which is exactly what languages which have immutable interned strings do.
You'd just have a broken VM if you used mutable strings for metaprogramming in Ruby, so it needs symbols. Both things it inherited from all of Perl, Smalltalk, and Lisp.
Amusingly, string literals interned by default in 3.4 or because of the setting in earlier >2.3 Rubies are still (despite being interned) Strings, while Strings interned with String#intern are Symbols.
Doesn't matter. The parent claim was:
> You'd just have a broken VM if you used mutable strings for metaprogramming in Ruby
From day one it was possible to freeze strings used in metaprograming. I mean Ruby Hashes do that to strings keys.
> Ruby 3.4 making it unnecessary because it is on by default.
That's incorrect: https://byroot.github.io/ruby/performance/2025/10/28/string-...