假设你想创建一个日历程序。看上去很简单,是不是?从很多方面来看,的确如此。要想计算一年的天数,相对来说并不算困难。一般来说,一年有365天,遇到闰年就在2月底加上一天。怎样计算闰年?也不难。只需要看一下年份即可。如果年份可以被4整除,但无法被100整除,或是能被400整除,那么这年便是闰年。
也许你还希望这个应用程序能够处理时区问题。这应该也不算难。只需利用全球定位系统(GPS)中的地理坐标来确定所在位置的时区即可。你还可以创建一个列表,将各州与时区对应起来。当然,时区并不是沿着州界划分的。现在你需要用更具体的、分辨率更高的信息来处理小区域。此外,你还不能忘记,亚利桑那州的大部分地区都是不使用夏令时的,它把自己置于一个“特殊的时空”当中了。
是不是还想让日历程序包含节假日的相关信息?当然,节假日通常都有明确的时间安排,至少大部分节假日都是如此,把它们加上去应该不会太困难。感恩节是11月的第4个周四,美国退伍军人节被定在每年的11月11日。那么逾越节(Passover)呢?看来,我们还需要将这个日历程序与另一个基于希伯来历的日历程序整合到一起。因为逾越节是从希伯来历一月的第15夜伊始的。因此,我们需要远超预期的更多信息。
那么,你是否还希望这个日历程序包含其他时间段,并且在过去时段和未来时段上都表现得准确无误呢?如果我们回到19世纪,在那个时代,由于标准化时区制尚未被推行,所以各个城镇都有自己的时间制度,而这些信息都需要“硬编码”(hard-coded) 到我们的应用程序中。与此类似,在过去的几个世纪里,虽然全球许多国家和地区都已放弃使用罗马儒略历(Julian calendar),转而使用格里高利历(Gregorian calendar),但是各国以及各地区所采用的具体时间制度并不全然相同。例如,俄罗斯“十月革命”的纪念日之所以是在11月,是因为在革命发生时,俄罗斯仍在使用罗马儒略历,其日期与西方许多地区所使用的格里高利历相差一周多,而“十月革命”发生在儒略历的10月底。如果希望日历程序准确且详尽,那么就应该将此类信息也植入进去。
这个过程还将持续下去。
以这种方式构建起来的系统最终会变得复杂无比,因为它所要反映的事物,本身就是复杂的。 [48] 通过一个简单的模型来处理绝大多数复杂性,是相对直接的方法。比如,我们知道了一年有365天或366天,就可以通过简单的运算来确定某一年到底有多少天。但是,如果你对准确性有要求,无论是想确保永远不会错过任何一个约会,还是想构建一辆既不会迷路也不会撞伤人的自动驾驶汽车,事情就会变得非常复杂。 [49]
这种复杂的情况就是必须处理的例外情况,也就是所谓的“边界情况”(edge case),若不处理,技术系统就会出现漏洞。 [50] 边界情况各种各样,从闰年问题,到如何编写数据库软件来处理特殊的人名,比如人名中带有特殊符号的情况。我们不能说边界情况是普遍现象,但它们确实经常出现,所以我们必须加以识别和管控。但是与此同时,技术的简单性也就渐渐消失了。边界情况使技术变得复杂了。这一点在科学模型中尤为突显,科学模型也是一种技术,也会随着时间的推移而发生变化。接下来,我们就以社会科学中的语言学为例展开讨论。