JavaScriptCore merge & binary compatibility

Maciej Stachowiak mjs@apple.com
Mon, 17 Feb 2003 22:28:56 -0800


On Monday, February 17, 2003, at 08:39  PM, Peter Kelly wrote:

> What we can do there is add a flag to UString::Rep to indicate whether 
> or
> not it's in the string pool. Then when doing a comparison we can check
> this and if it's set just compare the pointers. e.g.:

This is certainly possible. However, it's usually better design to make 
a new class or use a subclass instead of putting if 
(isThisASpecialObject) in the code. If you have a lot of ifs like this, 
you create a situation where two objects are the same class but behave 
in a permanently and systematically different way.

In addition to the special case in ==, you would probably need a 
separate constructor for making an atomized string, an explicit atomize 
operation, and a way to tell if a string has been atomized. You'd also 
need to make sure to atomize strings before storing them in places 
where it might matter, such as property names stored in a property map.

It's common in many other languages and systems for an atomized string 
to be represented by a different type, just so you always know exactly 
what you are dealing with. For example, Lisp dialects have a symbol 
type that is distinct from strings (but can converted back and forth). 
The X Window System has atoms that are distinct from char *. In 
Objective C, there is the concept of "selector" which is basically an 
atomized string representing a method name. Personally, I think it is 
cleaner to follow this common design pattern than to have some strings 
behave specially.

Another thing worth noting is that the code hardly ever converts 
between Identifier and UString except in specialized circumstances like 
debugging output. This to me is another sign that usage is orthogonal, 
so it makes sense to have separate classes.

Anyway, if you try hard enough, you may find a way to make this 
specific change without breaking compat. But I think some of the 
optimizations Darin and I did pretty much unavoidably require breaking 
compat, since they add new virtual methods, inline existing methods, 
and intentionally make objects smaller as the goal of the 
optimizations. So if compatibility is going to be broken anyway, I 
think you may as well use the clearer version. Breaking binary compat a 
little bit is basically the same as breaking it a lot, so unless you 
can get it down to 0, it's not worth going to extremes to preserve bin 
compat.

I hope you will keep these thoughts in mind as you evaluate our changes/

Regards,

Maciej