I was jigsawing again recently and suddenly there was this feeling of convergence with software engineering.
Jigsaws
There phase that crops up multiple times when I’m doing a jigsaw. I’ve sorted out some set of pieces. That could be edge pieces, ones with green bits or, say, everything to do with faces. Ideally the category is just the right size so the pieces can be laid out and seen all at the same time. That means I can see everything in one glance and it’s easier to pull out the piece I want. That’s easier but not necessarily easy. To start with it might be 100-200 pieces on view. I still have to search.
Piece by piece I work my way through them. Maybe I halve the number of pieces, so that’s 50-100. This is it. I re-arrange the pieces filling in all the gaps. The same stuff but in less space. That’s even easier to search and, with enough repetition, it gets to easy. I’ve been thinking of this as the “densify” phase. Since really noticing it, and starting to write this, I’ve doubled down on the technique and I think it helps.
I do this with code. Well, not exactly this but it feels the same. Densify is not the best word but it hasn’t mattered when it was all in my head. I’ll go with “consolidation” instead, picking the right name matters.
Software development
Now looking at in a previous post I said:
Collecting code together is also a great opportunity to compare how things are being done and notice patterns. This can lead to further consolidation.
Hey, I had the right word already.
So the idea here is to put things into a more concentrated form so you have a better chance of seeing things. This isn’t about cramming things in together. In C++ you could put most of a program in one line but that’s not going to make it easy to understand. You want to balance things between spread out and squashed together, minimise separation but still have separation.
I think you can go about it in a few ways:
- Putting like with like: These functions might already be in one file but separated or they might be scattered across the project. Collect all the, say, file copying functions together. If you were dealing with a build system you might find you copy files, copy files while substituting variables, or copy files only if they have changes.
- Remove unused code: If there is code that is built but never used, behind build flags that are never triggered or simply commented out then can you remove it? Unused code is taking space and attention away from the code that is being used. With less distractions it should be easier to see everything else.
- Build structured data: Create structs or classes around common data rather then deal with individual pieces. It might not be obvious. Maybe one part of your code has
left
,top
,right
andbottom
variables and another hasx
,y
,width
andheight
. Those both sound a lot like rectangles to me. A simple struct removes the need to find about with four separate variables. (While this is great in a codebase it can add complexity between codebases, take care with interfaces.) - Rollback copy-paste repetition: It can noticing exactly the same code in multiple files. However, functions are often copied, changed slightly to deal with a different input or object type, and then left. The functions might be 90% identical and it’s just the core action that differs. In most cases you can change this into one function that does the bulk of the work. That can be wrapped in small functions that set things up and pass in the right parameters for the action you want.
- Increasing line density: Some coding styles spread things out onto different lines a function parameter per line or storing each function result in a variable before using it. Using more horizontal spaces instead means fewer lines.
- Reducing blank lines: Depending on the codebase these can be sprinkled liberally. I think for languages with braces or equivalents then more than one blank line is a waste. Braces show the structure and a single blank line is enough to separate parts of code or entire functions. For languages without braces, Python, then you may need more than that to notice.
In the end
How often is this useful? In my last couple of roles it has been very useful. I’ve been able to find a dozen instances of essentially the same function or replace hundreds of complicated lines with simpler ones across a codebase. I’ve reduced the lines in a file by half or more. At the same time it’s made it easier to find code as it’s sub-divided and grouped better. If you have time it can even be unit tested more easily.
As I said, this isn’t about cramming things together. This re-organising so you can get an overview of more things at once. If the big picture is too big you may never really be able to take it all in.
Leave a Reply