First class value 可以:

    • 存储在 global variable,local variable,和 table field 中(可以存储在变量里面);
    • 作为 function parameter 传递(可以作为函数参数);
    • 作为 function return value(可以作为函数返回值);

    举一个反例有助理解,Lua 中的 list 就不是 first class value,见《 Programming in Lua 》第 5.1 节:

    These lists appear in four constructions in Lua: multiple assignments, arguments to function calls, table constructors, and return statements.

    原因是 list 其实代表 runtime stack (运行时堆栈)上的一小段。所以无法存储到 variable 中。
    第一类值,是可以作为对象传递的,可以作为函数返回的值域,table的子项,域这个称谓应该是和lua无关的吧。
    有些语言确实是不区分的,它的function(表示code)跟int、 double的地位是一样的。这种语言就为函数是第一类值。
    但问题是,有些语言是不能存储函数,不能动态创建函数,不能动态销毁函数(像 Lua 就可以通过赋值 nil 来销毁一个函数)。(这里函数是已经是广义的了,用来表示代码code)。只能存储一个指向函数的指针,这种语言称为函数是第二类值(比如 C语言)。

    另外有些语言不单可以传递函数,函数里面又用到一些外部信息(包括code, data)。那些语言可以将函数跟函数所用到的信息一起传递存储。这种将函数和它所用的信息作为一个整体,就为闭包(比如 PHP )。

    比如排序,A让B排序,B会做排序,但排序需要知道哪个比哪个大,这点B自己不知道,就需要A告诉它。而这种判断那个大,本身是一种动作,既然C语言中不可以传进第一值的函数,就设计成传递第二值的函数指针,这个函数指针就是A传向B的信息,用来表示一个行为。这里本来A调用B的,结果B又调用了A告诉它的信息,也就叫callback。

    跟着再将回调的概念进化,比如某人同时关心A、B、C、D、E、F事件,并且这些事件是一组的,比如敲键盘,鼠标移动,鼠标点击等一组。将一组事件结合起来。在有些语言就变成一个接口,接口有N个函数。有些语言就映射成一个结构,里面放着N个函数指针。跟着就不是将单个函数指针传进去,而是将接口,或者函数指针的结构传进去。这些根据不同的用途,有些人叫它为代理啊,监听者啊,观察者啊等等。