DEV Community

Discussion on: Solving the Expression Problem in any language

Collapse
 
bohdanstupak1 profile image
Bohdan Stupak

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?

Collapse
 
kspeakman profile image
Kasey Speakman • Edited

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.