Why Strings as Classes?

Steven Schveighoffer schveiguy at yahoo.com
Wed Aug 27 21:57:44 PDT 2008


"Nick Sabalausky" wrote
>> Concepts (or better categories (aldor concept not C++), that are 
>> interfaces for types, but interfaces that have to be explicitly assigned 
>> to a type) might relax this situation a little, but the need for some 
>> guarantees will remain.
>>
>
> If this "guarantee" (or mechanism for checking the types of operations 
> that a collection supports) takes the form of a style guideline that says 
> "don't implement opIndex for a collection if it would be O(n) or worse", 
> then that, frankly, is absolutely no guarantee at all.

The guarantee is not enforced, but the expectation and convention is 
implict.  When someone sees an index operator the first thought is that it 
is a quick lookup.  You can force yourself to think differently, but the 
reality is that most people think that because of the universal usage of 
square brackets (except for VB, and I feel pity for anyone who needs to use 
VB) to mean 'lookup by key', and usually this is only useful on objects 
where the lookup is quick ( < O(n) ).  Although there is no requirement, nor 
enforcement, the 'quick' contract is expected by the user, no matter how 
much docs you throw at them.

Look, for instance, at Tango's now-deprecated LinkMap, which uses a 
linked-list of key/value pairs (copied from Doug Lea's implementation). 
Nobody in their right mind would use link map because lookups are O(n), and 
it's just as easy to use a TreeMap or HashMap.  Would you ever use it?

> If you *really* need that sort of guarantee (and I can imagine it may be 
> useful in some cases), then the implementation of the guarantee does *not* 
> belong in the realm of "implements vs doesn't-implement a particular 
> operator overload". Doing so is an abuse of operator overloading, since 
> operator overloading is there for defining syntactic sugar, not for acting 
> as a makeshift contract.

I don't think anybody is asking for a guarantee from the compiler or any 
specific tool.  I think what we are saying is that violating the 'opIndex is 
fast' notion is bad design because you end up with users thinking they are 
doing something that's quick.  You end up with people posting benchmarks on 
your containers saying 'why does python beat the pants off your list 
implementation?'.  You can say 'hey, it's not meant to be used that way', 
but then why can the user use it that way?  A better design is to nudge the 
user into using a correct container for the job by only supporting 
operations that make sense on the collections.

And as far as operator semantic meaning, D's operators are purposely named 
after what they are supposed to do.  Notice that the operator for + is 
opAdd, not opPlus.  This is because opAdd is supposed to mean you are 
performing an addition operation.  Assigning a different semantic meaning is 
not disallowed by the compiler, but is considered bad design.  opIndex is 
supposed to be an index function, not a linear search.  It's not called 
opSearch for a reason.  Sure you can redefine it however you want 
semantically, but it's considered bad design.  That's all we're saying.

-Steve 





More information about the Digitalmars-d mailing list