yield的字面意思

Geek Talk里的一段对话,关于yield这个单词是否在所有编程语言里都是相同的含义。出于隐私,隐去了讨论者名字。不对讨论内容的正确性负责。

W:各位,我请教一个英语问题,yield 这个词语有几个意思?我最早是在Java里,Thread 有个 yield 方法表示 当前线程让出cpu,让其他线程先执行。yield 在这里的意思是“屈服, 放弃,让出”。后来在 C# 里,迭代器的实现可以用 yield return ,我当时就对 C# 里的 yield 和 Java 里的 yield 在意思上有没有相同的根源产生过怀疑,但没深究,就把它当作“产生,生成” 的意思来理解的,(我不确定我当时的理解对不对),后来在 Scala里 for推导里也有 yield 关键字,我也同样当作“产生,生成”的意思来理解。最近看到lua 的 coroutine里也有 yield ,我觉得可能它们是有相同或相似的根源的,只是我没有get到,这几种语言里 yield 所表达的,跟操作系统的线程原语 yield 是不是都是一个意思呢?

Y:是同源。因为Java刚出来时,Linux还没有线程那时候Unix有make_context,相当于非抢占的协程,所以Java的yield是为了给这些操作系统用的,但实际上到头来并没用上。

R:我一直认为c#里yield是生产、生成的意思,因为它只能用于实现IEnumerableyield后面必须跟return<element>,或者break,代表生产终止

W:我的英文不太好,所以我在猜测,到底这个词本身就确实有很多意思(就像中文里的“打”这个字不同上下文不同的意思),在这几种语言里 yield 也是不同的意思呢,还是 我们误解 C# 和 Scala 里的 yield 其实也是 “屈服、让出” 的意思(背后其实是流控上的含义?)

W:协程本质上是一种流控,我这么说有没有问题?还是说流控是协程实现手段之一更合理

Y:yield这里是专有名词,意思就是让出的意思,不过词源我不清楚。

W:从我了解到的 yield 这个关键字在多数语言里(C#, Scala, Python)里应该都是“生产、生成”的意思,而跟 java 里表示线程的 “让出”,完全不搭边。但在lua的coroutine 里 yield 又跟 Java线程的 “让出” 意思一致

M:感觉是动作的对象不一样而已吧

W:scala / python 里的 for comprehension 里的 yield 如果也是“让出”的意思而非“生产”的意思,还是有违背直觉的,尽管从 Control flow 上能解释的通

W:一切用到 yield关键字 的编程语言,含义都可以归纳为“交出控制权”?

S:伙计,我说一下现实生活中yield的例子,可能对你有帮助。在美国的公路上碰到yield的路标都表示在前方汇合点你要让行,如果没有车你可以并线。

W:这个例子解释线程的yield原语没有问题,但对 for-comprehension 或迭代器里的yield又怎解释呢?

W:补充给python程序员,Scala 里的for-comprehension跟 Python 里的list-comprehension是一回事,只不过更泛化。

G:to yield is to give up (something you own) on demand / claim. 我觉得如果从这个含义出发去解读,不论是线程(竞争中的个体)“让出”控制权(放弃抵抗或者内心执念),还是迭代器(农作物)“产出”值(粮食)都 make sense。 #my2c

W:这正是我觉得有所不对劲儿的地方,因为编程世界里通常是不太会出现 具有多重意思(含混)的 英文单词的。所以有可能是我们误解了 yield ,没有真正理解清楚。我现在偏向于,它在所有上下文里都是统一的含义:保存当前上下文(比如栈),让出执行权。

L:我觉得你的理解没错呀,yield更像是个受控的goto

G:我觉得yield这个词虽然有多种具体的释义,我直观感觉其内涵是一致的,只不过确实抽象了些,这让我想起英语和汉语的某些根本性的差别(抽象 vs具象,不定性vs定性)。可能有人会觉得我接下来的解释太过牵强,不过anyway我还是说了:这种抽象就像monad,它抽象了一种行为特征,同时任何一种具象的实现都不能完全表达出这种抽象,但每个具象的实现都能让我们更容易理解它(或者说让它更贴近我们实际遇到的事物),因此尽管释义多种多样,干的部分是相同的。也许扯远了,我并不确定Java线程的设计者和python的迭代器的设计者在当初选择yield这个词的时候是不是背后有相同的/相通的(其含义机械且确定,没有二义性的)计算机概念,我更倾向于相信是因为英语中这个动词准确的把表达出了线程和迭代器各自上下文里的各自的、具象的含义。即:从英语来说这两种释义它们是同源的,从计算机具体的、特定的概念来说,它们未必是。

J:第一次看到这个词是在Python,我觉得它的意思是喊一声。生产完对象喊一声,不用CPU了喊一声

W:也可能是我想多了,或许这两个语境意思并不统一,这也是我们母语非英语的程序员的一大问题,在捕获信息时需要付出更多的代价才能确定其准确性。

L:ruby里面有两个地方有yield,一个是method去call传入的block,一个是fiber出让调度,本质上都是切上下文,所以我觉得你没想多

Z:这个…你想多了吧,yield 在现代英语里本来就有这两意思。我还去查了 etymology dictionary. ld English gield “payment, sum of money; service, offering, worship;” from the source of yield (v.). Extended sense of “production” (as of crops) is first attested mid-15c. Earliest English sense survives in financial “yield from investments.”

西撒克逊古英语的gieldan和盎格鲁语geldan 都来自古日耳曼语的geldan, 有pay, to repay, return的意识。到14世纪早期,在投资中得道回报,也有survives in financial的意思,发展成了survives, give oneself up, surrender 的意思。 15世纪中叶gieldan另一分支,耕作谷物得道回报,发展成了production的意思。

Q:在国外开车除了停车线stop有时会遇到让车线yield。就是如果有直行车辆正在通过,停在那里等,否则进入车道。我想在for comprehension 里应该是差不多的意思,执行for里面的sequential functions,当所有functions 都被执行,弹出结果。

G:这是个好问题,专门去复习了一下python的generator语法:yield本质上就是“让出”但不“退出”,由于整个计算还没有结束(就好比generator说:我还不能死,还得保留当前状态),故不能return。

W:javascript 里 yield 明确的含义就是“让出”,python 也是。所以 c#/ scala 这种后出的语言,基本都是“拿来主义”,尽管未必是那个含义,也是把其他语言里已经被大众所熟知的语法直接拿来。

W:scala 里的 for-yield 是个语法糖,跟 js/python 里的generator 完全无关,要实现类似generator效果需要用 lazy/Stream 等惰性计算的特性。

W:我认为 C# 里的 yield 也是 “让出” 的意思,你可以跟 C# 开发者确认一下。

W:我知道这个词有多个意思,只是在程序语言里,是不是都代表一个意思,还是代表的是不同的意思,这才是我疑惑的。

R:C#里也是延迟执行的,迭代到了才执行生成对应的item的代码。这也是让我觉得像produce的原因

yield的字面意思》上有2条评论

  1. hongjiang 文章作者

    http://geek.csdn.net/news/detail/49827/
    徐宥的《计算机语言协程的历史、现在和未来》一文里:

    …正因为如此,我们可以从协程的角度来理解迭代器:当控制流转换到迭代器时,迭代器负责生成和返回下一个元素。一旦准备就绪,迭代器就让出控制流。在Python中,这种特殊的迭代器实现又被成为生成器。以协程角度切入的好处在于设计大大精简。实际上,在Python中,生成器本身就是一个普通函数,和其他普通函数的唯一不同,在于它的返回语句是协程风格的yield。这里,yield一语双关,既是让出控制流,也是生成迭代器的返回值。

    回复

发表评论

电子邮件地址不会被公开。 必填项已用*标注