In programming language design, a first-class citizen (also object, entity, or value) in a given programming language is an entity which supports all the operations generally available to other entities. These operations typically include being passed as a parameter, returned from a function, and assigned to a variable.
第一類對象(First-class Object)在1960年由Christopher Strachey發明,原來稱之爲第一類公民(First-class citizen),意思是指函數能夠做爲電腦中的第一類公民。英文中也稱之爲First-class entity或First-class value。 編程
第一類對象不必定是指面向對象程序設計中所指的對象,而是指程序中的全部實體(好比:變量、函數、隊列、字典等等)。通常第一類對象具備一下特徵: 數組
「固有身份」是指實體有內部表示,而不是根據名字來識別,好比匿名函數,還能夠經過賦值叫任何名字。大部分語言的基本類型的數值(int, float)等都是第一類對象;可是數組不必定,好比C中的數組,做爲函數參數時,傳遞的是第一個元素的地址,同時還丟失了數組長度信息。對於大多數的動態語言,函數/方法都是第一類對象,好比Python,可是Ruby不是,由於不能返回一個方法。第一類函數對函數式編程語言來講是必須的。 編程語言
在大多數語言中,數值和基礎類型都是第一類對象,然而不一樣語言中對函數的區別很大,例如C語言與C++中的函數不是第一類對象,由於在這些語言中函數不能在執行期創造,而必須在設計時所有寫好。相比之下,Scheme中的函數是第一類對象,由於能夠用lambda語句來創造匿名函數並做爲第一類對象來操做。 函數式編程
在諸如Python、Scala等函數式編程語言中,最主要的基礎是λ演算(lambda caculus),而λ演算的函數能夠接受函數看成輸入輸出。所以,這類編程語言每每實現了第一類函數(First-class Function),以Scala爲例。 函數
Scala,顧名思義「可伸縮的」,爲了使λ演算變得簡潔,Scala實現了第一類值(First-class Value),即全部函數都是first-class values ,這意味着Scala中的全部函數都是值,所以,函數能夠做爲值同樣進行參數傳遞或者從函數中返回。
做爲返回,結果爲2
val inc = (x : Int) => x + 1
inc(1)
做爲傳遞,結果爲List(2,3,4)
List(1, 2, 3).map((x: Int) => x + 1) spa
從以上結果能夠看出,函數是在執行期被建立的;函數能夠是匿名的;有返回值;可以被存儲;函數做爲實體知足了第一對象概念的定義。 設計
歷史背景 對象
第一類對象和第二類對象的概念,在1960年由Christopher Strachey引入。實際上他沒有提出嚴格的術語定義,而是給出了Algol語言中實數和過程的對比: 隊列
第一類對象和第二類對象。在Algol程序語言中,一個「實數」可能會出如今一個表達式中或被賦給一個變量,並可能在過程調用中做爲實際參數出現。而「過程」只可能會出如今另外一個過程調用中,最多見的是做爲操做符,有時候也做爲實參。除此以外,沒有表達式會涉及到過程,或者將過程做爲計算結果。所以在某種意義上,在Algol程序語言中的過程是第二類變量,它們老是會單獨出現,不可能被一個表達式或一個變量表示(形式參數除外)…一些編程語言中容許函數在執行時建立,並將其稱爲」第一類「(First-class),而函數在C語言中不是第一類對象;相對應的稱之爲第二類對象(second-class objects),由於從函數角度看這類對象是獨立的而且能在各類形式操做。像SmallTalk這種全面向對象語言,函數和方法都是第一類對象,由於操做符(+、-、etc)也是對象,所以操做符也是第一類對象。