WuF*_*uFa 22 programming-languages terminology
一流的价值可以
第二类值可以作为参数传递.
三等价值甚至不能作为论据传递.
为什么这些东西应该这样定义?据我所知,"可以作为参数传递"意味着它可以被推入运行时堆栈;"可以被分配到变量"意味着它可以被移动到内存的不同位置; "可以从子程序返回"几乎具有"可以分配给变量"的相同含义,因为返回的值总是被放入已知地址,因此第一类值完全是"可移动"或"动态",第二类value是一半"可移动",第三类值只是"静态",例如C/C++中的标签,只能通过goto语句来解决,除了"goto"之外你不能对该地址做任何事情..我的理解有意义吗?或者这三种价值究竟意味着什么?
Nor*_*sey 42
哦不,我可能要再次编辑维基百科.
实际上只有两个区别值得做:一流而不是一流.如果迈克尔斯科特谈到第三类任何东西,我会非常沮丧.
好吧,那么什么是"一流"呢?嗯,这个术语几乎没有技术含义.当存在时,其含义通常是比较性的,它适用于语言中的事物(我在这里故意模糊),它具有比同类事物更多的特权.这就是所有人的意思.
我们来看一些例子:
C中的函数指针是第一类值,因为它们可以传递给函数,从函数返回,并像任何其他值一样存储在堆分配的数据结构中.Pascal和Ada中的函数不是第一类值,因为虽然它们可以作为参数传递,但它们不能作为结果返回或存储在堆分配的数据结构中.
结构类型是C中的第二类类型,因为没有结构类型的文字表达式.(因为C99有一些带有命名字段的文字初始值设定项,但是这仍然不像在任何可以使用表达式的文字中那样通用.)
多态值是ML中的第二类值,因为尽管它们可以与名称绑定,但它们不能是lambda绑定的.因此它们不能作为参数传递.但是在Haskell中,因为Haskell支持更高级别的多态性,所以多态值是一流的.(它们甚至可以存储在数据结构中!)
在Java中,类型int是第二类,因为您无法从中继承.类型Integer是头等舱.
在C中,标签是第二类,因为它们没有值,您无法使用它们进行计算.在FORTRAN中,行号具有值,因此是第一类.C的GNU扩展允许您定义一流的标签,它非常有用.在这种情况下,头等舱意味着什么?这意味着标签具有值,可以存储在数据结构中,并且可以用于goto.但是这些值在另一种意义上是第二类,因为来自一个过程的标签不能有意义地用于goto属于另一个过程的标签.
我们是否知道这个术语是多么无用?
我希望这些例子让你相信,"一流"的想法在整体思考编程语言时并不是一个非常有用的想法.当你谈论特定语言或语言家族的特定功能时,它可能是一个有用的简写("语言不起作用,除非它具有一流的嵌套函数")但总的来说你更好说出你的意思,而不是谈论"一流"或"不一流"的事情.
至于"三等",只说拒绝.
如果某些东西可以在代码中显式操作,那么它就是一流的。换句话说,如果某个东西可以在运行时以编程方式进行操作,那么它就是一流的。
这与元编程密切相关,因为您在代码中描述的内容(在开发时)是一个元级别,而在运行时存在的内容是另一个元级别。但这两个元级别之间的界限可能会变得模糊,例如通过反射。当某些东西在运行时具体化时,它就变得可以明确地操纵。
我们谈论第一类对象,因为可以在运行时以编程方式操作对象(这就是目的)。
在java中,你有类,但它们不是一流的,因为除非使用反射,否则代码通常无法操作类。但在 Smalltalk 中,类是一流的:代码可以像操作常规对象一样操作类。
在java中,你有包(模块),但它们不是一流的,因为代码在运行时不会操作包。但在 NewSpeak 中,包(模块)是一流的,您可以实例化一个模块并将其传递给另一个模块以在运行时指定模块性。
在 C# 中,闭包是一流的函数。它们存在并且可以在运行时以编程方式进行操作。java 中还不存在这样的东西。
对我来说,一流/非一流的界限并不严格。有时某些语言结构很难发音,例如 java 原始类型。我们可以说它不是一流的,因为它不是一个对象,并且不能通过可以传递的引用进行操作,但原始值仍然存在并且可以在运行时进行操作。
PS:我同意诺曼拉姆齐的观点,二等和三等价值对我来说没有意义。