Programmers spend an inordinate amount of time typing. Frances Buontempo wonders whether this can be curtailed.
Last time I wrote about using labels and typecasting people. I still don’t know what label I’d choose for myself and I don’t know what to write about for an editorial either. Besides anything else, my typing has taken a nosedive recently. I really must practise with gtypist or similar. Remote pairing sessions seem to mean I get flustered and can’t remember where the letters or symbols are. I suspect some of the trouble comes from listening, looking at someone, typing and thinking simultaneously. Some days it’s easier to multitask than others.
Remote pairing or ensemble sessions can take on various forms. Some IDEs allow you to all connect to one session, which avoids the problem of having to push broken code for another team member to pick it up. You could copy code into a chat, but many chat app do very nasty things to whitespace, line endings and the like. I’m using Teams at work currently, which has a propensity to make code appear yellow on a green background when pasted into a chat, aside from messing with the contents. Looking at it makes me feel green, perhaps in sympathy. As an alternative to typing, we can resort to a call. We can even sketch a diagram. I prefer pen and paper or whiteboards, but there are many online collaboration tools. I always then spend far too long trying to work out how to move, focus or add text boxes, all the while muttering “I hate GUIs”. The thing about a piece of paper is it has a fixed size and clear edges, which affects what you choose to draw. Constraint can be liberating. A software tool may allow extension in all directions for a very long way. Finding anything afterwards can be a challenge. The old saying goes “A picture is worth a thousand words”, but if that picture has over a thousand labels and comments, not to mention arrows and other mystic symbols, words may well have been more succinct. Less is more and drawing clear diagrams is a skill.
Documenting things well is also a skill. I recently noticed when our business analysts ask for documentation they mean write down what was decided, so people know afterwards. As a programmer, when I hear the word documentation, I tend to groan. I have tried to use so many APIs, libraries and the like with pages and pages of instructions. Various things go wrong. Sometimes I am reading the wrong version for the tool I am using. Many cutting edge tools change at a huge pace, so it’s easy to waste time trying something that either no longer works or will only work after an upgrade, breaking many other things in the process. Other times, scroll bars are involved. You ever had that thing where you open a man page, start reading, page down, keep reading, notice something interesting you didn’t know, try it out, forget what you were trying to do, then remember, scroll further, try to find an example, give up, look on stack overflow, desperate for an example to copy and twiddle with, finally finding one using a totally different tool that you then install? And so it continues. Maybe it’s just me? That was, of course, far too many words to illustrate an example we are probably all familiar with. Too many words, people. Think back to documentation you have written. Was it useful for anyone? Have you ever re-read something you’ve previously written? I usually spot typos or similar when it’s too late, however that’s not what I’m talking about. Writing can tend to fall into one of two camps – either almost no details, so not much use, or every possible detail but no high level “How to start” or similar. If you have trouble documenting code, or writing blogs or articles, try to notice writing you like and ask yourself why. What’s good about it? How is it presented? Are the sections helpful and easy to navigate? This will make your writing better.
Many companies use some kind of wiki to keep their documentation. This is sensible, but trying to find useful information afterwards can be a challenge. It can feel like walking into someone’s room, only to find it full of hand-written notebooks. The instructions for baking the cake you were dreaming of may be in there somewhere, but frankly, it might be easy to throw it all out and start over. Wikis and the like need curating. If you don’t have a tidy up once in a while, the rot can set in. Most people tend to avoid deleting pages that are no longer relevant, just in case they prove to be important historical documents. Often they can be of interest, but are a distraction if you are trying to find out how to do something. If your system supports showing historical pages and views of pages, maybe trust it as you would trust version control? In fact, how often do we leave, or at least see, commented out code in a code base? If it’s not used, delete it. I guess it can take some skill to find code in version control history that no longer exists, especially if the file it was in has gone too, but it’s not impossible. And, it might be possible to write code to do what’s required if you can’t find an old version. Less clutter can make it easier to think.
I am reliably informed Rich Hickey, the inventor of Clojure once said, “Programming is not about typing, it’s about thinking.” On the face of it this sounds true, yet sometimes we need to try out code to see what it does. No amount of thinking will catch all the edge cases etc. In my career, I have often found myself in a meeting discussing a bug or feature and how to approach it, while people draw on white boards, speculate and the like. Frequently, we go nowhere near the code, guess, misremember and then when we come to write or fix the code, realise many further issues have not been taken into account. Don’t be shy of opening up the code while people talk and doing science. See what actually happens. It’s the only way. No amount of writing a wish list in a Jira will “Make It So”.
Talking of Clojure, as I’m sure you know this dynamic language is a Java-based dialect of Lisp. Dynamic languages offer what is referred to as duck typing, in that you can duck typing in the types, and furthermore “If it quacks like a duck, it is a duck”. Wikipedia tells me that though the Clojure “type system is entirely dynamic, recent efforts have also sought the implementation of gradual typing”. [Wikipedia-1]. I understand dynamic typing: the type checks happen at run time, though it can be possible to flush out problems with a linter without waiting until something blows up. This can be odd to get used to if you come from a static typing background. I had not come across the term gradual typing before, so had to read a lot of the internet. My executive summary is it’s some kind of mixed model, like C#, although compiled and statically type checked, since the introduction of a dynamic type some things may blow up at runtime instead of compile time. Other gradually typed languages are available, including J, Objective-C and Typescript. I’ve had a run in with Typescript recently. Initially it felt like too much typing, pun intended, though one or two ideas, such as being able to coerce some JSON into an interface actually saved some physical typing. I still have mixed feelings.
Whenever I’ve spent time using a dynamic language, allowing me to type x = 10
and the like, switching to C++ or similar and having to add an int
in as well seems unnecessary. I do eventually get over myself, but the paradigm shift takes a while. Occasionally, I find myself in what seems like the worst of both worlds. In particular, I am referring to Python’s type hints. These provide optional annotation for code. There were introduced by PEP484 [Python]. Initially, I was curious and tried them out. The PEP states
While these annotations are available at runtime through the usual annotations
attribute, no type checking happens at runtime. Instead, the proposal assumes the existence of a separate off-line type checker which users can run over their source code voluntarily. Essentially, such a type checker acts as a very powerful linter.
It mentions mypy, an optional type checker, as the inspiration. The type hints felt like a vast amount of extra effort for not much benefit. Many people often tell me it helps their IDE offer suggestions for auto-complete and similar. That’s as may be, but I tend to use Vim for Python, though I understand not everyone does. I have heard tale of type hints being used on large code bases, and the main thing I recall was the type hints finding places where a function would return None
because a snakey mess of if
/else
statements missed a return
. Such an error can be picked up by a linter, so I didn’t come away inspired. Since type hints are not all or nothing, you can add them in places you feel might be beneficial. I’m still not convinced of their value, but feel free to have a play and report back. There are plenty of details online, but Real Python [RealPython] offer a good overview.
In what I consider a similar vein, Stepanov and McJones added a template constraint, requires to their code listings in their Elements of Programming book [Stepanov09]. The C++ community was starting to talk about concepts at the time so it made sense. The start of the book told us the requires clause could be an “expression built up from constant values, concrete types, formal parameters, applications of type attributes and type functions, equality on values and types, concepts, and logical connectives.” They thereby described properties of a type. If you turn to Appendix B, you will find
#define requires(…)
which is somewhat underwhelming. I do see the benefit in what became concepts in C++. At very least, they can make error messages clearer. However, C++ being C++ means they can end up getting quite complicated. Trying to explain why you sometimes need to say requires requires
is a challenge [StackOverflow].
Even though C++ is statically type checked, you can achieve what feels a bit like duck typing with templates, though things will go wrong at compile time rather than run time. Freedom to take any type and call a method on it, without having to build up a class hierarchy or other boilerplate code can be liberating. This allows us to pass iterators into an algorithm and do something with each element, regardless of the data structure the iterators came from. You could suggest C#’s LINQ has a similar feel, but Stepanov’s genius idea was to separate the data structures and algorithms. C++ also allows use of any, variant, optional and similar. Claiming something is of type any feels like an oxymoron, but these can be very useful.
I started by talking about the physical act of typing, and then strayed into the world of types of objects in code. I could stray into category and type theory, but will spare you that. Let’s think about typing lots of code, or perhaps worse, attempting to grok a long function. Sometimes, we see a very long select statement or snakey mess of if
s and else
s. I personally believe it is usually possible to collapse these down a bit to something that’s easier to follow. Even pulling out of few statements into their own function can leave less detail to look at in one place, though they have moved elsewhere. Sometimes swapping a for loop for an algorithm makes the code more succinct. Opinions can be divided at this point. Sometimes code is obviously messy, sometimes it is quite neat, but sometimes it is ‘too cute’. You spend longer figuring out what it does when it’s a one liner than you would have done with a for
loop. Try out the cute code, by all means, but check you still understand it the next day.
Managing to be succinct and clear is difficult, but worth a try. Lengthy rambles take too long to read and I’m now running out of space, so shall end with a Pascal quote: “I would have written a shorter letter, but I did not have the time.” [Wikipedia-2]
References
[Python] Python: https://www.python.org/dev/peps/pep-0484/
[RealPython] Real Python: https://realpython.com/python-type-checking
[StackOverflow] For an example, see https://stackoverflow.com/questions/54200988/why-do-we-require-requires-requires
[Stepanov09] Alexander Stepanov and Paul McJones (2009) Elements of Programming ISBN 9780321635372, Addison Wesley. Available from: http://elementsofprogramming.com/
[Wikipedia-1] Clojure: https://en.wikipedia.org/wiki/Clojure
[Wikipedia-2] Pascal (Letter XVI), according to https://en.wikipedia.org/wiki/Lettres_provinciales
has a BA in Maths + Philosophy, an MSc in Pure Maths and a PhD technically in Chemical Engineering, but mainly programming and learning about AI and data mining. She has been a programmer since the 90s, and learnt to program by reading the manual for her Dad’s BBC model B machine.