String as Subclass of Symbol?

Speaking of

i might add that i hope whatever keys object will hash key and symbol
arguments the same so we can do

   val = keys['foo']

or

   val = keys[:foo]

Has it ever been considered making String a de-immutablized subclass of
Symbol? Would this allow for a natural coersion of Symbols to Strings,
akin to Integer to Float? The above is a common enough occurance. And
in general I can't think of a signifficant occurance in which I needed
to distingusih a symbol from a string of the same basic value (ie. :foo
and 'foo') for the same parameter. I suspect there really is no good
reason to ever do so --b/c if you are, you're doing something rather
tricky that probably should be done another way. Of course if anyone's
got a good counter example please share.

Not that I've fully work this idea through, but I suppose the upshot
would be two fold:

  1) Certain method could coerce symbol to string when deemed
appropriate,
     such a Hash#.

  2) If a Symbol doesn't respond to a method then coerce to String and
try that.
     (Perhaps certain methods would need to be excluded?)

This raises one other issue that hadn't occured to me before. String in
future Ruby will be advance beyond ascii, I assume Symbol will follow
suit. True?

T.

Has it ever been considered making String a de-immutablized subclass of
Symbol? Would this allow for a natural coersion of Symbols to Strings,
akin to Integer to Float? The above is a common enough occurance. And
in general I can't think of a signifficant occurance in which I needed
to distingusih a symbol from a string of the same basic value (ie. :foo
and 'foo') for the same parameter. I suspect there really is no good
reason to ever do so --b/c if you are, you're doing something rather
tricky that probably should be done another way. Of course if anyone's
got a good counter example please share.

Not that I've fully work this idea through, but I suppose the upshot
would be two fold:

  1) Certain method could coerce symbol to string when deemed
appropriate,
     such a Hash#.

This is inappropriate behavior. Attempting to mix strings and symbols for hash keys is bad design. Pick one and stick with it.

Rails' HashWithIndifferentAccess has unintuitive behavior, I don't want that unintuitive behavior copied to Ruby. For example, what class are the keys?

  2) If a Symbol doesn't respond to a method then coerce to String and
try that.
     (Perhaps certain methods would need to be excluded?)

If there are already doubts about its usefulness it is probably a bad idea. I don't want to have devote more brain-space to remembering what classes of objects I send to methods.

···

On Oct 24, 2005, at 7:17 AM, Trans wrote:

--
Eric Hodel - drbrain@segment7.net - http://segment7.net
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04

Hi --

Speaking of

i might add that i hope whatever keys object will hash key and symbol
arguments the same so we can do

   val = keys['foo']

or

   val = keys[:foo]

Has it ever been considered making String a de-immutablized subclass of
Symbol? Would this allow for a natural coersion of Symbols to Strings,
akin to Integer to Float? The above is a common enough occurance. And
in general I can't think of a signifficant occurance in which I needed
to distingusih a symbol from a string of the same basic value (ie. :foo
and 'foo') for the same parameter. I suspect there really is no good
reason to ever do so --b/c if you are, you're doing something rather
tricky that probably should be done another way. Of course if anyone's
got a good counter example please share.

Not that I've fully work this idea through, but I suppose the upshot
would be two fold:

1) Certain method could coerce symbol to string when deemed
appropriate,
    such a Hash#.

2) If a Symbol doesn't respond to a method then coerce to String and
try that.
    (Perhaps certain methods would need to be excluded?)

This all sounds a bit paradoxical: you're suggesting that String be a
subclass of Symbol (which means that a string would have Symbol's
instance methods in its lookup path), while symbols would (in effect)
resort to String's instance methods in the course of trying to resolve
methods. That sounds like a kind of two-way inheritance.

Which, in turn, means that inheritance probably isn't the solution to
the problem you're trying to solve. I don't think I've understood the
problem yet, though. The main problem I've seen with strings and
symbols is a tendency toward excessive conversion; I've often seen
things like:

   %w{ a b c }.each {|meth| define_method(meth.to_sym) ... }

I think there's a somewhat exaggerated sense of the speed-up factor
involved in symbols sometimes.

David

···

On Mon, 24 Oct 2005, Trans wrote:

--
David A. Black
dblack@wobblini.net

Has it ever been considered making String a de-immutablized subclass of
Symbol? Would this allow for a natural coersion of Symbols to Strings,
akin to Integer to Float? The above is a common enough occurance. And

Love your crazy ideas!

The main problem I see with this idea is that for "String < Symbol", a
string must be expected to behave polymorphically like a symbol. Now, the
only behaviour missing is immutability (I don't think the two methods
id2name and to_int present an issue), but that's different enough -- if
you're expecting an immutable symbol, what happens if it changes? (This is
pertinent for hash keys, for example.)

Now, Symbol < String actually makes sense to me, despite all the extra
methods. Symbol could redefine most of the methods in
(String.instance_methods - Symbol.instance_methods) to return a new mutable
string. That would give your proposed automatic conversion. But this still
leaves the problem of the behaviour of the mutator methods, <<, gsub!, et.
al. -- these cannot work properly on a symbol; they'd have to be undefined
or raise a NotImplementedError.

And I think that works OK, and it's backwards-compatible except for:
  if var.kind_of?(String) then var.chomp! end
and possibly
  begin
    var.chomp!
  rescue NoMethodError
  end

Cheers,
Dave

Eric Hodel wrote:

> Has it ever been considered making String a de-immutablized
> subclass of
> Symbol? Would this allow for a natural coersion of Symbols to Strings,
> akin to Integer to Float? The above is a common enough occurance. And
> in general I can't think of a signifficant occurance in which I needed
> to distingusih a symbol from a string of the same basic value
> (ie. :foo
> and 'foo') for the same parameter. I suspect there really is no good
> reason to ever do so --b/c if you are, you're doing something rather
> tricky that probably should be done another way. Of course if anyone's
> got a good counter example please share.
>
> Not that I've fully work this idea through, but I suppose the upshot
> would be two fold:
>
> 1) Certain method could coerce symbol to string when deemed
> appropriate,
> such a Hash#.

This is inappropriate behavior. Attempting to mix strings and
symbols for hash keys is bad design. Pick one and stick with it.

Easy to say, but not so easy in practice. Often it is not just a matter
of catering to ourselves but to others, some prefer to use strings over
symbols and vice-versa. But more importantly consider the difference in
the system itself. #method_missing carries a symbol, yet
#instance_methods returns strings. One has to deal with such things in
interchange.

The idea I'm inquiring about here, is that perhaps symbols and strings
should not thought of as wholly separate things. The symbol is a string
but immutable and light-weight. Thus it is more suitable to certain
scenarios, such a keys. Strings are just symbols "upclassed", mutable
with a larger method set, hence for more veritile usage. In this way we
could see them more as "modes" of essentially the same thing. And I
think this may be a very useful way to percieve it, that potentially
could bring an end to the all too common:

  def (x)
   x = x.to_sym

or

  def (x)
   x = x.to_s

Rails' HashWithIndifferentAccess has unintuitive behavior, I don't
want that unintuitive behavior copied to Ruby. For example, what
class are the keys?

I am not familiar with HashWithIndifferentAccess, what does it do
exactly and how is it unintuitive?

> 2) If a Symbol doesn't respond to a method then coerce to String and
> try that.
> (Perhaps certain methods would need to be excluded?)

If there are already doubts about its usefulness it is probably a bad
idea. I don't want to have devote more brain-space to remembering
what classes of objects I send to methods.

You misinterpret. Not doubt in usefulness, just working out certain
methods, like #class is an obvious excpetion, etc.

Whether there are any serious _technical_ issues with this idea, I'd
like to know. That's why I've inquired.

T.

···

On Oct 24, 2005, at 7:17 AM, Trans wrote:

David A. Black wrote:

This all sounds a bit paradoxical: you're suggesting that String be a
subclass of Symbol (which means that a string would have Symbol's
instance methods in its lookup path), while symbols would (in effect)
resort to String's instance methods in the course of trying to resolve
methods. That sounds like a kind of two-way inheritance.

Sort-of. The inheritance isn't strictly neccessary for what I am
suggesting. For instance, compare Integers which can be coerced to
Floats, although Float is not a subclass of Integer. But there is a
relationship here b/c one can easily imagine them as such: subclass
Integer and add an attribute for the fractional part. So while the
subclassing is not a must, I suggest it b/c it actually fits into the
overall concept and in this particular case makes a great deal of
sense: Symbols and Strings encode the same kind of data. The sole
difference is in mutability and the methods included.

Hmm.. .let me try to explain that a tad better. I think the fact the
they are readily capable of a class <-> subclass relationship, is what
allows the possiblity of auto-coercion in the first place. If they did
not there would be be no obvious and essentially trivial process by
which to coerce. Does that make sense?

So in a way you are right, it is a kind of two-way inheritance. And if
you think about the orgins of Symbol one can more understand why.
Symbols did not originally exit in Ruby. They were added later as a
light-weight substitute for Strings. So indeed their very existance is
one intended to easily interchange depeding on the usage.

Which, in turn, means that inheritance probably isn't the solution to
the problem you're trying to solve. I don't think I've understood the
problem yet, though. The main problem I've seen with strings and
symbols is a tendency toward excessive conversion; I've often seen
things like:

   %w{ a b c }.each {|meth| define_method(meth.to_sym) ... }

Although that is a rather direct "abuse" if you will. We are used to
method names being represented a symbols, so we overlook that
#define_methed and the like will handle the conversion for us --But
that is a perfect example of how this type of coercion is already going
on all over the place, only it's being done manually. My premise, and
essentially the problem, is that we are wasting out efforts hadling
this manually when it can be done automtaically, moreover, because of
the extra coding involved one programmer may only support symbols,
another strings. Which means any programmer interfacing two such
systems will have to compensate. And becuase we don't generally see
each other code (assuming good black-box components) we have multiple
to_sym or to_s being applied to the same parameter as it is passed
along --quite inefficient.

I think there's a somewhat exaggerated sense of the speed-up factor
involved in symbols sometimes.

That may be the case, but then why have symbols?

Thanks,
T.

Dave Burt wrote:

Has it ever been considered making String a de-immutablized subclass of
Symbol? Would this allow for a natural coersion of Symbols to Strings,
akin to Integer to Float? The above is a common enough occurance. And

Love your crazy ideas!

The main problem I see with this idea is that for "String < Symbol", a string must be expected to behave polymorphically like a symbol. Now, the only behaviour missing is immutability (I don't think the two methods id2name and to_int present an issue), but that's different enough -- if you're expecting an immutable symbol, what happens if it changes? (This is pertinent for hash keys, for example.)

Now, Symbol < String actually makes sense to me, despite all the extra methods. Symbol could redefine most of the methods in (String.instance_methods - Symbol.instance_methods) to return a new mutable string. That would give your proposed automatic conversion. But this still leaves the problem of the behaviour of the mutator methods, <<, gsub!, et. al. -- these cannot work properly on a symbol; they'd have to be undefined or raise a NotImplementedError.

FWIW, Most Smalltalk class hierarchies have Symbol < String.

VisualWorks' class comment describes a Symbols as "... Strings that are represented uniquely."

···

And I think that works OK, and it's backwards-compatible except for:
  if var.kind_of?(String) then var.chomp! end
and possibly
  begin
    var.chomp!
  rescue NoMethodError
  end

Cheers,
Dave

--
Daryl

Dave Burt wrote:

> Has it ever been considered making String a de-immutablized subclass of
> Symbol? Would this allow for a natural coersion of Symbols to Strings,
> akin to Integer to Float? The above is a common enough occurance. And

Love your crazy ideas!

Thanks :slight_smile:

The main problem I see with this idea is that for "String < Symbol", a
string must be expected to behave polymorphically like a symbol. Now, the
only behaviour missing is immutability (I don't think the two methods
id2name and to_int present an issue), but that's different enough -- if
you're expecting an immutable symbol, what happens if it changes? (This is
pertinent for hash keys, for example.)

Now, Symbol < String actually makes sense to me, despite all the extra
methods. Symbol could redefine most of the methods in
(String.instance_methods - Symbol.instance_methods) to return a new mutable
string. That would give your proposed automatic conversion. But this still
leaves the problem of the behaviour of the mutator methods, <<, gsub!, et.
al. -- these cannot work properly on a symbol; they'd have to be undefined
or raise a NotImplementedError.

And I think that works OK, and it's backwards-compatible except for:
  if var.kind_of?(String) then var.chomp! end
and possibly
  begin
    var.chomp!
  rescue NoMethodError
  end

I considered this, but it doesn't do well with the methods. It doesn't
make much sense to undefine all those methods, and not doing so would
make symbol much heavier, as would making it a subclass to begin with.
I think David makes a good point, it's more like Symbol <-> String. So
it can be thought of as going either way, but which way is more
advantageous?

Probably the first question to ask: does it even makes sense for a
subclass of an immutable to become mutable? Is that reasonable or even
possible?

But beyond that the coercion issue stands on it's own, String does not
need to be a subclass of Symbol or vis-versa for that to work. And
really this is the more significant concept here. Although if
subclassing facilitates that, even better.

Thanks,
T.

Trans wrote:

So in a way you are right, it is a kind of two-way inheritance. And if
you think about the orgins of Symbol one can more understand why.
Symbols did not originally exit in Ruby. They were added later as a
light-weight substitute for Strings. So indeed their very existance is
one intended to easily interchange depeding on the usage.

When were symbols introduced? I think it was quite some time ago.
Definitely a 20th-century feature.

Who described them as a "lightweight substitute for strings"?

I think there's a somewhat exaggerated sense of the speed-up factor
involved in symbols sometimes.

That may be the case, but then why have symbols?

They're immutable. They're easier to type. They're singletons in a
sense, so they save memory.

Hal

Hal Fulton wrote:

Trans wrote:
> So in a way you are right, it is a kind of two-way inheritance. And if
> you think about the orgins of Symbol one can more understand why.
> Symbols did not originally exit in Ruby. They were added later as a
> light-weight substitute for Strings. So indeed their very existance is
> one intended to easily interchange depeding on the usage.

When were symbols introduced? I think it was quite some time ago.
Definitely a 20th-century feature.

Ruby 1.6.0 introduced Symbols in a stable release.

Who described them as a "lightweight substitute for strings"?

Symbols are more lightweight objects than strings, since they are
immediates like fixnums.

                                                       matz.

>>I think there's a somewhat exaggerated sense of the speed-up factor
>>involved in symbols sometimes.
>
> That may be the case, but then why have symbols?

They're immutable. They're easier to type. They're singletons in a
sense, so they save memory.

All good (and lightweight) reasons.

T.

Trans wrote:

Hal Fulton wrote:
> When were symbols introduced? I think it was quite some time ago.
> Definitely a 20th-century feature.

Ruby 1.6.0 introduced Symbols in a stable release.

This doesn't seem right, though I'm not sure.

Are you sure that isn't just when the Symbol *class*
was introduced?

Symbols, as I recall, used to be essentially Fixnums.

Hal