Hi. Thanks for a great post. Also thumbs up for F# as it's a language I enjoy and regret that it is not as popular in .NET world as Scala on JVM.
Still, I can't quite live with that
However, proper OO principles cannot satisfy #2 of the Expression Problem. That is, in a proper OO implementation when I want to add a new behavior to a type with multiple subclasses, I have to go touch every subclass, even if it is just to add a cursory method which throws NotImplementedException.
Maybe I'm not fully following but to me NotImplementedException indicates a violation of interface segregation principle. If we want to add behaviour only to several subtypes does this mean that they should also inherit other interface (ICircumferencable in our case) which contains new method whereas original interface (IShape in our case) will possess just Area property?
Thanks for the comment. You are correct that my statement is for the case not following the ISP (The I in SOLID.) Typically, the comparison for the Expression Problem is between Union Types and subclasses of an abstract class. You could formulate the same with the ISP, but this still does not achieve #2, since you have to touch (add methods to) all classes that should have the behavior. Since the ISP cannot alleviate #2, for my purposes it just trades NotImplementedExceptions -- or alternatively the Null Object Pattern -- for another layer of abstraction to manage and navigate thru. For OO design ISP perhaps adds more value, but here it would just have implied more abstractions.
I believe the value of achieving #2 is having a holistic view of behavior across data cases. Whether base classes or ISP, using proper OO objects means coupling data and behavior. This distributes cross-object behavior into multiple containers (objects), directly at odds with understanding a behavior holistically. Not every problem needs to look at behavior this way, but when you do, organizing them with objects has a very high cognitive load for the developer. That is the primary reason why OO fails to achieve #2 regardless of other applied principles.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Hi. Thanks for a great post. Also thumbs up for F# as it's a language I enjoy and regret that it is not as popular in .NET world as Scala on JVM.
Still, I can't quite live with that
Maybe I'm not fully following but to me NotImplementedException indicates a violation of interface segregation principle. If we want to add behaviour only to several subtypes does this mean that they should also inherit other interface (ICircumferencable in our case) which contains new method whereas original interface (IShape in our case) will possess just Area property?
Thanks for the comment. You are correct that my statement is for the case not following the ISP (The I in SOLID.) Typically, the comparison for the Expression Problem is between Union Types and subclasses of an abstract class. You could formulate the same with the ISP, but this still does not achieve #2, since you have to touch (add methods to) all classes that should have the behavior. Since the ISP cannot alleviate #2, for my purposes it just trades
NotImplementedExceptions
-- or alternatively the Null Object Pattern -- for another layer of abstraction to manage and navigate thru. For OO design ISP perhaps adds more value, but here it would just have implied more abstractions.I believe the value of achieving #2 is having a holistic view of behavior across data cases. Whether base classes or ISP, using proper OO objects means coupling data and behavior. This distributes cross-object behavior into multiple containers (objects), directly at odds with understanding a behavior holistically. Not every problem needs to look at behavior this way, but when you do, organizing them with objects has a very high cognitive load for the developer. That is the primary reason why OO fails to achieve #2 regardless of other applied principles.