acm-header
登录

ACM通信

实践

我们用来计算的隐喻


我们计算的隐喻,插图

图片来源:Andrij Borys Associates / Shutterstock

回到顶部

在他们现在的经典著作中我们赖以生存的隐喻6乔治·拉科夫和马克·约翰逊开始向语言学和哲学世界表明,隐喻不仅仅是诗歌和华丽的修辞。他们展示了隐喻是如何渗透到我们生活的各个领域的,尤其是隐喻决定了我们如何理解世界,我们如何在其中行动,我们如何在其中生活。他们表明,我们的概念系统也是基于隐喻的,但由于我们通常意识不到我们自己的概念系统,他们不得不通过一个代理来研究它:语言。

通过研究语言,莱科夫和约翰逊试图理解隐喻是如何在我们的生活中赋予意义的。他们提出的基本例子是概念隐喻“争论就是战争”。我们理解与另一个人争论的行为,就像我们理解战争一样。这就导致了我们日常语言中的以下表达:

  • 你的索赔站不住脚的。
  • 攻击每一个弱点在我的观点。
  • 拆除他的论点。
  • 我从来没有赢得了和他争吵。

这些句子可能看起来无伤大雅,但问题是基于它们我们如何行动和感受。我们最终会把和我们争论的人看作是我们的对手,某人攻击我们的立场,所以我们组织我们的论点,就好像我们在和另一个人打仗。这意味着隐喻不仅仅是语言的繁盛;我们生活。拉科夫和约翰逊建议设想一种文化,在这种文化中,争论不被视为胜利者和失败者之间的战争,而是语言是一种舞蹈,你必须与一个伙伴合作,以一个团队的形式达到一个预期的目标,得出结论。

这本书继续分析了语言和隐喻的不同方面,以及它们如何影响我们的概念和世界观。两位作者举了很多例子来论证我们对世界的理解是基于隐喻的,而这些隐喻是行为的基础。

本书最大的启示之一是,隐喻促进了某些思维方式,同时限制了其他思维方式,正如争论即战争的例子所说明的那样。本文将此思想应用于计算机科学。隐喻如何塑造我们理解计算及其相关问题的方式?使用的隐喻会导致什么样的问题?而且,单子不像墨西哥卷饼!8

首先,本文探讨了隐喻如何帮助我们理解相对年轻的计算机世界,以及它们如何影响我们构建代码或设计算法和数据结构的方式。我们甚至根据隐喻是我们的武器库的一部分来解决问题工具箱。“有时候,我们的工具会按照我们的要求行事。其他时候,我们调整自己以适应工具的要求,”作者Nicholas Carr在他的书中说道浅滩。3.隐喻是理解的工具。

回到顶部

隐喻的理解

人们通过将新概念与已有知识联系起来来理解新概念。早在20世纪40年代末和50年代初,当今天的计算机诞生时,还没有这样的发明的词,但人们把它们理解为自动大脑。实际上,这个词电脑当时是存在的,但用来指为工程师做计算的人。想想工程师需要知道炮弹的轨迹,或者风会如何影响飞机的机翼形状;他们会抛出一些公式和数字人的电脑才能得到答案。现在出现了这些自动完成工作的新机器;他们被称为电子计算机,最终放弃了电子名字的一部分。所以,我们自己的学科是以一个比喻来命名的。

但如果你不理解隐喻的局限性,隐喻也会掩盖可能性。新隐喻的一个常见问题是,这个词的原意是根据表面价值使用的。用来解释一个新概念的词实际上可能会限制对这个概念本身的理解。在他的书中的信息5詹姆斯·格莱克对电报的发明作了引人入胜的叙述。这个词tele-graph意味着far-writing。你瞧,早期的电报是一种奇怪的机器,它试图在远处写东西,把字母表中的字母一对一地映射成电线,这听起来非常不切实际。大约在那个时候,多亏了路易斯·布莱叶(Louis Braille),人们开始明白,语言可以以一种不同于发音(或书写)的形式编码。摩尔斯电码是改进电报的下一步,也让人们认识到,人们不必“远距离写作”才能进行真正的远距离通信。

多亏了数学家克劳德·香农和其他像他一样的人,我们成功地摆脱了电报隐喻和建立整个信息论学科始于20世纪40年代末。香农的重要著作,通信的数学理论,提出了通信的基本要素:信息必须先被编码,然后发送到一个通道,由另一端解码,目的端才能接收到信息。7

回到顶部

隐喻和代码

有一句著名的未署名的名言(通常被误认为是Charles Baker的名言)是,“编程就是给另一个程序员写关于我们对问题的解决方案。”2程序是对如何解决问题的解释;这是一种隐喻,代替了一个人的理解。然而,为了使隐喻有效,它们需要使用我们已经知道的概念来传达意义。一个特定程序的解释力可以用来衡量它本身的优雅程度。

考虑下面的例子。比方说,你可以编程一台计算机来命令其他计算机执行任务,尊重它们的到达顺序。这种描述已经很难理解了。另一方面,你可以通过描述a来描述解队列服务器分配工作工人基于一个先到先得队列纪律。

排队是一个日常生活中常见的概念,在超市、银行、机场和火车站都能看到。人们知道它们是如何工作的,因此对于阅读您的代码的人来说,谈论队列、工作者和作业可能比试图解释这个设置而不使用队列比喻。

通过选择正确的隐喻,您的程序达到了一个抽象级别,使不了解问题的人理解解决方案所需的努力最少。此外,解决队列问题免费提供了完整的数学理论。数学本身是一个只有当一种适当表达的语言可用来处理问题时才能解决问题的领域。有了队列的比喻,您就不再是在黑暗中盲目打拳了。现在,您可以使用队列理论提供的所有工具来分析和理解这个问题。

回到顶部

作为隐喻的数据结构

分析数据结构可以帮助我们了解哪种结构更适合特定问题的性能特征,但我们常常忘记数据结构还包含解释能力。

数据结构的选择有助于传达含义。可以在数组中存储一堆元素,但如果需要确保元素是惟一的,该怎么办呢?这不正是该做的吗?您的集合的底层表示仍然可以由普通数组支持,但现在您的程序以更清晰的方式表达其意图。当其他程序员阅读它时,他们将理解集合中的元素必须是唯一的。重要的是要认识到,程序只是计算机需要处理的另一个比特序列。是程序员赋予这些位的意义,所以您必须在它们之上使用正确的隐喻,以使您的程序更清晰。如前所述,“没有人见过机器不能理解而人能理解的程序。”2

您必须努力使您的程序对其他程序员来说尽可能容易理解。理解的容易程度应该是衡量程序的标准。请记住,您可以用许多不同的方式排列代码来解决计算问题,但并不是所有这些排列都有利于人类的交流和理解。您必须问自己:通过阅读我的代码,其他人是否能够理解我是如何解决这个特定问题的?


通过选择正确的隐喻,您的程序达到了一个抽象级别,使不了解问题的人理解解决方案所需的努力最少。


正如隐喻支持某些理解方式并限制其他方式一样,数据结构也是如此。之前我们看到了使用直接隐喻的问题,比如最初的电报。当涉及到数据结构时,您可以看到集合将显示其元素是唯一的,并且它将允许您测试一个元素是否是集合的成员。但是,对于链表,您可以一个接一个地遍历它的元素,而不能够跳过它们。对于数组,您可以通过索引来寻址它的元素。队列和堆栈也是如此,这两种最基本的数据结构在任何算法课程中都是教授的。每种方法都可以使用数组来实现——不同的是,一个方法分别以FIFO(先进先出)的顺序返回元素,而另一个方法则分别以后进先出的顺序返回元素。

即使这看起来像是大多数程序员每天都要做的事情,但当您选择使用堆栈而不是队列时,您就决定了如何解释您的程序。堆栈是程序处理的项的集合的一个很好的比喻,因为它告诉程序的未来读者期望处理项的顺序。您甚至不需要阅读堆栈是如何实现的,因为您可以假设您将按照后进先出顺序获取项目。这就是为什么类型在计算机科学中如此重要的原因——不是程序静态类型检查中的类型,而是类型概念用来描述程序:人,用户,栈,树,节点,你能想到的。类型是讲述程序故事的字符;如果没有类型,就只能对字节流进行操作。

回到顶部

认知上的飞跃

目标是找到正确的比喻来描述和解释问题。正如前面在排队理论的例子中所解释的那样,从必须按特定顺序处理的任务到理解这是一个排队问题需要一个认知飞跃。一旦你成功地实现了认知上的飞跃,所有排队理论的数学工具都可以为你所用。图论充满了日常任务的例子,一旦转化为图问题,就有众所周知的解决方案。每当您请求谷歌Maps将您带到目的地时,谷歌将您的问题转换为图形表示,并给出一个或多个建议路径图中。图是正确的比喻,数学家和计算机都能理解。有没有其他的例子,似乎很难,但可以通过找到正确的比喻来解决?分布式系统的文献非常有趣。

在20世纪80年代末,施乐公司的Alan Demers和他的同事们试图找到在不可靠的网络中复制数据库的解决方案。他们将自己的算法分类为“随机”,并用谣言传播的比喻来解释:一台计算机将更新的消息告知另外两台计算机,然后每台计算机依次将更新的消息告知另外两台计算机,以此类推,直到信息在整个系统中被复制。这个比喻让位于一个叫做八卦算法的新研究领域。的流言蜚语隐喻使得这个想法很容易解释,但是施乐团队仍然缺乏数学工具来帮助分析算法的有效性。

在他们的研究中,他们发现了另一个与他们的问题相关的隐喻:流行病。他们认为,他们的算法复制数据的方式与流行病在人群中传播的方式相同。通过使用这个新的比喻,他们可以立即接触到所有的知识流行病的数学理论1和他们的工作非常吻合。他们不仅将论文命名为“用于复制数据库维护的流行算法”,4他们还用该学科的命名法来解释他们的算法。这是一个找到正确的隐喻,从而进入一个解释力强大的新世界的问题。

回到顶部

隐喻无处不在

我们真的在编程中使用了那么多的隐喻吗?让我们看一看分布式系统文献中的一个例子斜体):

每当节点需要同意在一个共同的价值上,a共识算法用于决定在一个值。通常有一个领袖过程,该过程负责根据它从它的同行。节点之间通过发送通信消息在一个通道,这可能会变成拥挤的因为太多流量。这可以创造一个信息瓶颈,队列在每一端渠道备份。这些瓶颈可能呈现一个或多个节点反应迟钝的,导致网络分区。这个过程是不是太长了回应死亡?为什么它不承认心跳而且触发一个超时?可能还会继续,但你懂的。

回到顶部

代码故事

程序员必须能够用他们的代码讲述一个故事,解释他们如何解决一个特定的问题。像作家一样,程序员必须知道他们的隐喻。许多隐喻都能够解释一个概念,但您必须有足够的技巧来选择正确的隐喻,以便能够将您的想法传达给将来阅读代码的程序员。

因此,你不能使用所有你知道的隐喻。你必须掌握选择隐喻和扩大意义的艺术。你必须知道什么时候加减。您将学习像作者一样修改和重写代码。一旦没有其他东西要添加或删除,您就完成了您的工作。你一开始的问题现在已经解决了。这就是你一开始想表达的意思吗?

回到顶部

致谢

感谢Jordan West和Carlos Baquero关于隐喻如何渗透计算的讨论,以及他们对本文的反馈。

ACM队列的q戳相关文章
queue.acm.org

首先,不伤害:软件开发人员的希波克拉底誓言
菲利普·a·Laplante
http://queue.acm.org/detail.cfm?id=1016991

为代码编码
弗里德里希·斯泰曼和托马斯Kühne
http://queue.acm.org/detail.cfm?id=1113336

一段不错的代码
乔治诉Neville-Neil
http://queue.acm.org/detail.cfm?id=2246038

回到顶部

参考文献

1.贝利N.T.J.流行病的数学理论。C.格里芬公司,1957年。

2.贝克,c (Ed)。程序员的工作。自动化资料处理(1967年4月);http://archive.computerhistory.org/resources/text/Knuth_Don_X4100/PDF_index/k-9-pdf/k-9-u2769-1-Baker-What-Programmer-Does.pdf

3.卡尔,N。浅滩。诺顿出版社,2011年。

4.Demers, A., Greene, D., Hauser, C., Irish, W.和Larson, J.用于复制数据库维护的流行算法。在六人会议记录thACM分布式计算原理年度研讨会,(1987), 112。

5.格雷克J。信息:一段历史,一种理论,一场洪水。万神殿,2011年。

6.莱科夫和马克。我们赖以生存的隐喻。芝加哥大学出版社,1980年。

7.香农,C.E.和韦弗,W。通信的数学理论。伊利诺伊大学出版社,1949年。

8.抽象、直觉和“单子教程谬误”。https://byorgey.wordpress.com/2009/01/12/abstraction-intuition-and-the-monad-tutorial-fallacy/

回到顶部

作者

阿尔瓦罗·威德拉alvaro-videla.com@old_sound)在一家瑞士大公司担任首席架构师。此前,他是苹果公司的高级软件工程师和RabbitMQ的核心开发人员。他是RabbitMQ。


版权归所有者/作者所有。授权ACM出版权利。
请求发布的权限permissions@acm.org

数字图书馆是由计算机协会出版的。版权所有©2017 ACM, Inc.


没有发现记录

Baidu
map