3 ms·
> No one should ever use inheritance in any long-term production use case without some way of enforcing strict discipline, ensuring that calls can only go one w
by rramadass 2y ago
> No one should ever use inheritance in any long-term production use case without some way of enforcing strict discipline, ensuring that calls can only go one way -- up or down, but not both. I don't know to what extent tooling to enforce this discipline exists.
Disagree with your first part. Inheritance used to express Subtyping is different from that used for Code-reuse and yet again different from that used for implementing Framework skeleton structure. You have to disambiguate them carefully when using it. See the article linked to by user "Fannon" here - https://news.ycombinator.com/item?id=42789466 https://news.ycombinator.com/item?id=42789466
As for tooling, you have to enforce the contract using pre/post/inv clauses following Meyer's DbC and also explicit documentation.
- sunshowers 2y agoThanks for that article -- I have to agree with Jacob Zimmerman in the comments to the article: > I don’t get it. I read one part of the article, think I get it, then I read a different part and what I read there doesn’t jive with what I thought I understood. And I can’t figure out how to reconcile them. --- > As for tooling, you have to enforce the contract using pre/post/inv clauses following Meyer's DbC and also explicit documentation. I think we call them asserts and type-level state machines :) I don't really believe in documentation as enough of a barrier to doing worse things. It must, at a structural level, be easier to do better things.
- rramadass 2y agoThere is no confusion if you understand that Inheritance is just a "mechanism" to express three (and maybe more) different kinds of "policies" and a single class may implement any or all of them in which case it becomes important to disambiguate which methods/functions express which "policies". There is a abstract concept and a syntactical expression of that concept which needs to be clear in one's mind. Again, asserts are just the "mechanism" to express pre/post/inv "policies" in code. Without having an understanding of pre/post/inv from the pov of Hoare Logic, merely using asserts will not give you much benefit. Documentation is quite important here. Both the above can be seen in the design of the Eiffel Language where they are integrated into proper syntactical mechanisms. Once you understand the concepts here, you can apply them explicitly even if your language does not support the needed syntax (eg. Contracts). See Bertrand Meyer's OOSC2 for details - https://bertrandmeyer.com/oosc2/ https://bertrandmeyer.com/oosc2/ Specifically "Design-by-Contract (DbC)" and "Inheritance Techniques" and "Using Inheritance well". Also relevant is my other comment here - https://news.ycombinator.com/item?id=42788947 https://news.ycombinator.com/item?id=42788947
- sunshowers 2y agoI agree that inheritance does too many things and has too many degrees of flexibility. I think other kinds of polymorphism like typeclasses don't have this issue, and are better due to that. Automation is highly preferable to documentation. I think the discussion would benefit from you concretely working through an example. What change(s) are you proposing to how inheritance is done in C++ or Java, and how would they prevent spaghetti code and nested upcalls/downcalls?
- rramadass 2y agoI am not sure that you understood what i wrote. Inheritance's flexibility is its very strength that allows you to express different concepts elegantly. Also no amount of Automation/Tooling/etc. can substitute for documentation explaining the intent behind the code. The main thing i would like to see in C++/Java/whatever is support for "Design-by-Contract" (DbC) similar to that given in Eiffel. There is already a proposal for C++; see this recent HN discussion - https://news.ycombinator.com/item?id=42131473 https://news.ycombinator.com/item?id=42131473 Basically this is a way to apply Hoare Logic to functions/methods directly in the implementation language itself. Now use this across the types/classes in a inheritance hierarchy and you can enforce the semantics that you want to express. Regarding a concrete example; I have already pointed you to Bertrand Meyer's OOSC2 and three specific chapters to read; They walk you through proper examples with explanations. Additionally also see his Applying Design By Contract paper (pdf) here - https://se.inf.ethz.ch/~meyer/publications/computer/contract.pdf https://se.inf.ethz.ch/~meyer/publications/computer/contract.... If you would like to see complete application code using a C++ OO framework i suggest creating a sample MFC app using Visual Studio C++ wizard and just looking at the generated code without adding anything of your own. It uses a Document/View architecture (a variation of MVC) where your app specific classes derive from MFC framework given classes. The framework invokes your derived methods (i.e. downcall) which can as needed call back to base's method (i.e. upcall). There is a strong coupling between the framework classes and your app specific ones by design. You can see how different usages of inheritance are implemented to give a powerful app framework; see documentation starting here - https://learn.microsoft.com/en-us/cpp/mfc/document-view-architecture?view=msvc-170 https://learn.microsoft.com/en-us/cpp/mfc/document-view-arch...