"headius (Charles Nutter)" <headius / headius.com> wrote:
> I propose that we eliminate the new "f" suffix and just make the compiler
> smart enough to see literal strings with .frozen the same way.
> 
> So this code:
> 
> str = "mystring".freeze
> 
> Would be equivalent in the compiler to this code:
> 
> str = "mystring"f
> 
> And the fstring table would still be used to return pooled instances.

This is a great idea IMHO.  The backwards compatibility is a huge win
and I think this is the best idea so far regarding frozen strings.

> IMPLEMENTATION NOTES:
> 
> The fstring table already exists on master and would be used for these
> pooled strings. An open question is whether the compiler should
> forever optimize "str".frozen to return the pooled version or whether
> it should check (inline-cache style) whether String#freeze has been
> replaced. I am ok with either, but the best potential comes from
> ignoring String#freeze redefinitions...or making it impossible to
> redefine String#freeze.

Initially (a few minutes ago), I thought it'd be better to inline-cache
to minimize surprise/keep compatibility.  And maybe spew a loud warning on
String#freeze redefinition.

But thinking about this more, string literals are already special.
String#initialize is already ignored for string literals, so perhaps
#freeze may be unredefinedable, as well.

> If we do not want to overload the existing .freeze method in this way,
> we could follow suggestions in http://bugs.ruby-lang.org/issues/8977
> to add a new "frozen" method (or some other name) that the compiler
> would understand.

I think having only .freeze is better (especially for compatibility) and
a new .frozen method would be of minimal benefit.
(But you know Ruby far better than I do)

> I also propose one alternative method name: the unary ~ operator.
> 
> There is no ~ on String right now, and it has no meaning for strings that we'd be overriding. So the following two lines would be equivalent:
> 
> str = ~"mystring"
> str = "mystring"f

I hate this alternative "name".  It's too ambiguous/confusing
(consider: ~"username" or /regexp/ =~ ~"foo"),
not backwards compatible, and hard to search for documentation on.

I think a beginner new to the language would be very confused by this.
You have my strong support of #freeze, but my strongest disapproval of ~

> JUSTIFICATION:
> 
> Making the compiler aware of normal method-based String freezing has the following advantages:
> 
> * It will parse in all versions of Ruby.
> * It will be equivalent in all versions of Ruby other than the fstring pooling.
> * It extends neatly to Array and Hash; the compiler can see Array or Hash with literal elements and return the same object.
> * It does not require a pragma (http://bugs.ruby-lang.org/issues/8976 )
> * It looks like Ruby.

Amen!