Everyone agrees that programming languages should give the programmer more control, convenience, and flexibility, right? So all of the following sound like good ideas, don’t they?
Everyone knows that programs should not blow up.
(This is important, among other reasons, because users frequently provide silly input.) Operators should do something reasonable in almost every conceivable situation, and just let the programmer write tests for silly things. Therefore, given
a = "my dog has fleas"
we want the following results:
> a 'my dog has fleas' > a.substr(0, 2) 'my' > a.substr(3, 3) 'dog' > a.substr(42, 7) ''
because the programmer can always check for out-of-bounds results:
> a.length 16 > a.substr(42, 7).length 0
b = [2, 4, 6, 8]
we want these results:
> b [ 2, 4, 6, 8 ] > b 2 > b 8 > b undefined
because the programmer can always check:
> b.length 4 > (typeof b) === "undefined" true
Everyone knows that floating point arithmetic can overflow.
(Dividing a positive number by zero is a special case of that general situation.) Instead of blowing up the program, let’s just return a unique value that we can check for:
> isFinite(1 / 2) true > isFinite(1 / 0) false
and, of course, an overflow must absorb all subsequent computations:
> 1 / 0 Infinity > (1 / 0) + 4 Infinity > ((1 / 0) + 4) * 10 Infinity > (((1 / 0) + 4) * 10) - 5 Infinity > ((((1 / 0) + 4) * 10) - 5) / 2 Infinity
Everyone knows that overloaded operators promote familiarity and economy of notation.
Common mathematical and programming practice lead us to expect the following:
> 2 + 3 5 > 2.1 + 3.1 5.2 > "2" + "3" '23'
Everyone knows that we need automatic type conversions.
It is convenient to have “narrower” values converted automatically to “wider” types when evaluating expressions. So clearly we need this kind of “widening”:
> 2 + 3 5 > 2.1 + 3.1 5.2 > 2 + 3.1 5.1 > 2.1 + 3 5.1
Now that we’ve established that, the obvious next step is to support this kind of “widening” as well:
> 2 + 3 5 > "2" + "3" '23' > 2 + "3" '23' > "2" + 3 '23'
Everyone knows that we need controllable conversion of strings to numbers.
In addition to:
> parseInt("123") 123
programmers need to deal with binary:
> parseInt("1101", 2) 13
and other computer-oriented bases:
> parseInt("123", 8) 83 > parseInt("123", 16) 291 > parseInt("123", 4) 27 > parseInt("ff", 16) 255
Since we can specify the base explicitly, we might as well support this:
> parseInt("123", 7) 66
or (for those of us who fondly remember the PDP-10):
> parseInt("ff", 36) 555
After all, programmers always know what they’re doing, and should always get exactly what they ask for.
> parseInt( 1 / 0, 19 ) 18
Don’t repeat yourself.
is very different from simplistic responses to non-simple situations.
You don’t need static typing; just write tests.
If you want to eliminate run-time problems, just used a statically-typed language.
These problems are the fault of the other party; just vote for my candidate.
The title comes from a co-worker on a large project a few years ago. The effort offered several design challenges, and it seemed all to easy for well-meaning participants (and non-participants) to propose simplistic solutions. After a while, his standard response was to say with a grin, “All ya gotta do…“
give more detailed coverage.
There’s an Easter-egg link in the article to Dijkstra’s famous Turing Award lecture entitled The Humble Programmer. Despite its length (slightly longer than a typical blog post) and serious tone, it’s worth the time. Care in the construction of our programs is still appropriate, whether we call it “software craftsmanship”, “joint application development”, or “pragmatic programming”.
Even though the title phrase became an abused cliche, Structured Programming (A.P.I.C. studies in data processing, no. 8)
is a classic in our field. Although we have (some) nicer tools at our disposal, a careful reading shows how little the fundamental challenges of programming have changed in 40 years. A collection of Dijkstra’s essays, Selected Writings on Computing: A Personal Perspective paints a broader picture of the issues that have challenged us in roughly that same time frame. It is a mix of technical articles, notes on the computing culture of the day, and amusing (but pointed) parables.