> What I'm trying to say is that the main reason why symbols exist in
> Ruby in the first place is performance from what I've been told.

Correct, and your proposed changes would completely nullify those
performance benefits (see below).

> People reading some Ruby book will notice that it is not particularly
> designed with performance in mind but it is designed mostly towards
> programmer's happiness. If that is the case, then worrying about
> bothered programmers makes sense to a language like Ruby in my
> opinion.

So basically what you're saying is "Ruby is written for happiness and
not performance, lets make it even more slow!". I'd rather see a world
where Ruby is both fast (enough) and easy to use instead of it being
easy to use and slower than a sloth.

Regarding the benchmarking information, you're missing a crucial aspect.
While the numbers in the specific examples I gave both clearly show that
the use of Strings is substantially slower. Yes, it's "only" 112 kb but
the difference will keep growing and growing until you hit your memory
limit.

This is exactly one of the reasons Symbols exist: to make it easier and
faster to use commonly re-used Strings. The best example of this are
Hash keys.

> This isn't possible when you're serializing/deserializing using some
> library like JSON or any other. You don't control how hashes are
> created by such libraries.

Of course it is. Marshal allows you to store arbitrary Ruby objects
(with the exception of a few such as Proc instances), in other cases you
can re-create your objects based on the supplied Hash.

If you do not like using raw Hashes the solution in my opinion is not to
more or less re-write Ruby (and break everything that exists in the
process) but instead solve this on your own application level. Using
Hashie is one example but another one, one I consider far better, is to
use your own classes. Consider the following:

    hash = {'id' => '123-abc-456', 'body' => 'hello'}

    if hash['id'] and !hash['id'].empty?
      puts "Processing message ID #{hash['id']}"
    end

    if hash['body'] and !hash['body'].empty?
      do_something(hash['body'])
    end

This is not a flaw in your proposal in particular but it's one of the
reasons why I'm not a big fan of using Hashes all over the place. If in
this example the "id" key is suddenly changed to "ID" you now have at
least 3 places where you have to modify your code and most likely other
places further down the line. This can be solved by doing something as
simple as the following:

    class Message
      attr_reader :id, :body

      def initialize(options)
        @id   = options['id']
        @body = options['body']
      end

      def has_id?
        return @id && !@id.empty?
      end

      def has_body?
        return @body && !@body.empty?
      end
    end

This allows you to write the following instead:

    message = Message.new({'id' => '123-abc-456', 'body' => 'hello'})

    if message.has_id?
      puts "Processing message ID #{message.id}"
    end

    if has_body?
      do_something(message.body)
    end

In this specific example it may seem a bit like an overkill but if that
Hash gets used in a dozen places you can save yourself tremendous
amounts of time by just wrapping a class around it.

Yorick