The challenges of teaching software engineering

I’ve just finished teaching a four-day course introducing software engineering for the first time. My plan is to refine the course (I’m teaching it again in October), and it will eventually become the basis for doctoral training programmes in research software engineering at Oxford, and part of a taught Masters. My department already has an M.Sc. in Software Engineering for commercial engineers (in fact I have that degree), and we want to do the same for software engineers in research context.

Of course, I can also teach your team about software engineering!

Some challenges that came up:

  • I’m too comfortable with the command-line to get people past the initial unfamiliar discomfort. From that perspective, command-line tools are all unusably hard. I’ve learnt from various sources to try foo --help, man foo, and other incantations. Others haven’t.

  • git, in particular, is decidedly unfriendly. What I want to do is commit my changes. What I have to do is stage my changes, then commit my staged changes. As a result, teaching git use takes a significant chunk of the available time, and still leaves confusion.

  • you need to either tell people how to set their core.editor, or how to quit vim.

  • similarly, there’s a world of difference between python foo.py and python3 foo.py, and students aren’t going to interpret the sorts of errors you et if you choose the wrong one.

  • Introduce a tangent, and I run the risk of losing people to that tangent. I briefly mentioned UML while discussing diagrams of objects, as a particular syntax for those diagrams. In the subsequent lab, some people put significant time into making sure their diagrams were valid UML.

  • Finding the trade-off between presentation, tutorial, and self-directed exercise is difficult. I’m used to presentations and will happily talk on many topics, but even I get bored of listening to me after the ~50% of the time I’ve spent speaking on this course. It must be worse for the students. And there’s no substitute for practical experience, but that must be supported by guidance.

  • There are so many topics that I didn’t get to cover!

    • only having an hour for OOP is a sin
    • which means I didn’t even mention patterns or principles
    • similarly, other design techniques like functional programming got left off
    • principles like Agile Software Development, Software Craftsmanship, or Devops don’t get a mention
    • continuous integration and continuous delivery got left off. Even if they didn’t, the amount of work involved in going from “I have a Python script” to “I run my tests whenever I change my script, and update my PYpi package whenever they pass” is too damn high.
    • forget databases, web servers, browsers, mobile apps, desktop apps, IoT, or anything that isn’t a command line script or a jupyter notebook
    • and machine learning tools
    • and concurrency, processes and process improvement, risk management, security, team dynamics, user experience, accessibility…

It’s only supposed to be a taster but I have to trade off introducing everything with showing the value present in anything. What this shows, as I found when I wrote APPropriate Behaviour, is that there’s a load that goes into being a programmer that is not programming.

Falsehoods programmers who write “falsehoods programmers believe” articles believe about programmers who read “falsehoods programmers believe” articles

For reasons that will become clear, I can’t structure this article as a “falsehoods programmers believe” article, much as that would add to the effect.

There are plenty of such articles in the world, so turn to your favourite search engine, type in “falsehoods programmers believe”, and orient yourself to this concept. You’ll see plenty of articles that list statements that challenge assumptions about a particular problem domain. Some of them list counterexamples, and a subset of those give suggestions of ways to account for the counterexamples.

As the sort of programmer who writes falsehoods programmers believe articles, my belief is that interesting challenges to my beliefs will trigger some curiosity, and lead me to research the counterexamples and solutions. Or at least, to file away the fact that counterexamples exist until I need it, or am otherwise more motivated to learn about it.

But that motivation is not universal. The fact that I treat it as universal turns it into a falsehood I believe about readers of falsehoods articles. Complaints abound that falsehoods articles do not lead directly to fish on the plate. Some readers want a clear breakdown from “thing you might think is true but isn’t true” to “Javascript you can paste in your project to account for it not being true”. These people are not well-served by falsehoods articles.

Longer, fuller stacks

Thinks to self: OK, this “full-stack” project is going to be fairly complex. I need:

  • a database. I don’t need it yet, I’ll defer that.
  • a thing that runs on the server, listens for HTTP requests from a browser, builds responses, and sends them to the browser.
  • a thing that runs on the browser, built out of bits assembled by the server thing, that the user can interact with.

What I actually got was:

  • a thing that runs on the server.
  • a thing that defines the environment for the server.
  • a thing that defines the environment on development machines so that you can run server-development tasks.
  • a thing that turns code that can’t run in a browser into code that can run in a browser.
  • a thing that turns code that can run in a browser into code that does run in real browsers.
  • a headless browser that lets me test browser code.
    • BTW, it doesn’t work with that server environment.
    • a thing that shows how Linux binaries are loaded, to work out how to fix the environment.
    • also BTW, it doesn’t run headless without setting some environment variable
    • a thing that is used for cross-platform native desktop apps, that I can configure to work headless.
  • a thing that builds the bits assembled by the server thing so that the test thing can see the code being tested.

And somehow, people argue that this is about reducing development costs.

The importance of the passive voice is described.

I am writing a blog post, in which I intend to convince you of my case. A coherent argument must be created, in which the benefits of my view are enumerated. Paragraphs are introduced to separate the different parts of the argument.

The scene was set in the first sentence, so readers know that the actor in the following sentences must be me. Repeating that information would be redundant. Indeed, it was clearly me who set that scene, so no need to mention me at the start of this paragraph. An article in which each sentence is about the author, and not the article’s subject, could be perceived as a sign of arrogance. This perception is obviously performed by the reader of the article, so there is no need to explicitly call that out.

The important features of the remaining sentences in the first paragraph are those relating to the structure of the article. These structural elements are subjects upon which I act, so bringing them to the fore in my writing involves suppressing the object, the actor in the text. I can do this by choosing to use the passive voice.

Unfortunately, grammar checkers throughout the world of computing give the impression that the passive voice is always bad. Millions of people are shown underlining, highlighting, and inline tips explaining that their writing is wrong. Programmers have leaked the abstraction that everything in their world is either 1 or 0, into a world where that does not make sense. Sentences are either marked active (1), correct (1), or passive (0), incorrect (0).

Let us apply that to other fields of creative endeavor. Vincent: a starry night is not that brightly colored. 0. You used too much paint on the canvas. 0. Stars are not that big. 0.

Emily: too many hyphens. 0. No need to capitalize “microscope”. 0. Sentence fragment. 0.

On the features of a portfolio career

Since starting The Labrary late last year, I’ve been able to work with lots of different organisations and lots of different people. You too can hire The Labrary to make it easier and faster to create high-quality software that respects privacy and freedom, though not before January 2020 at the earliest.

In fact I’d already had a portfolio career before then, but a sequential one. A couple of years with this employer, a year with that, a phase as an indie, then back to another employer, and so on. At the moment I balance a 50% job with Labrary engagements.

The first thing to notice is that going part time starts with asking the employer. Whether it’s your current employer or an interviewer for a potential position, you need to start that conversation. When I first went from full-time to 80%, a few people said something like “I’d love to do that, but I doubt I’d be allowed”. I infer from this that they haven’t tried asking, which means it definitely isn’t about to happen.

My experience is that many employers didn’t even have the idea of part-time contracts in mind, so there’s no basis on which they can say yes. There isn’t really one for “no” either, except that it’s the status quo. Having a follow-up conversation to discuss their concerns both normalises the idea of part-time employees, and demonstrates that you’re working with them to find a satisfactory arrangement: a sign of a thoughtful employee who you want to keep around, even if only some of the time!

Job-swapping works for me because I like to see a lot of different contexts and form synthetic ideas across all of them. Working with different teams at the same time is really beneficial because I constantly get that sense of change and excitement. It’s Monday, so I’m not there any more, I’m here: what’s moved on in the last week?

It also makes it easier to deal with suboptimal working environments. I’m one of those people who likes being in an office and the social connections of talking to my team, and doesn’t get on well with working from home alone (particularly when separated from my colleagues by timezones and oceans). If I only have a week of that before I’m back in society, it’s bearable, so I can consider taking on engagements that otherwise wouldn’t work for me. I would expect that applies the other way around, for people who are natural hermits and would prefer not to be in shared work spaces.

However, have you ever experienced that feeling of dread when you come back from a week of holiday to discover that pile of unread emails, work-chat-app notifications, and meeting bookings you don’t know the context for? Imagine having that every week, and you know what job-hopping is like. I’m not great at time management anyway, and having to take extra care to ensure I know what project C is up to while I’m eyeballs-deep in project H work is difficult. This difficulty is compounded when clients restrict their work to their devices; a reasonable security requirement but one that has led to the point now where I have four different computers at home with different email accounts, VPN access, chat programs, etc.

Also, absent employee syndrome hits in two different ways. For some reason, the median lead time for setting up meetings seems to be a week. My guess is that this is because the timeslot you’re in now, while you’re all trying to set up the meeting, is definitely free. Anyway. Imagine I’m in now, and won’t be next week. There’s a good chance that the meeting goes ahead without me, because it’s best not to delay these things. Now imagine I’m not in now, but will be next week. There’s a good chance that the meeting goes ahead without me anyway, because nobody can see me when they book the meeting so don’t remember I might get involved.

That may seem like your idea of heaven: a guaranteed workaround to get out of all meetings :). But to me, the interesting software engineering happens in the discussion and it’s only the rote bits like coding that happen in isolation. So if I’m not in the room where the decisions are made, then I’m not really engineering the software.

Maybe there’s some other approach that ameliorates some of the downsides of this arrangement. But for me, so far, multiple workplaces is better than one, and helping many people by fulfilling the Labrary’s mission is better than helping a few.

The Logical Fallacy

Nary a week goes by without seeing a post by a programmer, for programmers, on the subject of logical fallacies in arguments. This week’s, courtesy of hacker news, is not egregious, enlightening, or indeed different in any way from the usual torrent. It is merely the one that prompted me into writing this article. The most frequent, and most severe, logical fallacy I encounter among programmers is this one:

  • basing your argument on logic.

Now, obviously, for a fallacy to be recognised it needs to have a Latin name, so I’m going to call this one argumentum ex logica.

Argumentum ex logica is the fallacious reasoning that the best course of action for a group of people is the one that can be arrived at by logical deduction. No need to consider the emotions of the people involved, or the aesthetic properties of any potential solutions. Just treat your workplace like your high school debating club, pick (seemingly arbitrarily) some axioms, and batter your way through to your preferred conclusion.

If people disagree with you on (unreasonable) emotional grounds, just name their logical fallacies so you can overrule their arguments, like you’re in an episode of Ally McBeal and want their comments stricken from the record. If people manage to find a flaw in the logic of your argument, just pick a new axiom you’d never mentioned before and carry on.

The application of the argumentum ex logica fallacy is frequently accompanied by descriptions of the actions of “the brain”, that strange impish character that sits inside each of us and causes us to divert from the true path of Syrran of Vulcan. Post hoc ergo propter hoc, we are told, is an easy mistake to make because “the brain” sees successive events as related.

Here’s the weird thing. We all have a “the brain” inside us, as an important part of our being. By writing off “the brain” as a mistaken and impure lump of wet fat, programmers are saying that they are building their software not for humans. There must be some other kind of machine that functions on purely logical grounds, for whom their software is intended. It should not be.

Applications and Spelling of Boole

While Alan Turing is regarded by many as the grandfather of Artificial Intelligence, George Boole should be entitled to some claim to that epithet too. His Investigation of the Laws of Thought is nothing other than a systematisation of “those universal laws of thought which are the basis of all reasoning”. The regularisation of logic and probability into an algebraic form renders them amenable to the sort of computing that Turing was later to show could be just as well performed mechanically or electronically as with pencil and paper.

But when did people start talking about the logic of binary operations in computers as being due to Boole? Turing appears never to have mentioned his name: although he certainly did talk about the benefits of implementing a computer’s memory as a collection of 0s and 1s, and describe operations thereon, he did not call them Boolean or reference Boole.

In the ACM digital library, Symbolic synthesis of digital computers from 1952 is the earliest use of the word “Boolean”. Irving S. Reed describes a computer as “a Boolean machine” and “an automatic operational filing system” in its abstract. He cites his own technical report from 1951:

Equations (1.33) and (1.35) show that the simple Boolean system, given in (1.34) may be analysed physically by a machine consisting of N clocked flip flops for the dependent variables and suitable physical devices for producing the sum and product of the various variables. Such a machine will be called the simple Boolean machine.

The best examples of simple Boolean machines known to this author are the Maddidas and (or) universal computers being built or considered by Computer Research Corporation, Northrop Aircraft Inc, Hughes Aircraft, Cal. Tech., and others. It is this author’s belief that all the electronic and digital relay computers in existence today may be interpreted as simple Boolean machines if the various elements of these machines are regarded in an appropriate manner, but this has yet to be proved.

So at least in the USA, the correlation between digital computing and Boolean logic was being explored almost as soon as the computer was invented. Though not universally: the book “The Origins of Digital Computers” edited by Brian Randell, with articles from Charles Babbage, Grace Hopper, John Mauchly, and others, doesn’t mention Boole at all. Neither does Von Neumann’s famous “first draft” report on the EDVAC.

So, second question. Why do programmers spell Boole bool? Who first decided that five characters was too many, and that four was just right?

Some early programming languages, like Lisp, don’t have a logical data type at all. Lisp uses the empty list to mean “false” and anything else to mean true. Snobol is weird (he said, surprising nobody). It also doesn’t have a logical type, conditional execution being predicated on whether an operation signals failure. So the “less than” function can return the empty string if a<b, or it can fail.

Fortran has a LOGICAL type, logically. COBOL, being designed to be illogical wherever Fortran is logical, has a level 88 data type. Simula, Algol and Pascal use the word ‘boolean’, modulo capitalisation.

ML definitely has a bool type, but did it always? I can’t see whether it was introduced in Standard ML (1980s-1990), or earlier (1973+). Nonetheless, it does appear that ML is the source of misspelled Booles.

Digital Declutter

I’ve been reading and listening to various books about the attention/surveillance economy, the rise of fascism in the Anglosphere and beyond, and have decided to disconnect from the daily outrage and the impotent swiping of “social” “content”. The most immediately actionable advice came from Cal Newport’s Digital Minimalism. I will therefore be undertaking a digital declutter in May.

Specifically this means:

  • no social media. In fact I haven’t been on most of them all of April, so this is already in play. By continuing it into May, I intend to do a better job of choosing things to do when I’m not hitting refresh.
  • alerts on chat apps on for close friends and family only.
  • streaming TV only when watching with other people.
  • Email once per day.
  • no RSS.
  • audiobooks only while driving.
  • Slack once per day.
  • Web browsing only when it progresses a specific work, or non-computering, task.
  • at least one walk per day, of at least half an hour, with no technology.
  • Phone permanently in Do Not Disturb mode.

It’s possible that I end up blogging more, if that’s what I start thinking of when I’m not browsing the twitters. Or less. We’ll find out over the coming weeks.

My posts for De Programmatica Ipsum are written and scheduled, so service there is not interrupted. And I’m not becoming a hermit, just digitally decluttering. Arrange Office Hours, come to Brum AI, or find me somewhere else, if you want to chat!