Programming languages 关于一级、二级和三级价值
头等舱值可以是Programming languages 关于一级、二级和三级价值,programming-languages,terminology,Programming Languages,Terminology,头等舱值可以是 作为论据通过 从子例程返回 分配给一个变量 第二类值只能作为参数传递 第三类值甚至不能作为参数传递 为什么要这样定义这些东西?据我所知,“可以作为参数传递”意味着它可以被推送到运行时堆栈中;“可以分配到一个变量”意味着它可以移动到内存的不同位置;“可从子例程返回”几乎与“可分配到变量”的含义相同,因为返回值总是放在已知地址中,所以第一类值完全是“可移动”或“动态的”,第二类值是“可移动”的一半,第三类值只是“静态的”,例如C/C++中的标签,它只能通过goto语句进行寻址,除了“
为什么要这样定义这些东西?据我所知,“可以作为参数传递”意味着它可以被推送到运行时堆栈中;“可以分配到一个变量”意味着它可以移动到内存的不同位置;“可从子例程返回”几乎与“可分配到变量”的含义相同,因为返回值总是放在已知地址中,所以第一类值完全是“可移动”或“动态的”,第二类值是“可移动”的一半,第三类值只是“静态的”,例如C/C++中的标签,它只能通过goto语句进行寻址,除了“goto”之外,您不能对该地址执行任何操作。我的理解有意义吗?或者这三种价值观到底意味着什么?哦,不,我可能不得不再次编辑维基百科 实际上只有两个区别值得区分:一流的和非一流的。如果迈克尔·斯科特谈论三等舱的事情,我会非常沮丧 好吧,那么什么是“头等舱”呢?嗯,这是一个几乎没有技术意义的术语。这个意思,当出现时,通常是比较性的,它适用于一种语言中的东西(我在这里故意含糊其辞),它比一个可比较的东西有更多的特权。这就是所有人的意思 让我们看一些例子:
- C中的函数指针是一级值,因为它们可以传递给函数,从函数返回,并像任何其他值一样存储在堆分配的数据结构中。Pascal和Ada中的函数不是一级值,因为尽管它们可以作为参数传递,但不能作为结果返回或存储在堆分配的数据结构中
- 结构类型在C中是二级类型,因为没有结构类型的文本表达式。(由于C99有带命名字段的文字初始值设定项,但这仍然不如在任何可以使用表达式的地方都有文字一般。)
- 多态值在ML中是二级值,因为尽管可以让它们绑定到名称,但不能被lambda绑定。因此,它们不能作为参数传递。但在Haskell中,因为Haskell支持更高级别的多态性,所以多态值是一流的。(它们甚至可以存储在数据结构中!)
- 在Java中,
类型是第二类,因为不能从中继承。类型int
是第一类Integer
- 在C语言中,标签是第二类的,因为它们没有值,您无法使用它们进行计算。在FORTRAN中,行号有值,第一类也有值。C有一个GNU扩展,允许您定义一流的标签,它非常有用。在这种情况下,头等舱意味着什么?这意味着标签具有值,可以存储在数据结构中,并且可以在
中使用。但这些值在另一种意义上是第二类的,因为一个过程的标签不能有意义地用于属于另一个过程的goto
goto
至于“第三类”,只要说不就行了。如果某些东西在代码中可以显式操作,那么它就是第一类的。换句话说,如果可以在运行时以编程方式对某个对象进行操作,那么它就是一流的 这与元编程密切相关,因为您在代码中描述的(开发时)是一个元级别,而在运行时存在的是另一个元级别。但这两个元层次之间的屏障可能会模糊,例如反射。当某个东西在运行时被具体化时,它就变得明确可操作
- 我们谈论第一类对象,因为对象可以在运行时以编程方式操作(这正是目的)
- 在java中,您有类,但它们不是一流的,因为除非使用反射,否则代码通常无法操作类。但在Smalltalk中,类是一流的:代码可以像处理常规对象一样操作类
- 在java中,您有包(模块),但它们不是一流的,因为代码不会在运行时操纵包。但在NewSpeak中,包(模块)是一流的,您可以实例化一个模块并将其传递给另一个模块,以在运行时指定模块性
- 在C#中,闭包是一级函数。它们存在并且可以在运行时以编程方式进行操作。这样的东西在java中还不存在