Re: The quest for value semantics (was: Re: Ugly bug in Foundation, beware!)
Re: The quest for value semantics (was: Re: Ugly bug in Foundation, beware!)
- Subject: Re: The quest for value semantics (was: Re: Ugly bug in Foundation, beware!)
- From: Marcel Weiher <email@hidden>
- Date: Thu, 10 Jun 2004 23:13:30 +0100
See, no bloat! Happy now?
Fixes the bloat issue but not lossless, see above.
Changing the behavior of NSDictionary as it is now was never an actual
proposition, you should have paid attention much, much above. But I am
glad you retract your "bloat" claim. We'll get through the others
eventually. :-))
This becomes a matter of statistics. Ponder on this: If your
machine produces lets say thousand keys a second, where only 0.1
promille is mutable.
Maybe your programs are random string/mutable-string generators.
Mine aren't.
Sorry that it wasn't plainly enough written for you to deduce the
point.
Sorry, it seems you didn't understand your own point.
That is left as an exercise for the student. [Hint: look just above
this section at your own reasoning]
Looks fine.
Ok, it looks like I have to explain it to you:
- on the one hand, you argue that it doesn't matter that mutable string
keys are rare
- yet without even batting an eyelid, you argue that it does matter
that other mutable keys are rare
Which is it? Does frequency matter or does it not? Yes or no? Or is
it the classic case of "it matters when it supports my argument, and it
doesn't matter when it undermines my argument"?
False. The "no extra cost" is only for those cases where it
doesn't occur! Duh!
You really want that mutable string as key, eh ?
Nope. I just don't want that mutable string as (a) value (b) member
of my set (c) element of my array either. So I am going to have get
the mutability of that string removed at some other point, at which
point it won't be problem for the dictionary either.
Let's play a little game, it's called "odd one out".
NSSet - client copies, if necessary
NSArray - client copies, if necessary
NSDict value - client copies, if necessary
NSDict key - dict copies, always
Can you tell which one is different?
Well can you figure out where in these classes you are want to store
an individual object and where you are keeping an index together with
one ? Do the terms key and value and their different meanings ring a
bell ?
You didn't get it, obviously. Two points (1) an NSSet will also have
difficulties if the hash changes, yet here a contract "don't change the
object" is perfectly fine. Why, oh master, is just the contract fine
here, and yet will cause havoc when in an NSDictionary? Are NSSet
users somehow smarter than NSDictionary users? Do they stick to rules
better? (2) If you think that protecting the key is the only issue
here, then you win, well, another Zonk, or probably a number of them.
Actually, three points, so another one: (3) with all the other methods
of storage (including dict values), the client code is "cluttered" with
copies or whatever measures you take to ensure you have what you want,
but for some reason it makes sense to have a special case for
NSDictionary keys, in which case we do not make a copy of the key
(because that would be bloated), but instead rely on the dictionary.
And if we change, for example, from two parallel arrays to an
dictionary, we change the code to copy or not copy. Somehow, all of
that doesn't make senses, especially since the case of a mutable UI
element directly making a key seems exceedingly rare in the first case.
I just did a grepm through my source code, and the overhwelming
majority of key arguments to -setObject:forKey: are string constants,
with some generated NSNumber instances and some keys from other
dictionaries.
[workarounds]
It exists and it works.
That is why it's called a *work*around, yes.
That's why _you_ call it workaround, because you expect too much from
NSDictionary.
I expect a class named NSDictionary to implement a dictionary
abstraction for objects. A reasonable expectation, given the name.
Had it been called NSPropertyListDictionary or NSStringKeyDictionary, I
wouldn't have expected that.
I don't expect NSDictionary to solve these problems in the first place.
NSDictionary doesn't need to "solve" these problems, it just should not
create them without need.
[identity]
NSDictionary as specified is using -hash and -isEqual:
Yes, and NSObject provides implementations, and the docs for hash
(which were posted here before) actually says that the hash it is
doing (independent of value!) is a good one for mutable objects
placed in collections!
It actually says that mutable objects in collections are dangerous.
Yes. And that you simply shouldn't change them while they are inside.
And that you should use a hash that does *not* depend on these values
(a fact you keep conveniently overlooking)! Such a recommended hash
will break in a NSDictionary!
[snip]
> Mutable objects in collections that exhibit varying hash and isEqual:
like NSMutableString break things:
False. Mutable objects in collections are just fine, as long as you
don't mutate them.
For example (typed into mail):
void store( id dict, int lots ) {
id str = [NSMutableString stringWithFormat:@"%d ",lots];
[str appendString:@"of implementations work with mutable strings in
dicts and run just fine"];
[dict setObject:@"it works!" forKey:str];
}
This has a mutable string key, yet it is absolutely fine, copying gains
nothing and only slows us down.
According to you, every Smalltalk system on the planet should
experience constant breakdowns, because none of them copy they
dictionary keys. Yet somehow, against the odds, they run just fine,
and use dictionaries quite a lot.
So, it seems that reality and your view of reality are in disagreement.
Which do you think should be adjusted?
Or differently, why do you think the rationale for a NSCopying
protocol is there in the first place ?
I have never seen a rationale for the NSCopying protocol, and quite
frankly, find it somewhat superfluous.
I think the rationale for the existence of NSCopying goes hand in hand
with the distinction of immutable and mutable classes.
Which is one that doesn't actually hold water once you look at it more
closely, see the immutable NSArray changing for a simple example.
As certain classes wanted to have their private immutable copies of
parameters. Like accessors, like NSDictionary....
Well, copying accessors have similar problems in that you penalize the
entire system by trying and failing to have a blanket solution to the
issue of mutability, which you simply cannot get in a language with
references, mutable state and even pointers and introspection, meaning
I can actually change the value even of so-called immutable objects.
You will reply that I shouldn't do that, but that, again, is just a
contract.
I suspect the original designers of Foundation long left NeXT/Apple,
noone there knows the fundamental design decisions anymore, and so
they don't shed a light on anything in this discussion. :)
They wanted to have "value" semantics, wether that was ever consciously
formulated or not. This is somewhat understandable, because value
semantics can be quite nice. And they even managed to pull it off for
some very simple classes and common use-cases, with some clever tricks
(like copy mapping to retain and thus not costing anything for common
cases -> I don't dispute that this is clever).
But, it seems they got carried away and thought that the mechanisms
they had put in place would scale, and the simple fact is that they
don't. The whole idea of immutability breaks down rather rapidly (in
an imperative language with references and mutable state (and even
pointers!) like Objective-C, with strings just ever so barely making it
if you look just right. For all the collections that contain objects
it is already essentially meaningless.
Cheers,
Marcel
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.
References: | |
| >Ugly bug in Foundation, beware! (From: Ondra Cada <email@hidden>) |
| >Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Alastair Houghton <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Ondra Cada <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Alastair Houghton <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Brent Gulanowski <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Alastair Houghton <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Ondra Cada <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Marcel Weiher <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Brent Gulanowski <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: "Louis C. Sacha" <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Marcel Weiher <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Nat! <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Marcel Weiher <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Nat! <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Marcel Weiher <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Nat! <email@hidden>) |
| >Re: Is that really a bug at all? (was: Re: Ugly bug in Foundation, beware!) (From: Marcel Weiher <email@hidden>) |