29 July 2011

Oxymoronic: Computer Science & Software Engineering

I think I'll kill two birds with this stone. At RIT, there are two main computing majors: Computer Science and Software Engineering. Both of these are misnomers.

See, Computer Science is concerned primarily with programming as it relates to computing theory. Programming, while certainly related to the design of (reasonably) precise things, is by no means scientific. Science is systematic, rigorous, testable, and predictable. Computer hardware and software alike operate under the illusion of determinism and reliability for the sake of pragmatism alone.

Further, computing theory is only related to computing insofar as programmers actually implement the mathematical ideas of the theorists. Research is valueless without eventual application.

Software Engineering, on the other hand, is concerned with programming in the context of project management. It asks what the process is (or ought to be) for creating software in teams of people according to business requirements. Software engineers also operate under an illusion of determinism and reliability, but their misplaced faith is not in computers—instead their money is on programmers. The fool and his money have parted.

So computers are fallible, and programmers are fallible, and it's a wonder any of us ever gets anything done at all. The best programmers know the secret of how things are really done in the software world: communication.

I don't mean meetings, or agile (or worse, Agile), or documentation, or any of dozens of other borderline buzzwords that a manager might throw around. No, I mean the plain and simple fact that programming is writing, and programmers have the unique task among authors of writing in such a way that both computers and humans can readily parse and evaluate their work.

Of course, any fool can write for one or the other. If I write an informal description of an algorithm on paper, it's perfectly human-readable; if I write a formal implementation of an algorithm in heavily optimised machine code, then it's perfectly computer-readable.

And this is why I hate the word code. If you call it “coding” for a computer, then the quality of your writing from a human perspective is probably utter trash. Don't get me wrong, of course: for a first draft, utter trash is perfectly acceptable provided it can still convey the intended meaning.

But for a final draft, a certain amount of editing is necessary. Programmers differs from writing in another key aspect: though neither a program nor a work of prose is ever truly complete (final draft is an oxymoron as well), you must release both sometime; the difference is that a program, like a work of nonfiction, can be updated in editions to maintain freshness and currency.

Programming is like creating a diamond from scratch. When you code, you make the stone. You may then polish what's there and cut what shouldn't be, but both the colour and the clarity of that stone are immutable. No amount of refactoring will fix an idea that was poorly styled or unclear from the outset.

In conclusion, I might add that I insist that programming is not art. I believe this simply because I'm not good at art, but I am good at programming. I'm also good at design and craft, and that's what I believe programming is.

Programming is writing for one audience who seemingly doesn't understand you but is also endlessly critical, and simultaneously for another who seemingly understands you but is also painfully literal. It is writing manuals and dictionaries and phrasebooks to help these two disparate audiences communicate. It's logical, illogical, philological, analogical, anthropological, and frequently epistemological.

I fucking love it.

Oxymoronic: Pharmaceutical Company

There is a magical place where geniuses in white coats carry out research and produce remedies in the everlasting fight against human ailment. Most of them do what they do because they want to help people. The rest of them are businessmen (and women). Businessfolk are in the business of turning the work of the workers into the business of the businessfolk. By “the business of the businessfolk”, I naturally mean “the money of the businessfolk and the investors, and to a certain extent the workers as well, and to a much smaller extent some philanthropy and humanitarian aid to keep up appearances”.

So therein is the oxymoron: while you started your pharmaceutical company with good intentions, trying to reduce human suffering, now you don't want to reduce it at all, because when human suffering decreases, you'll see an equal decline in the sales of your remedies. That represents an equal decline in the funding available for your workers to carry out your research, which represents a loss of research, which allows ailments to propagate unfettered and suffering to increase.

Ordinarily I don't believe in doing things for the sake of doing things, but as a pragmatist, my objective morality compels me to pursue the path of least human suffering, as well as the path of least absurd complexity, which in this case means making a slightly unusual suggestion:

Pharmaceutical companies should not be companies. They should be government services. And before you say that our government is too far in debt to be creating more services, why don't we cut everything that isn't a public service and just see if the simplest concept isn't really the best?

On Brilliance

You are brilliant, but you don't know that the following things are true:

  • Your work is meaningless until proven meaningful; don't complain, work.
  • You do not have to be an insufferable asshole; you probably will anyway.
  • You are not better because you are smarter; you are worse for believing you are.
  • The world is not a meritocracy; your sense of entitlement is undeserved.
  • Intelligence is not a skill; you have to be able to do something.
  • The truth is not self-evident; you do have to explain.
  • You can't stop people from sticking beans up their nose; it won't stop you from trying.
  • You are a fool; wisdom comes only from knowing the depth of your own folly.

06 July 2011

Why Closures?

In a language with reasonably rich partial function application, it seems to me that there's very little need for implicit closures. In pseudocode:

greeter = λname.
    message = 'Hello, ' + name + '!'
    return λε. print(message)

greeter("world")()

Could easily be rewritten explicitly as something along the lines of:

greeter = λname.
    message = 'Hello, ' + name + '!'
    return λm. print(m) fix message

greeter("world")()

Where `fix` is an operator accepting a lambda and some parameters and returning a new lambda with the given parameters fixed, that is, λx. f(x) fix y is identical to λε. f(y). With the appropriate consideration given to reference semantics, this would have exactly the same effect; indeed, C++0x lambdas can be written with explicit closures exclusively:

return [&message]() -> void { std::cout << message; }

Supporting implicit capture not only complicates implementation; as with exceptions and globals, implicit capture reduces locality and makes analysis more difficult. Limiting functions to explicit capture requires support for lambdas with multiple parameters, because you cannot write:

sub = λx. λy. (x - y)

Instead you must write:

sub = λx, y. (x - y)

Which lends itself to partial application quite nicely:

neg = sub(0)
ident = sub(?, 0)

It would seem, then, that the primary reason for supporting implicit capture is historical, namely the roots of functional programming in the lambda calculus. And really, since implicit capture is the basis of scope, the fact that a functional language can easily survive without it calls into question whether the concept of scope is necessary or good. Functional programming is all about making state explicit, after all. Why not hold a function accountable not only for values it uses, but also for operations? I intend to play with this idea in the future.