Auto Ads by Adsense

Sunday, January 20, 2013

The "Science" in Computer Science

When I was an undergraduate, it was very common for many of us to view the "science" in Computer Science as an oxymoron. The proof was that all the "real" sciences had names like "Physics", "Chemistry", "Astronomy", and "Biology", while we were lumped in with "Political Science", "Social Science", and of course, "Military Science". Many took the position that Computer Science should be considered a branch of mathematics, while those of us who were liberal arts majors (I count myself and Jonathan Blow as the major advocates of this) considered Software Engineering a branch of the literary arts as the goal was ultimately to produce code that was easy for humans to read, since machines didn't care what your code looked like.

If you read Thomas Kuhn's The Structure of Scientific Revolutions, however, there is a sense in which Computer Science is a science. Consider the construction of a program to be a sociological construction of a theory about how best to approach a problem. You start out with version 1, which solves some portion of a problem. Later on, as the problem is better understood through the lens of your theory (i.e., your users start using your program and start providing you with feedback), you tinker with your theory to make it better fit the evidence (user feedback or market feedback). As a result, your program becomes more complicated and your program's structure (theory) starts to show it's datedness. When things go to a head, however, you either refactor or rewrite all the offending crufty code, throwing it away and replacing it with a new program (theory )that accommodates all the evidence to date. This is equivalent to perhaps relativity supplanting Newtonian physics. Note that the analogy even holds here --- old versions of your program continue to work, but the newer program (better theory) is more elegant, and fits better with the problem space. If your rewrite fails, the result is less useful than the previous version and society refuses to adopt your new program. For instance, Vista was not widely adopted and most users stayed on Windows XP instead.

There's even space in there for unit tests and systems tests: those tests are the empirical experiments by which you attempt to prove that your theory (program) works. In effect, when writing tests, you're trying to prove that your theory about how the problem should be solved is wrong. If you have the resources, you might even want such experiments be run/written by a third party, so they have no cognitive biases with which to approach the problem.

Obviously, this view of software engineering as actually "doing science" can only be carried up to a limit, but I find it to be an interesting analogy, and would be interested in hearing your thoughts.


lahosken said...

If you'll excuse me, I have to go create the #overlyhonestheuristics hashtag.

Jeremy Ong said...

When I grew up, I thought that computer engineers were the people who designed and built software, and computer scientists were people who worked on NP Hard problems on pencil and paper.

Typically, when I think of "science" in general, I think of a hypothesis driven subject (hence, the scientific method).

The funny thing about computer science is that it's much more hypothesis driven than people would expect. Even though a single machine is deterministic (if one can believe or accept that), the network and interworking of larger systems in general is anything but.

But once the design has been specified, I think the actual implementation is the non-science that a scientist has to do to verify his hypothesis via experimentation. In physics, there is also an aspect of experimentation that feels very "liberal arts" as you mention, because communicating the result afterwards is paramount.

systemBuilder said...

I don't consider software engineering to be computer science, but software engineering is more akin to biology, since successful software projects grow very much like living organisms, they grow in certain directions, undifferentiated (like early UNIX), then those undifferentiated parts get more elaborate, and they grow in spirts, followed by a consolidation period where the gains are optimized (did you know that babies grow as much as 1 inch overnight? At that point, they consolidate their gains and prepare for the next growth spurt ...)

Computer Scientists are generally considered with coming up with general techniques to solve problems that are provably optimal or provably better than previous techniques. THAT is a very different pursuit than software engineering.