The Limited Construct Principle

I would like to present a new guiding principle for software development along the lines of the SOLID principles. It’s not really a new principle because argue from this principle often, however I am not aware of it being stated anywhere explicitly. I call it the Limited Construct Principle. Simply put it means that given a choice between multiple programming constructs you should choose the most limited, one that can accomplish the task. Why? Well the reasoning is that a more limited construct will always communicate your intention more clearly than a less limited one. Let’s look at some examples

GOTO vs Structured Programming

The first one I would like to address is the source of this blog post by Robert Martin. The GOTO statement can easily perform the function of if-then-else, while loops, for loops, function calls etc. However seeing the GOTO statement gives the reader no indication of what the intention is. No indication of what form of flow control is coming next. Furthermore since all forms of flow control are possible with the use of structured programming and all individual structured programming constructs are more limited than GOTO the Limited Construct Principle would indicate that we should never use GOTO. This is in fact strongly recommended.

Access Modifiers

Many languages allow the user to specify whether a variable is public or private to the scope of a class/namespace. Since private is more limited following LCP would indicate that we should always make our variables private unless we need them to be public. Stack overflow agrees. In addition to communicating your intention to human readers of the code the access modifiers also communicate intention to the computer allowing your editor to tell you a private variable is never used and can be safely deleted or simply not include that code when compiling. This concept is so powerful that even in language that don’t have public/private as first class concepts people have figured out a way to effectively implement it using closures and it is now considered best practice.

Collection Operations

In C# we can use a for statement or a foreach statement to iterate over a collection. The foreach statement is more limited because it can only operate on a single item in the collection at a time so we would generally choose the foreach statement and when we choose the for loop it would be an indication we want to do something more complicated (order probably matters!). However if we’re performing some of the more frequent collection operations we should use the LINQ methods that are even more limited and specific such as Select for transformation and Where for filtering. This indicates our intention. Note that the principle is still applicable even if the language itself does not strictly enforce the limitations (although it’s still better if it does). For example it is possible to keep track of the previous item in a foreach loop or mutate the objects in a collection during a where but you shouldn’t because the construct you chose indicated you wouldn’t.

Immutable Data Constructs

Clearly immutable data is a more limited construct than mutable data so LCP would indicate that we should always use an immutable data construct unless it is necessary for the data to change. Many functional languages have constructs that support this concept, in F# all data is immutable unless you specify otherwise, similarly Clojure provides specific constructs for different forms of mutability. Immutable data immediately communicates a great deal to any reader of your code. For example if you pass immutable data into a function you know that the after the function you will still have the same piece of data. However although it is possible to model immutable data structures in C# I do not generally choose to do so, primarily this is because C# makes working with immutable data a poor choice in many situations both because of performance concerns and ugly verbose syntax. Thus the application of LCP should be balanced against any additional programmer work or extra code required. As much as I would prefer to use immutable data in C# the language pushes me not to.

If we follow Limited Construct Principle consistently we will make our code easier to follow and reason about. Limited constructs will make it more immediately apparent how they are going to be used, easing the mental burden of the reader. Then when we use more capable constructs we will be clearly communicating that those capabilities are intended to be used.

 

Leave a Reply

Your email address will not be published. Required fields are marked *