For a little context, the history constraint isn't mentioned in Liskov's original paper <http://doi.acm.org/10.1145/62139.62141> (1987); it first appears in Liskov and Wing <http://doi.acm.org/10.1145/197320.197383>(1994).
Having said that (my apologies if this is well-trodden ground, I'm New Here), I don't think Liskov Substitution is best thought of as the law of the land, but rather as a useful guideline to be violated only with eyes wide open. And, having said all that, it seems to me that making CharBuf a subclass of String is a square-peg/round-hole situation. I'm gonna read some code now. - Kurt On Fri, Feb 22, 2013 at 6:27 AM, Nick Wellnhofer <[email protected]>wrote: > On 22/02/2013 06:38, Marvin Humphrey wrote: > >> On Thu, Feb 21, 2013 at 4:43 AM, Nick Wellnhofer <[email protected]> >> wrote: >> How about a three-prong strategy which uses both of those approaches and >> adds one more? >> >> * Externally, expose iterators as full-blown, opaque objects. >> * Internally, allocate iterators on the stack using alloca() and access >> the >> struct members directly. >> * To accommodate highly performance-sensitive client code, provide >> access to >> raw string data, so that the client can operate on it using its own >> highly >> optimized and customized routines. >> > > +1 > > > This remains a problem if we make CharBuf a subclass of String. If safe >> iteration is part of String's interface, then a mutable subclass which >> cannot >> support safe iteration violates the Liskov Substitution Principle[1]. >> > > Doesn't a mutable subclass of an immutable class already violate the > Liskov Substitution Principle? See "history constraint" on the Wikipedia > page. > > Nick > >
