Live data from Hacker News

A significant amount of programming is done by superstition

utcc.utoronto.ca

81–90 of 214 posts

Re: A significant amount of programming is done by superstition

#81
post #14

I'll have to admit something about myself -- I've never been able to learn how to do anything from just reading its first principles. I need to have a working example that I can then adapt and change and observe changes in the result. This has been especially true in programming. I've been writing programs in some capacity for 18 years now and not once in that time have I been able to simply read the reference manual…

Almost nobody can. Some people think they can, and charge forward with it, but rarely do they produce something that actually works. Usually, they bang on it and test it and cargo-cult it until it works, then convince themselves that it's from 'first principles'. Even if it were a common ability to produce engineering work from written design principles, I'm not certain that's what we want. Experimentation is the key…

> Experimentation is the key to science.

Computer science is a branch of mathematics. Here you build models, reason about them, find properties, then prove them, then rely on them. Tests - a.k.a. experiments - are usually not exhaustive and don't provide guarantees of correctness.

Having said that, I agree that experiment is of crucial importance - how else you would validate your models in the first place? However, both experimenting and reasoning can be flawed, and part of the trick is to learn how to do that properly. Computer science is difficult.

Re: A significant amount of programming is done by superstition

#82
post #9

Earlier quoted context omitted.

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". [1] https://en.wikipedia.org/wiki/Cargo_cult_programming

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,…

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.

Re: A significant amount of programming is done by superstition

#83
While the article is dramatically true (credits to StackOverflow for some of my production code), there's a factor that isn't taken into account here: time.

Yes, because as engineers our time is more valuable than a minimal and perfectly-standard-compliant solution. I would happily read all the RFCs, and all the significant papers in CS, and all...etc.

The reality is that we don't get paid to read, but to ship.

Re: A significant amount of programming is done by superstition

#84
post #68

Earlier quoted context omitted.

"A significant amount of (shipped, so-called production-quality) code is not fully understood by its authors" Of course. Time spent fully understanding the code before it's shipped is time that it's not shipped. This is sort of a Gresham's-Law situation, where "bad code drives out good code". The code that is fully tested & debugged with all situations understood isn't available to the user at first. As a result, the…

Anyone can build a bridge that stands up, but only an engineer can build a bridge that barely stands up. Good Enough is our main design goal. Anything more than good enough means you're wasting resources.

And that applies not only to engineers, but to managers - i.e., task definers. Managers aren't interested to ask engineers to build something which will withstand the test of time unless they are sure that time will be actually needed - and with limited information (and high speed of changes) you have today managers tend to think short term. So the whole civilization works along the principle of dog chasing the rabbit running from left to right - instead of predicting where rabbit will be in 10 seconds, let's run straight towards the rabbit and in half a second update the course. We win since rabbits don't usually run predictably along the straight line.

Re: A significant amount of programming is done by superstition

#85
A very sigifigant part of Ansible service module code was done to deal with misbehaving init scripts. They are very much cargo-culted just like RPM or debian package formats - borrow the ones from your previous project.

They are hard to get right and many apps don't daemonize correctly or return OK before they are ready to be running - and then are actually running much later. Upstart/systemd didn't neccessarily make that more clear for people to understand either.

While I haven't tried it, I recently encountered a reference to https://github.com/jordansissel/pleaserun and it sounds promising.

I don't know how much of this applies to programming in general, really, but init scripts are.. yes... special things.

Re: A significant amount of programming is done by superstition

#87
I am someone who tends to work from first principles, to a fault. It slows me down a lot. But it's like a compulsion.

StackOverflow has improved my programming life dramatically, because it makes it a lot easier to "memoize" the search from what you're doing down to first principles. Whatever question you're trying to get clarity on, there is probably a StackOverflow answer out there that builds a positive case for a particular option, going all the way back to primary documents like standards.

Re: A significant amount of programming is done by superstition

#88
post #9

Earlier quoted context omitted.

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". [1] https://en.wikipedia.org/wiki/Cargo_cult_programming

not applicable either, the code and program structures serve a purpose and the article specifically described removing parts that are not applicable.

Except there's always that nagging feeling in the back of a programmer's head that says, I might need that later.

Silly as it may be with things like git around, I can recall thinking, "maybe we will run this on AIX..." when hacking on a multi-OS shell script.

Not good practice to leave the bloat in, but at least give developers the benefit of the doubt that it isn't outright magic to them.

Re: A significant amount of programming is done by superstition

#89
post #81

Earlier quoted context omitted.

Almost nobody can. Some people think they can, and charge forward with it, but rarely do they produce something that actually works. Usually, they bang on it and test it and cargo-cult it until it works, then convince themselves that it's from 'first principles'. Even if it were a common ability to produce engineering work from written design principles, I'm not certain that's what we want. Experimentation is the key…

> Experimentation is the key to science. Computer science is a branch of mathematics. Here you build models, reason about them, find properties, then prove them, then rely on them. Tests - a.k.a. experiments - are usually not exhaustive and don't provide guarantees of correctness. Having said that, I agree that experiment is of crucial importance - how else you would validate your models in the first place? However,…

Programming is a branch of engineering. Very little programming is done by proof; It's done by experimentation, debugger, and tests are human-reasoned and hopefully cover all codepaths and critical junctures (for every x > 0, you test x=1, x=0, x=-1).

Proof is of critical importance - It's how you find those junctures, for example, how you optimize, how you design and how you reason about runtime, etc. But programming as practiced in the field is engineering first, mathematics second.

Re: A significant amount of programming is done by superstition

#90
post #27

Earlier quoted context omitted.

A lot of us find Yoda conditions easier to read: if(0 == very_long_function_name_here(param1, param2)) { Tells me a lot after I've read a little of the line, whereas: if(very_long_function_name_here(param1, param2) == 0) { Makes the == 0 part easy to miss, and buried behind a lot of clutter.

Why would you ever have a function with a name that long in the first place? Also, there are many more ways of dealing with readability: try different formatting and indentation rules, wrap lines manually where you think it makes sense and so on. As for your example, even the lowly C let's you do something like this: int (*short_name)(int) = &veeeeery_long_and_ugly_and_unnecessary_function; if(short_name(1) == 2) { p…

Why would you ever have a function with a name that long in the first place?

Sometimes you might not have a say in how the function was named... having some practices to deal with the unruly code that hasn't been graced by one's own perfect sense of style isn't terrible! ;)

try different formatting and indentation rules, wrap lines manually where you think it makes sense and so on.

All fine ideas, but I wouldn't discount yoda-conditions as not being in the same category.

Some languages are more opinionated than others, but one positive thing about "superstitious" programming is that code is often more consistent because of it ('pythonic' PEP 8, code patterns, skeletons/boilerplate, ...). Many times you'll end up seeing the same patterns elsewhere, for example adherence to Google C++ style guidelines on projects completely unrelated to Google -- simply because they are both practical and familiar.

In a similar vein, I'd probably religiously opt for a #define ... #undef pattern for your given example, because I've seen it more often than using a separate function pointer variable. There isn't really a technical advantage, but mostly one of familiarity.

Post reply on HN