A significant amount of programming is done by superstition

March 25, 2015

Ben Cotton wrote in a comment here:

[...] Failure to adhere to a standard while on the surface making use of it is a bug. It's not a SySV init bug, but a bug in the particular init script. Why write the information at all if it's not going to be used, and especially if it could cause unexpected behavior? [...]

The uncomfortable answer to why this happens is that a significant amount of programming in the real world is done partly through what I'll call superstition and mythology.

In practice, very few people study the primary sources (or even authoritative secondary sources) when they're programming and then work forward from first principles; instead they find convenient references, copy and adapt code that they find lying around in various places (including the Internet), and repeat things that they've done before with whatever variations are necessary this time around. If it works, ship it. If it doesn't work, fiddle things until it does. What this creates is a body of superstition and imitation. You don't necessarily write things because they're what's necessary and minimal, or because you fully understand them; instead you write things because they're what people before you have done (including your past self) and the result works when you try it.

(Even if you learned your programming language from primary or high quality secondary sources, this deep knowledge fades over time in most people. It's easy for bits of it to get overwritten by things that are basically folk wisdom, especially because there can be little nuggets of important truth in programming folk wisdom.)

All of this is of course magnified when you're working on secondary artifacts for your program like Makefiles, install scripts, and yes, init scripts. These aren't the important focus of your work (that's the program code itself), they're just a necessary overhead to get everything to go, something you usually bang out more or less at the end of the project and probably without spending the time to do deep research on how to do them exactly right. You grab a starting point from somewhere, cut out the bits that you know don't apply to you, modify the bits you need, test it to see if it works, and then you ship it.

(If you say that you don't take this relatively fast road for Linux init scripts, I'll raise my eyebrows a lot. You've really read the LSB specification for init scripts and your distribution's distro-specific documentation? If so, you're almost certainly a Debian Developer or the equivalent specialist for other distributions.)

So in this case the answer to Ben Cotton's question is that people didn't deliberately write incorrect LSB dependency information. Instead they either copied an existing init script or thought (through superstition aka folk wisdom) that init scripts needed LSB headers that looked like this. When the results worked on a System V init system, people shipped them.

This isn't something that we like to think about as programmers, because we'd really rather believe that we're always working from scratch and only writing the completely correct stuff that really has to be there; 'cut and paste programming' is a pejorative most of the time. But the reality is that almost no one has the time to check authoritative sources every time; inevitably we wind up depending on our memory, and it's all too easy for our fallible memories to get 'contaminated' with code we've seen, folk wisdom we've heard, and so on.

(And that's the best case, without any looking around for examples that we can crib from when we're dealing with a somewhat complex area that we don't have the time to learn in depth. I don't always take code itself from examples, but I've certainly taken lots of 'this is how to do <X> with this package' structural advice from them. After all, that's what they're there for; good examples are explicitly there so you can see how things are supposed to be done. But that means bad examples or imperfectly understood ones add things that don't actually have to be there or that are subtly wrong (consider, for example, omitted error checks).)

Comments on this page:

By Just some guy at 2015-03-25 23:16:49:

In practice, I'd love to work from authoritative documentation. Given the choice, I'll always go with what's actually correct, according to the documentation and specification and test suite, because then I'm not in danger of some developer fixing a bug and changing the behavior of my program.

The problem is not one of motivation, but one of ability. Most software I use has extremely poor documentation, if it exists at all. There's often no test suite to demonstrate current behavior, or ensure it won't change in an incompatible manner. Usually there's no specification at all.

What's a programmer to do? I can't exactly refuse to work on any commercial software project with dependencies. I can't write specifications and documentation (and then promote them for acceptance) for every project we use. I can't write everything from scratch. I can push for better documentation/specifications/testing for the software I work on, but it's definitely an uphill battle.

By Nadya at 2015-03-26 14:39:31:

Every good programmer preaches for well-written documentation and good examples.

In reality, due to managers pushing absurd limits onto production, documentation is usually left out to write more code to slap something together to ship and sell to make the manager happy.

This is usually because the manager is not a programmer and doesn't realize the maintenance hell that is going to happen if any of the programmers who wrote and understand the code leave and a new programmer now has to read through undocumented code to understand what does what and what they can change without breaking things.

Programmers slap code together because they aren't given the time to read the specs/docs and write good, documented code. There are very few who have a deep understanding of the language they are writing and no dependencies on 3rd Party Libraries where everything is in-house and they can document all their code and they are the only person working on the code (or even more rare: there are multiple programmers with such deep knowledge who work alongside this rare, master programmer).

By pdkl95 at 2015-03-28 03:45:35:

thought (through superstition aka folk wisdom) that init scripts needed LSB headers that looked like this.

aka http://c2.com/cgi/wiki?CargoCultProgramming

Sorry, I have to retract that. Upon rereading, I see that it is a very closely related thing – but not the same.

By God at 2015-05-10 10:12:03:

>Failure to adhere to a standard while on the surface making use of it is a bug.

Like saying you're sysv compatible but not reproducing sysv behavior :^)

Written on 25 March 2015.
« What is and isn't a bug in software
Why systemd should have ignored SysV init script LSB dependencies »

Page tools: View Source, View Normal, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Wed Mar 25 02:16:41 2015
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.