On Wed, Aug 26, 2026 at 7:15 PM David Kastrup <[email protected]> wrote:
> Luca Fascione <[email protected]> writes: > > > I would call it "base" if it made not much sense to use it that level of > > the class hierarchy: > > the base class would have abstract members so you _could_ > not create a Book_base object > But wait, I wasn't making a point about how this is implemented in a language or the other, I was just making a OO-theory point here. The implication I was alluding to was more that use of these "xxx_base" names seems to work well in cases where the type in question sits at a good point in its type hierarchy where you'd like a somewhat heterogeneous collection of things that are related in some ways but differ (sometimes quite a bit) in other ways. I find this difficult to discuss abstractly. An concrete example that comes to me is that in a renderer you'd have a Shape class, which would have subclasses like PolygonMesh and SubvidMesh and NURBSMesh, say. They'll share relatively little code (they'll all tell you their bounds, say, but compute that in very different ways, but they will all also have a name, maybe a source file and location, maybe a shader attachment and it's likely the code for these might sit in that base class). So for some places in the program it'll be real handy to just have a collection of these things and think of them as Shape's without too much inspection (say you might have a factory, and that could just plainly hand you back a Shape reference [*]), while others might need to know more specifically what they're dealing with. [*] Again, an OO-theory "reference", not a C++'s Type& thing. This might be implemented in practice using a shared_ptr<Type> or a unique_ptr<Type> thing if your codebase is C++. Or your system's "pointer-like" thing because you want to memory allocate in specific ways, maybe. Or just a plain object because it's a Python codebase, and you don't even "see" objects as being pointers, names of things just mean "pointer to that thing", right? > If you derive both a rhombus and a rectangle class from a quadrilateral > class, a valid question would be "is this a quadrilateral?". You would > not ask "is this a book base?" though, but there are no actual Book_base > objects. But hang on, I've never seen "is-a" to have this strict/exact behaviour like you're outlining. In all the cases I'm familiar with the "obj is-a Type" relation means: is this object an instance of class "Type" or any of its subclasses. Your function that answers the question "is this a book_base?" could be presented with an instance of the book type or the bookpart type. And it would say "yes" to either of them, whereas if it was presented with a score object maybe, then it would say "no". (I'm not sure what kind of object would be in flight in that area of the code, I'm sure this example seems goofy). What I'm trying to say is that if you have a need to place all the bookparts and books you have in flight into a single collection, and/or you have a big enough portion of your accessors that honestly should work with either one uniformly, then this is the situation that "xxx_base" seems to cover well. Another classic case of this situation is recursive structures: those cases where you have a SetOfThings object that contains Things or SetOfThings, and often it's just awkward to have either Thing inherit from SetOfThings or viceversa, so you make a third class (call it ThingBase) and make them both inherit from it, so that you implement composition using a ThingBase reference [see previous *]. Then you get a structure traverser (say) that only ever needs to know about ThingBase. And this thing might interact with visitors, and some of them might need to tell a Thing apart from a SetOfThings, while other visitors never need that. (Classic case of this in graphics is again the Shape: the bounding routine code has very material clarity gains from being able to look uniform across all your classes of primitives, for example). > It suffers from the fact that we derive both Item and Spanner from Grob, > so LilyPond already uses "Item" for something more specific rather than > something less specific. At least an "Item" again is too unspecific on > its own and falls into lots of different grob types even if they are not > distinguished through the C++ type lattice. > I think this is a key reason why "Item" should not be used here. It's a distant part of the code and you would give it an unrelated meaning. It lowers cognitive overhead on the part of the reader to not have to go and think that an "item" in <these files> means a grob-ish thing, while if you are in <those files> it means a book-ish thing. I know this wouldn't be the entire name of the Type, but it still helps. And again, "base" has served me and my colleagues well is in this role of root of a collection of somewhat related things. It's less attention devoted to this aspect, that can be repurposed for other, likely more valuable work. HTH, L -- Luca Fascione
