Connascence
Every so often I hear or read about the term “Connascence”, especially in the Ruby community. It has always seemed like an interesting idea, but I hadn’t followed up with more research until recently.
Connascence refers to two or more things that are born or produced together, or that grow together. In software, it descibes two entities that are related in such a way that a change to one would require a change to another.
A good place to start for background is the [Wikipedia article on Connascence](http://en.wikipedia.org/wiki/Connascence_(computer_programming). Connascence was originally applied to software by Meilir Page-Jones, but a few years ago, Jim Weirich did a series of talks on the topic:
-
The Building Blocks of Modularity at Mountain West Ruby Conference 2009 gives a good introduction to the topic.
-
Grand Unified Theory of Software Design at Aloha on Rails (2009 or 2010?) is a longer version of the MWRC talk and explains things better, but this video doesn’t show the slides, so it’s harder to follow.
-
Connascence Examined at ETE 2012 is a good follow-on that gives more detail about the types of connascence.
Gregory Brown also wrote a good article, Connascence as a Software Design Metric.
What I find so interesting about connascence is that it is a good way to explain some of the refactoring and design ideas we take for granted every day.
For example, when we extract a hard-coded number or string to a constant, we are reducing Connascence of Meaning to Connascence of Name.
When we replace a set of positional method arguments with a hash, we are reducing Connascence of Position to Connascence of Name.
When we extract a duplicated computation to a method, we are reducing Connascence of Algorithm to Connascence of Name.
At a higher level, Connascence of Execution can be used to inform the kinds of optimizations a compiler might perform, or whether or not it is safe to reorder the statements in a method.
Connascence of Timing explains race conditions.
Connascence of Identity helps us understand the kinds of problems we might run into when serializing or de-serializing an object graph.
Overall, I find this a fascinating topic, and I’m starting to think about the idea consciously in my day-to-day work to see if it helps me make better decisions.
Something I find particularly interesting is that Smalltalk’s keyword message selectors seem to combine Connascence of Position and Connascence of Name.
Consider a method like
SequenceableCollection>>replace:with:from:to:
. This method replaces
one object in a collection with another object, but only within a
limited range of indices. In Ruby, this method would take four
positional parameters and would be somewhat confusing for the caller.
Most advice I’ve seen would recommend using a hash of named parameters
or keyword parameters in Ruby 2.0.
In Smalltalk, the method name communicates both what the parameters mean and the order in which they should appear. I’m still thinking about this, but I think Smalltalk method names only result in Connascence of Name even though they also include an aspect of Connascence of Position. There’s something interesting here, but I haven’t completely figured out what that is yet.
What do you think?