The Atoms of Programming

In the world of physics, there are many different models that can be used, though typically each of them has different applicability to different contexts. At the small scale, quantum physics is a very useful model, Newtonian physics will yield evidently incorrect predictions so is less valuable. Where a Newtonian model gives sufficiently accurate results, it’s a lot easier to work with than quantum or relativistic mechanics.

All of these models are used to describe the same universe – the same underlying collection of observations that can systematically be categorised, modelled and predicted.

Physical science (or experimental philosophy) does not work in the same way as computational philosophy. There are physical realisations of computational systems, typically manifested as electronic systems or pencil-and-paper simulations. But the software, the abstract configurations of ideas that run on those systems, exist in entirely separate space and are merely (though the fact that this is possible is immensely powerful) translated into the electronic or paper medium.

Of course one model for the software system is to abstract the electronic: to consider the movement of electrons as the presence of voltages at terminals; to group terminals as registers or busses; to further abstract this range of voltages as 0 and that range as 1. And indeed that model frequently is useful.

Frequently, that model is not useful. And the great thing is that we get to select from a panoply of other models, at some small or large remove from the physical model. We can use these models separately, or simultaneously. You can think of a software system as a network of messages passed between independent objects, as a flow of data through transformers, as a sequence of state changes, as a graph of single-argument functions, as something else, or as a combination of these things. Each is useful, each is powerful, all are applicable.

Sometimes, I can use these models to make decisions about representing the logical structure of these systems, transforming a concept into a representation that’s valid in the model. If I have a statement in a mathematical formulation of my problem, “for any a drawn from the set of Articles there exists a p drawn from the set of People such that p is the principal author of a” then I can build a function, or a method, or a query, or a predicate, or a procedure, or a subroutine, or a spreadsheet cell, or a process, that given an article will yield exactly one person who is the principal author of that article.

Sometimes, I use the models to avoid the conceptual or logical layers at all and express my problem as if it is a software solution. Object-oriented analysis and design, data flow modelling, and other techniques can be used to represent a logical model, or they can be used to bash the problem straight into a physical model without having thought about the problem in the abstract. “Shut up and code” is an extreme example of this approach, in which the physical model is realised without any attempt to tie it to a logical or conceptual design. I’ll know correct when I see it.

I don’t see a lot of value in collecting programming languages. I can’t count the number of different programming languages I’ve used, and many of them are entirely similar. C and JavaScript both have sequences of expressions that are built into statements that are built into procedures. Both let me build aggregations of data and procedures that either let me organise sequential programs, represent objects, represent functions, or do something else.

But collecting the models, the different representations of systems conceptually that can be expressed as software, sometimes called paradigms: this is very interesting. This is what lets me think about representing problems in different ways, and come up with efficient (conceptually or physically) solutions.

More paradigms, please.

Dogmatic paradigmatism

First, you put all of your faith in structured programming, and you got burned. You found it hard to associate the operations in your software with the data upon which they act, and to make sure that the expectations made on the data in one place are satisfied when that data has been modified in that other place, or over there in yet another place. Clearly structured programming is broken.

Then, you put all of your faith in object-oriented programming, and you got burned. You found it hard to follow the flow of a program when it jumps in and out of different classes, and to see which parts were coupled to what. Clearly object-oriented programming is broken.

Then, you put all of your faith in functional programming, and you got burned. You found it hard to represent real business processes in terms of immutable data structures and pure functions, and to express changes to the operating environment without using side effects. Clearly functional programming is broken.

Or maybe it’s you. Maybe, rather than relying on faith to make these conceptual thought frameworks do what you need from them, you could have thought about the concepts.

Détournement and Recuperation

Letterists International probably invented the ideas behind free software and creative commons. They created the idea of détournement, in which existing mainstream logos and slogans were subverted for anarchist, satirical and other radical political purposes, like the picture of the Queen defaced in the cover of the Sex Pistols single.

The counterpart to détournement is recuperation, in which radical ideas are appropriated by the cultural mainstream to be re-used in safe contexts, like the use of Thunderclap Newman’s “Something in the air” to advertise an airline.

Free Software enables both of these: mainstream software made available under free software licences like the GPL can be put to radical new uses because of the terms of the GPL. But it also enables software built to political ends, and shared under those terms, to be put to mainstream uses.

If anything, open source software is a bigger enabler of recuperation. By relieving receivers of the pay-it-forward obligation, open source licences make it easier for incumbent organisations using traditional software model to make use of ideologically-motivated software publication.

Sitting on the Sidelines

Thank you, James Hague, for your article You Can’t Sit on the Sidelines and Become a Philosopher. I got a lot out of reading it, because I identified myself in it. Specifically in this paragraph:

There’s another option, too: you could give up. You can stop making things and become a commentator, letting everyone know how messed-up software development is. You can become a philosopher and talk about abstract, big picture views of perfection without ever shipping a product based on those ideals. You can become an advocate for the good and a harsh critic of the bad. But though you might think you’re providing a beacon of sanity and hope, you’re slowly losing touch with concrete thought processes and skills you need to be a developer.

I recognise in myself a lot of the above, writing long, rambling, tedious histories; describing how others are doing it wrong; and identifying inconsistencies without attempting to resolve them. Here’s what I said in that last post:

I feel like I ought to do something about some of that. I haven’t, and perhaps that makes me the guy who comes up to a bunch of developers, says “I’ve got a great idea” and expects them to make it.

Yup, I’m definitely the person James was talking about. But he gave me a way out, and some other statements that I can hope to identify with:

You have to ignore some things, because while they’re driving you mad, not everyone sees them that way; you’ve built up a sensitivity. […] You can fix things, especially specific problems you have a solid understanding of, and probably not the world of technology as a whole.

The difficulty is one of choice paralysis. Yes, all of those broken things are (perhaps literally) driving me mad, but there’s always the knowledge that trying to fix any one of them means ignoring all of the others. Like the out of control trolley, it’s easier to do nothing and pretend I’m not part of the problem than to deliberately engage with choosing some apparently small part of it. It’s easier to read Alan Kay, to watch Bret Victor and Doug Engelbart and to imagine some utopia where they had greater influence. A sort of programmerpunk fictional universe.

As long as you eventually get going again you’ll be fine.

Hopefully.

Programming, maths and the other things

Sarah Mei argues that programming is not math, arguing instead that programming is language. I don’t think it’s hard to see the truth in the first part, though due to geopolitical influences on my personality I’d make the incrementally longer statement that programming is not maths.

But there’s maths in programming

Let’s agree to leave aside the situations in which we use programming to solve mathematics problems, such as geometry or financial modelling. These are situations in which the maths is intrinsic to the problem domain, and worrying about the amount of maths involved could potentially confuse two different sources of maths.

Nonetheless, one may argue that the computer is simulating a mathematical structure, and that therefore you need to understand the mathematical model of the structure in order to get the computer to do the correct thing. I can model the computer’s behaviour using the lambda calculus, and I’ve got a mathematically-rich model. I can model the computer’s behaviour as a sequence of operations applied to an infinite paper tape, and I’ve got a different model. These two models can be interchanged, even if they surface different aspects of the real situation being modelled.

It’s the second of the two models that leads to the conclusion that capability at advanced maths is not intrinsic to success at programming. If what the computer’s doing can be understood in terms of relatively simple operations like changing the position of a tape head and tallying numbers, then you could in principle not only understand a program but even replicate it yourself without a deep knowledge of mathematics. Indeed that principle provides the foundation to one argument on the nature of software as intellectual property: a computer program is nothing more than a sequence of instructions that could be followed by someone with a pencil and paper, and therefore cannot represent a patentable invention.

Maths, while not intrinsic, may be important to programming

It may, but it probably isn’t. Indeed it’s likely that many thousands of programmers every day ignore key results in the mathematical investigation of programming, and still manage to produce software that (at least sort-of) works.

Take the assertion as an example. Here’s a feature of many programming environments that has its root in the predicate systems that can be used to reason about computer programs. The maths is simple enough: if predicate P is true before executing statement S, and consequent Q will hold after its execution, then the result of executing S will be P AND Q.

From this, and knowledge of what your program should be doing, then you can prove the correctness of your program. Because of the additive nature, if you can prove the outcome of every statement in a subroutine, then you can make an overall statement about the outcome of that subroutine. Similarly, you can compose the statements you can make about subroutines to prove the behaviour of a program composed out of those subroutines. Such is the basis of techniques like design by contract, and even more formal techniques like proof-carrying code and model-carrying code.

…which are, by and large, not used. You can write an assertion without having the mathematical knowledge described above, and you can write a program without any assertions.

Here’s what Tony Hoare said about what programmers know of their programs, back in 1969 (pronoun choice is original):

At present, the method which a programmer uses to convince himself of the correctness of his program is to try it out in particular cases and to modify it if the results produced do not correspond to his intentions. After he has found a reasonably wide variety of example cases on which the program seems to work, he believes that it will always work.

Since then, we’ve definitely (though not consistently) adopted tools to automate the trying out of programs (or routines in programs) on particular cases, and largely not adopted tools for automatic proof construction and checking. Such blazing progress in only 45 years!

There are more things in heaven and earth, Horatio

Here’s a potted, incomplete list of things required of someone or a group of people making software. The list is presented in order of remembering them, and doesn’t reflect any intrinsic dependencies.

  • know of a problem that needs solving
  • think of a solution to the problem
  • presume or demonstrate that the solution can be made out of software
  • understand whether the solution will be useful and valuable
  • understand the constraints within which the solution will operate
  • understand and evaluate the changes to the system that arise from the solution existing
  • design an implementation of the solution to fit the constraints (maths is optional here, but index cards and arrows on whiteboards will often work)
  • build that solution (maths is optional here)
  • demonstrate that the implementation does indeed solve the problem (maths is optional here)
  • convince people that they in fact need this problem solved in this particular way
  • explain to people how to use this implementation
  • react to changes that occur in the implementation’s environment
  • pay for all of the above (some maths helps here)

The point is that actual programming is a very small part of everything that’s going on. Even if maths were intrinsic to parts of that activity, it would still be a tiny contribution to the overall situation. Programming is maths in the same way that cooking is thermodynamics.

Goals upon goals upon goals

As I read Ed Finkler’s piece on losing excitement in technology, I found myself recognising pieces of my own story. The prospect of a new language or framework no longer seems like a new toy, an excuse to stay up all night studying it, using it and learning its secrets as I would have done a few years ago. Instead I find myself asking what new problems are introduced, whether they’re worth accepting over the devils we know are in our existing tools and how many developer-decades are soon to be lost in reimplementing libraries that have been in CPAN for decades in a new language and delivered via a new packaging system.

Because, as I alluded to when not really talking about Swift and as more eloquently described by Matt Gemmell, our problems do not, for the most part, come from our tools and will not be solved by adding more tools. Indeed a developer’s fixation on their tools will allow the surrounding business, market, legal and social problems to go unchecked. No change of programming language will turn customers who don’t want to pay $0.99 into customers who do want to pay $99. Implicitly unwrapped optionals might catch the occasional bug in development but they just aren’t worth a 100x increase in value to people on the sharp end of our creations.

What will be of benefit to them? I think we’re going to have to go through the software equivalent of the consolidation that the consumer goods industry has already seen in hardware. Remember the introduction to the iPhone?

An iPod, a phone, an internet mobile communicator, these are NOT three separate devices!

Actually it’s none of those things. Well, it is, in that it’s all of those and more. Fundamentally, it’s a honking great handheld control unit with hundreds of buttons on, just like Sony used to make for their TV remotes. One of those buttons will turn it into a phone, one will turn it into an iPod, one will turn it into a web browser, another lets you add other buttons that do other things. They don’t all do their things in the same way, and just to keep things interesting the buttons will arbitrarily change location and design and behaviour every so often. The Sony remotes didn’t do that.

The core experience of an iPhone, or Android phone, or Windows phone—the thing you see when you switch it on and wait long enough—is a launcher. It’s the Program Manager from Windows 3.0, packaged up in a shiny interactive box. Both Program Manager and today’s replacement offer the same promise: you’ve got a feeling that you left a button around here somewhere that probably starts you doing the thing you need to do.

So we still need to make good on the promise that you have just one device, by making that one device act like just one device (preferably one which works properly and does what people expect, which is what I spend a lot of time thinking about and working on). How we get there will be the interesting problem for at least another decade. How our tools support that journey will be a fun sideshow, certainly important but hardly the focus. The tools support the goals that support our goals that support the world’s goals.

Open Source and the Lehrer-von Braun defence

Tom Lehrer’s song about Wernher von Braun is of a man who should not be described as hypocritical:

Say rather that he’s apolitical. “Once the rockets go up, who cares where they come down? That’s not my department,” says Wernher von Braun.

The idea that programming as a field has no clear ethical direction is not news. As Martin Fowler says here, some programmers seem to believe that they are mere code monkeys. We build things, it’s up to other people to choose how they get used, right?

It’s in open source software that this line of thinking is clearest. Of course anyone can use commercial software, but it becomes awkward to have blood money on your company’s records. Those defence companies and minerals miners just lead people to ask questions, and it’d be better if they didn’t. You could just choose not to sell to those people, but that reduces the impact of your product.

A solution presents itself: don’t take their money! Rather, decouple the sending up of the thing and the choice of where it comes down, by making it available to people who now don’t have any (obvious or traceable, anyway) connection to you or your employer. That’s not your department! Instead of selling it, stick it up on a website (preferably someone else’s, like GitHub) and give a blanket licence to everyone to use the software for any purpose. You just built a sweet library for interfacing with gyroscopic stabilisers, is it really your fault that someone built a cruise missile that uses the library?

“But wait,” you say, “this doesn’t sound like the clear-cut victory you make it out to be. In avoiding the social difficulties attendant in selling my software to so-called evildoers, I’ve also removed the possibility to sell it to gooddoers. Doesn’t that mean no money?” No, as Andrew Binstock notes, you can still sell the software.

Anyway, perhaps it’d be useful to restructure the economics of the software industry such that open source was seen as a value-driver, so you can both have your open source cake and eat the cake derived from valuable monetary income. You might do that by organising things such that an open source portfolio were seen as a necessary input to getting hired, for example. So while plenty of people still don’t get paid for open source software, they still indirectly benefit from it monetarily.

We can, evidently, easily spin contributions to open source such that they are to our own benefit. What about everybody else? When a government uses Linux computers to spy on the entire world, or an armed force powers its weapons with free software, is that pro bono publico?

The usual response would be the Lehrer-von Braun defence detailed above. “We just built it in good faith, it’s up to others to choose how they use it.” An attempt to withdraw from ethical evaluation is itself an ethical stance: it’s saying that decisions over whether the things you make are good or evil are above (or beneath) your pay-grade. That we, as developers, are OK with the idea that we get large paychecks to live in comfortable countries and solve mental problems, and that the impact of those solutions is for somebody else to deal with. That despite being at the epicentre of one of the world’s biggest social and economic changes, we don’t care what happens to society or to economy as a result of our doings.

Attempts have been made to produce “socially aware” software, but these have so far not been unqualified successes. The JSON licence includes the following clause:

The Software shall be used for Good, not Evil.

Interestingly, in one analysis I discovered, the first complaint about this clause is that it interferes with the Free Software goal of copyleft. How ethical do we think an industry is that values self-serving details over the impact of its work on society?

The other problem raised in relation to the JSON licence is that it doesn’t explain what good or evil are, nor who is allowed to decide what good or evil are. Broad agreement is unlikely, so this is like the career advisor who tells you to “follow your dreams” without separating out the ones where you’re a successful human rights lawyer and the ones where you’re being chased by a giant spider with a tentacle face through an ever-changing landscape of horror.

I should probably stop reading H. P. Lovecraft at bedtime.

The Software Leviathan

Thomas Hobbes viewed society as a meta-person, a gigantic creature whose parts were human and which was in the service of those humans. Left to their own devices, people would not work well together as their notion of individualism and search for personal gain leads directly to conflict: strong government is needed to instil a sense of cooperation and of social obligation. This idea of “government through social contract” is pervasive in Western political thought, being the basis as it is for the “government of the people, by the people, for the people” with which Abraham Lincoln hoped to lead post-civil war America.

Software systems themselves can also be thought of as Leviathans. From a purely technical sense, all of “professional” software construction is based on notions of composition, of software systems that are themselves made of software systems. So we have structured or procedural programming, with routines composed of subroutines. And functional programming, with functions composed of functions. And object-oriented programming, with objects composed of objects. So central are these ideas to expressions of thought in software that they are considered paradigmatic by many, representing fundamental world-views of the art/craft/science.

There’s a second formulation of software-as-Leviathan, which is closer to Hobbesian meaning. The technical aspect of our software systems is merely a substrate[*] through which a social system—that of the people interacting with the software, the people acting on the software, and the people interacting with the other people—is reified. So the descriptions Hobbes made of his Leviathan can be made of these socio-technical systems:

  • First the Matter thereof, and the Artificer; both which is Man[sic].
  • Secondly, How, and by what Covenants it is made; what are the Rights and just Power or Authority of a Soveraigne; and what it is that Preserveth and Dissolveth it.
  • Thirdly, what is a Christian Common-Wealth.
  • Lastly, what is the Kingdome of Darkness.

[*] I wonder what form of substance gives the best sense of the analogy. Scaffolding? Lubricant? Mortar? Framework?

OK, maybe not so much the third one, except that it is really an attempt to define the values and norms of a society, which in the context of Hobbes’s writing, meant a Christian society.

Of course, any attempt to describe such a system is going to be filtered by the preconceptions, ideas and values of the person creating the description. Which brings me onto today’s topic: the pun in the new domain of this blog. Evidently it’s a contraction of “Structure and Interpretation of Computer Programmers”, based on the Abelson and Sussman book title. That book is abbreviated to SICP, so it’s not too difficult to see how it might be adapted to SICPers.

We can also see it as being a Latin abbreviation: sic pers., meaning such a person. So there is both the Structure and Interpretation of Computer Programmers, and there is this person who is doing the interpreting, in the domain name.