头等函数(first-class function)是指在程序设计语言中,函数被当作头等公民。这意味着,函数可以作为别的函数的参数、函数的返回值,赋值给变量或存储在数据结构中。 有人主张应包括支持匿名函数(函数字面量,function literals)。在这样的语言中,函数的名字没有特殊含义,它们被当作具有函数类型的普通的变量对待。1960年代中期,克里斯托弗·斯特雷奇在“functions as first-class citizens”中提出这一概念。
简介头等函数是函数式程序设计所必须的。通常要使用高阶函数。map函数就是一个高阶函数,其实参是一个函数及一个list,返回结果是把作为参数的函数作用于list的每个元素后的结果形成的list。
把函数作为函数参数与函数返回值会遇到特别的困难。特别是存在非局部变量与嵌套函数、匿名函数。历史上,这被称作函数参数问题。早期的命令式编程语言,或者不支持函数作为结果类型(如ALGOL 60,Pascal),或者忽略嵌套函数与非局部变量(如C语言)。早期的函数式语言Lisp采取了动态作用域方法,把非局部变量绑定到函数执行点最近的变量定义。Scheme语言支持词法作用域的头等函数,把对函数的引用绑定到闭包(closure)而不是函数指针,这使得垃圾收集成为必须。
概念在这一节,比较把函数视作头等公民的典型的函数式语言Haskell与把函数视作二等公民的命令式编程的C语言的有关概念1。
高阶函数:函数作为实参传递更多信息:高阶函数
具有函数参数的函数,称为高阶函数。函数式语言如Haskell:
map :: (a -> b) -> [a] -> [b]map f [] = []map f (x:xs) = f x : map f xs函数不是头等公民的程序设计语言可以使用函数指针或delegate,实现函数作为参数。C语言例子:
void map(int (*f)(int), int x[], size_t n) { for (int i = 0; i [Integer]]f = let a = 3 b = 1 in [map (\x -> a * x + b), map (\x -> b * x + a)]类型论主条目:函数类型
对于类型论,函数类型接受值类型A并返回值类型B可写为A→B或B。根据柯里-霍华德对应,函数类型可对应于逻辑蕴涵,lambda抽象对应于,函数调用对应于肯定前件推理规则。类型论还使用头等函数建模关联数组与类似的数据结构。
对于范畴论,头等函数对应于closed category设置。例如,简单类型λ演算对应于笛卡儿闭范畴(CCC)的内部语言。
本词条内容贡献者为:
王慧维 - 副研究员 - 西南大学