I actually really like the content of the article, but I'm not convinced superstition is the right word here. Yes, absolutely I have copied an init script / makefile or whatnot and if it worked after I tweaked it then I went on my business. But I didn't use it as is because of superstition, but rather because it now worked I believed it correct.
Yes, quite often that came without a perfect knowledge of every single option, certainly usually without referring to the manual for every one of them.
Perhaps this is semantics. But the definition of superstition is:
a widely held but unjustified belief in supernatural causation leading to certain consequences of an action or event, or a practice based on such a belief
Which ya, isn't quite the right thing. Anyways, agree with the sentiment of this 100%, just not the title. :)
I think this is more commonly called "cargo cult programming", defined by Wikipedia[1] as: "the ritual inclusion of code or program structures that serve no real purpose".
I think there's a significant distinction here to be made between "configuration" and "programming".
Do I copy/paste swaths of code that I don't understand and put them in my programs? No, absolutely not, because each line is one I can reason about and want to understand.
But do I copy/paste swaths of configuration files / init scripts / etc, without understanding the implications of every single configuration? Yes, absolutely, because the depth behind each of those options is often irrelevant to me. (until I discover otherwise late at night when an alarm goes off (!!))
I think it is important to distinguish these. I don't think any dev that's done ops work would claim they aren't guilty of the latter, but at the same time I think very few good devs ever, and I mean ever, do the first.
Init scripts are code though. I mean, they're code that's mostly boiler plate, but they're still code - I can do arbitary things in them, reasonably unconstrained by their stated purpose.
Configuration is programming. Perhaps I, being the devops sort, am somewhat alone in this opinion, but I opine it anyway: Configuration is programming. Often very simple programming, but programming nonetheless.
There's a configuration language a Google that's stated goal is that it's not turing complete... and yet it is, because it was a necessity for achieving the expressiveness, and now it's almost entirely unreadable because of the convolutions needed to achieve the real-world solutions necessary in it. There's another that's python based, and widely bashed for being 'too hard to reason about', but it has none of the problems with disgusting 'standard' libraries.
Where I am now, Facebook, has adopted a python based model... and used almost none of python's features. Instead, everything is generated through convoluted lists and dictionaries, and it's treated with very little exception as a json file. This saddens me.
Almost all configuration should be done by libraries with sane defaults. So should programming, even though it's not.
I don't believe this to be so, necessarily. You can copy-paste code AND understand what it does. I'm not sure how this is cargo-cult programming on its own(because it's not). To me creating factories, interfaces, and object hierarchies "because that's how it's done" without understanding why or whether or not it's actually needed is more "cargo cult" programming.
There are certainly people who just copy-paste code without understanding it. As an anecdote(because I'm on a role apparently with this topic) copying C# code off of StackOverflow that does AES encryption but sets the IV to all zeroes.. And not reading the comments that say this is bad practice but a customer constraint...
I guess my point is that a LOT of people seek and implement examples and while some don't understand them some find them extremely efficient and DO understand them.. In fact every time you use a library you are, in effect, copy-pasting code that you are relying on...
Yes, I would characterise a lot of programming as "cargo cult" programming.
I'm not sure what the details are here besides init script, but in this particular case the job is boring and difficult/slow to test. Who wants to reboot their machine all the time to test it?
... Which is why sysv init has taken so long to fix. If it's not obviously broken it won't get fixed.
The part about how people "copied an existing init script or thought ... that init scripts needed LSB headers that looked like this" sounded like it to me.
I didn't initially manage to follow the right sequence of links to find the example[1], but now that I have, the context seems to be that "System V init ignores all of these" (the parts people copied without understanding), so the description still looks applicable to that example. (They serve no purpose at the point in time when they're added by cargo-cultists but cause problems much later when someone/something assumes that they are actually meaningful.)
Yeah, I don't really get what definition of "superstition" the author is intending here. It seems like "laziness" or "lack of rigor" would be more appropriate terms.
Traditional superstitions include not walking under a ladder, and throwing spilt salt over the left shoulder. "Lack of rigor" would apply to these but "laziness" would not.
Superstition connotes that an act is performed due to faith that it is beneficial or necessary, rather than an understanding of the underlying mechanism or controlled experiments to demonstrate the need.
> Yes, absolutely I have copied an init script / makefile or whatnot and if it worked after I tweaked it then I went on my business. But I didn't use it as is because of superstition, but rather because it now worked I believed it correct.
That, plus the whole "ugh, I don't want to have to write all this boilerplate from scratch".
Initscripts are mostly boilerplate, and it's just plain tedious do to anything other than copy/paste what you know works.
I had the same issue. 'Superstition' wasn't the right word. Perhaps 'pragmatism' or even 'science': "This has been observed to work, I shall use it again. I will abandon it for a better one should I find one, or if it should fail".
Pragmatism doesn't need to draw a cause/effect link like superstition does, and superstition doesn't generally lend itself to abandoning faulty beliefs.
I'm not picking at what you do just trying to explain the author's context.
The first principles of computation are mathematical and believing something to be correct is not the standard. Proving is the mathematical standard. I take the author's point of reference to be more formal processes than the ordinary practical programming practices they criticize.
The first principles of computation are not the first principles of software development. A computer is not a Turing Machine: it is an electro-mechanical wrapper around the limited imitation of a Turing-like core, and that wrapper and the physical properties of the system put extreme limitations on what can or cannot be proven.
Software development is a perfectly ordinary engineering activity, or should be (although it is mostly done by non-engineers), and the same standards should apply. No mechanical engineer or electrical engineer has ever shipped a "provably correct" machine. They have shipped machines that conform to best practices, including heuristic analyses of MTBF and so on.
As I said, I was only attempting to clarify the author's intent [in so far as I could divine it]. So perhaps your counter-argument might be better directed there.
Out of curiosity, if the first principles of software development are not based in mathematics, what do you believe are their basis and how does it differ from "folk wisdom" if we take "folk" to include communities of engineers rather than as merely pejorative?
Do I trust my OS to have a memory allocator that works and to protect processes from reading and writing each other's memory? Yes, but not totally.
Do I trust its more modern and complex APIs? Less so.
Do I trust code I copied from stackoverflow that has 100+ points? Yes, but even less so than I trust the complex or new corners of my OS. So, I read every line I copy. On the other hand, I am lazy, so if this gets to 1000+ lines, chances are I won't read every line. I will think a bit more about the trust issue, though.
Do I trust the documentation of the libraries shipping with my OS? More than stack overflow answers with 20-ish points, but certainly not completely.
Do I make assumptions about APIs? I try not to, but it is hard. There is lots of documentation where it is hard or impossible to find out what the code claims to do in edge conditions.
For example, in https://msdn.microsoft.com/en-us/library/352y4sff(v=vs.110)...., can one pass a null transaction? I wouldn't know, and the page doesn't tell me, so this afternoon, I wrote a conditional operator calling another constructor if transaction is null.
I did consider a "let's try it and assume it always works if it works once" approach, though. I also think many people do that ('if it compiles and runs, it must be valid C')
We generally have some idea of what's in the black boxes we use, and we are always open to change our beliefs based on new evidence ("faith" is a belief that will stay the same no matter what evidence is presented: in Bayesian terms it is a belief with a prior of 0 or 1, neither of which can be changed by any evidence.)
"Hopeful" or "optimistic" programming might be better.
Yes, quite often that came without a perfect knowledge of every single option, certainly usually without referring to the manual for every one of them.
Perhaps this is semantics. But the definition of superstition is:
a widely held but unjustified belief in supernatural causation leading to certain consequences of an action or event, or a practice based on such a belief
Which ya, isn't quite the right thing. Anyways, agree with the sentiment of this 100%, just not the title. :)