Please Use Loosely Coupled Pure Subroutines : How To Subdivide Programs

Some people get bent out of shape about superficial style choices in code.  Whenever you work with someone new there is always the “Okay, curly braces should be after a newline” conversation.  I have yet to find someone who writes code in such a way that it makes a difference for me, I don’t care where you put your curlies.  The things we should care about are substantial style choices that make code more reliable and easier to maintain.  For example I think it’s hardly controversial to say that we should name variables so that they match their semantics.  “count” is a better variable name than “c”, just as “widgetCount” is better than “count”.

There is another style consideration in the same vein with which I thought we were all on the same page.  Or at least in short time everyone would be, but it’s been 8 years since I’ve made this revelation and I haven’t seen a change in practices.  So I’m going to cry it out to the world in hopes that people adopt it.  If there was one thing I could tell every programmer that I think would help the State of Software the most, it would be this.

Please use loosely coupled pure subroutines.

Every programming language worth talking about has support for subroutines, all the way down to the assembly level (6502 assembly jsr opcode, c functions, java methods).  We all have to make the decision constantly while programming of when and why to break certain logic into subroutines.  How do you do it?  Let us refer to the Linux Kernel Coding Style document, they have alot of important code with many maintainers, they should have a good idea:

This is more or less the rule I’ve adopted, hopefully you have something similar running through your brain.  Maybe this is controversial, maybe I should be happy stopping here so we can all get on the same page, but no, I’m going to push forward and assume we all agree with some version of this rule.

Different languages have different faculties for limiting scope and mutability, C has Blocks for Structured Programming, Java has Objects with private fields, C++ has ‘const’, etc.  Generally, why do languages have these features?  Because managing context and capabilities in code allows us to work with complex code efficiently by dividing our code into small chunks that are easy to reason about.  When we divide our program into subroutines we can do better by limiting their context and capabilities.  We do this by using loosely coupled Pure Functions.

(For those who don’t know what Pure Functions are, they are functions who given the same input arguments always return the same value no matter the calling context and they cause no side-effect.  Loosely coupled in this context means the subroutines should have the minimal set of information needed to make their calculations, also check out Information Hiding.)

For the purposes of our discussion we’ll say that functions that appear pure by contract are as good as pure.  We don’t care if you have side effects on an object that you created and no one else can see, we aren’t Haskell.

Enough abstract talking, lets bring this principle back to a real language, C#.  C# unlike Fortran or Nim doesn’t have explicit support for pure functions and private methods pass around all the state of the object.  How can we use this principle?  By building our methods from loosely coupled pure static functions:

CalcBar and CalcBaz are loosely coupled pure functions.  What have we gained by dividing our code this way?

  • The temporal coupling between CalcBar and CalcBaz is explicit at the call site in Start, this means Joe Programmer coming back into Start will be less likely to futz that up.
  • CalcBar and CalcBaz can be evaluated on their own merit, all the code and possible data required to understand the code is right between the curlies.
  • CalcBar and CalcBaz are easily and directly testable.  Maybe Foo.Start is difficult to test but there is no excuse not to test CalcBar and CalcBaz if you want to.

Right about now OOP heads are starting to get mad at me.  Cool down my babies, let me explain.  Objects as an abstraction are very stateful, they have public methods with void return types.  If you are working with OOP that’s just how things are done.  I’m not suggesting you write all your code functionally and ditch OOP.  Keep building objects’ public interfaces however you were doing it.  I’m merely suggesting you build those public methods on solid functional footing by dividing them into collections of loosely coupled pure functions.

Now I understand that depending on your situation pure functions might be hard to swing, like I said earlier apparent pure functions are just as good, and loosely coupled functions are better than methods.  You just have to choose the most limiting construct for your subroutine.

If you haven’t read Andrew Hunt’s “The Pragmatic Programmer” I highly recommend it.  It boils down to a list of tips for programming that are useful no matter what tools you are programming with (here is the list tips).  I’m now going to list all of his tips that are apropos to programming with loosely coupled pure functions:

  • DRY—Don’t Repeat Yourself – when you divide your code into loosely coupled pure functions you remove required context which makes your code more reusable
  • Eliminate Effects Between Unrelated Things – this one should be pretty apparent, pure functions are orthogonal by definition
  • Always Design for Concurrency – pure functions factor out state change which makes them easier to reason about in threaded code since they can’t have race conditions
  • Design to Test – public pure functions are easier to test, all you have to do is call them with their input and check the output

If you are already using a functional language, chances are you blew off this article paragraphs ago, but according to TIOBE you probably aren’t.  I honestly think this is the one easiest thing people can start doing to make their code easier to maintain, easier to write, and less buggy.

Software Engineering Parables 3: Project Xanadu


In the 1960’s Ted Nelson inspired a generation with his papers on the future of information and his coined term ‘hypertext.’  The culmination of his thoughts became Project Xanadu.  Project Xanadu was a mixture of the World Wide Web with version control which in his eyes would solve many of the worlds woes.  His assumption was that many of the worlds problems stem from ignorance and misinformation.  It was ambitious and complete in its appraisal of the problem with exchanging and archiving information.  One killer feature that was noted was the impossibility for dead hyperlinks.  Project Xanadu had a  ~20 year head start on Tim Berners-Lee’s World Wide Web, but alas it didn’t ship in time.

This story comes to mind when in Software Engineering we are designing something and the discussion devolves into a chain of minor considerations that complicate the larger goal.  History shows us that the implementation of the web that revolutionized the world was the system that ignored versions and dead-ends, the flawed version is the one that shipped and brought immeasurable value to humanity.


Different Strokes: Process vs Product

Different people get into software for different reasons, and they get into it differently, like almost anything else.  For some people software engineering is a means to a end, for others it is the enjoyment.  In reality most people fall somewhere on that spectrum of enjoyment, process vs product.

I believe I can get along with anyone.  I’m not as good as my wife, she’s a meek sweetheart who everyone likes.  But some of the most challenging relationships in your software career will happen from dealing with people whose raison d’etre is different than yours.  One example is pacing: someone who loaves process but loves product might have a more sporadic schedule where they will avoid the work, psych themselves up, then finally take their medicine and cram.  A classic example of this is probably how most of us did our homework, because homework sucks.  Someone who enjoys software development won’t have an issue working at a more constant rate, until then end of development when the work becomes less interesting of course.

This is where a solid development system and scheduling comes into play, and scrum does a good job at this.  The product people need regular checkups to reduce the amplitude and period of their cram sessions.  The process people need regularly scheduled time to provide feedback on the target.  Small companies can run without a solid system and be productive, but it isn’t sustainable.  Like driving a car around in first gear, the wear on the engine will eventually catch up with you.