I have seen many times statements like- "Please make this feature a first class citizen in so and so language/platform". For example, it is said about enums in C#/.net. So, when is a feature considered a "First class citizen" in a programming language/platform?
When is a feature considered a "First class citizen" in a programming language/platform?
BTW: the term "first class citizen" is derecommended e.g. by the google styleguide for inclusive language as a socially charged term: developers.google.com/style/inclusive-documentation– tkruseFeb 24, 2020 at 9:21
@tkruse What is "derecommended"?– GhermanJun 8, 2021 at 12:26
An object is first-class when it:
- can be stored in variables and data structures
- can be passed as a parameter to a subroutine
- can be returned as the result of a subroutine
- can be constructed at runtime
- has intrinsic identity (independent of any given name)
The term "object" is used loosely here, not necessarily referring to objects in object-oriented programming. The simplest scalar data types, such as integer and floating-point numbers, are nearly always first-class.
1So, what makes enums second class object in .net/C#?– GulshanJan 25, 2011 at 8:17
7@Gulshan - you could argue the lack of intrinsic identity - C# enums are basically just syntactic sugar (i.e. a "given name") for an integer value. Compare with Java, where the enums are objects in their own right.– mikeraJan 25, 2011 at 8:24
@mikera, in .NET enums are values in their own right. Java just does not have any values, only objects, that's the only difference.– SK-logicJan 25, 2011 at 11:08
@mikera: Though that prevents Java's enums from having some nice properties such as being able to represent bit fields with them. While their implementation is probably more first-class-y most of their APIs still has plenty of integer (or string) constants and many uses of those cannot easily be replaced with enums.– JoeyJan 25, 2011 at 13:37
I don't think enums can be constructed at runtime in .Net, can they? I thought they were always constants.– travisJan 25, 2011 at 15:54
The notion of "first-class citizen" or "first-class element" in a programming language was introduced by British computer scientist Christopher Strachey in the 1960s in the context of first-class functions. The most famous formulation of this principle is probably in Structure and Interpretation of Computer Programs by Gerald Jay Sussman and Harry Abelson:
- They may be named by variables.
- They may be passed as arguments to procedures.
- They may be returned as the results of procedures.
- They may be included in data structures.
Basically, it means that you can do with this programming language element everything that you can do with all other elements in the programming language.
It's all about "equal rights": you can do all of the above, with, say, integers, so why should any other thing be different?
The definition above is a bit restrictive in the sense that it only really talks about the aspect of first-classness as related to being objects of the program. A more general definition would be that a thing is first-class if you can do everything with it you can also do with other things of similar kind.
For example, Java operators and Java methods are of similar kind. You can define new methods, you can (somewhat) freely choose the names of your own methods, you can override methods, you can overload methods. James Gosling can do all of that with operators, too, but you and I can't. I mean, contrary to popular belief, Java does support operator overloading: for example, the
+ operator is overloaded for
String, and IIRC in Java 7 also for
BigDecimal (and probably a couple I forgot), it's just that you don't have any influence over it. That clearly makes operators second-class according to this second definition. Note that methods still aren't first-class objects according to the first definition, though. (Does that make operators third-class?)
Great answer. So, for example, the pipenv docs say "Windows is a first-class citizen, in our world." Would this imply you can do everything with
pipenvon Windows that you can also do with it on Linux?– djvgJan 8, 2021 at 11:58
2No, I don't think that usage of the term "first-class citizen" has anything with to do with the formal Programming Language Theory definition of the term. I think pipenv are just using the term with its normal standard English meaning. Jan 8, 2021 at 12:02
As in "treated fairly?" Thanks for your help.– djvgJan 8, 2021 at 14:26
Usually this refers to a construct that is passable as a parameter, can be defined as a return type from a function or can be assigned a value. Normally you need to be able to construct them at runtime. For example an instance of a class would be a first class citizen in c++ or java, but a function in C would not be.
What makes a class a first class citizen in c++ ? Jan 25, 2011 at 7:33
2@bjarkef: Sounds like that was already answered by its matching the description offered in the preceding sentences. Jan 25, 2011 at 7:47
@Jonathan: Yes, sorry, I misread the "construct them at runtime". Yes you can construct an instance of a class at runtime (an object), but not the class itself. That is what confused me. Jan 25, 2011 at 7:53
1Passing by parameter is still not enough. In C/C++ I would still consider functions as second class citizens. They can be passed as parameters, returned as results placed inside other objects. But they can not be manipulated without the help of other constructs (like std::bind is required to bind parameters to a function). Jan 25, 2011 at 8:13
@Martin I never said that functions were first class citizens in C/C++.– PemdasJan 25, 2011 at 15:21
I would say a feature is a first class citizen if it is implemented solely by the language.
i.e. it does not require multiple language features or a standard library to implement that feature.
In C/C++ I do not consider functions to be a first class citizen (others may).
This is because there are ways to manipulate functions that are nut supported directly by the language but require the use of other language features. Binding parameters to a function is not directly supported and you must build a functor to implement this feature.
1Wouldn't that make bound functions (or "closures") not be first-class, while functions themselves are? How does 0x's support for closures factor in to your analysis? Jan 25, 2011 at 10:19
@Fred Nurk: It all depends on the language. In some languages closures are first class systems. In others not. I am not familiar enough with C++0x yet to make an explicit comment. Jan 25, 2011 at 16:18
Let's say the language is either C or C++ (but not 0x), as in you answer. Wouldn't your definition of "first-class" make bound functions (or "closures") not be first-class, while functions themselves are? Jan 26, 2011 at 1:03
@Fred Nurk: If you limit the only thing you can do with a function is make them a closure, then sure. But to me that's like saying if you platform supports integers addition only by importing a library. Then integers are first class citizens but addition of integers is not considered. In my view closure is an operation that can be performed on a function that effectively returns a new function (but it depends how you define it). But closure and binding are only two operations how many others are we excluding from the discussion (I am not sure that was a question). Jan 26, 2011 at 1:16
@Martin: I must not be explaining myself clearly. Given "a feature is a first class citizen if it is implemented solely by the language", then functions in both C and C++ are implemented solely by the language and would thus be first-class. Bound functions (which can also be called "closures") are what you're talking about with binding parameters, etc., but that's a different feature. Jan 26, 2011 at 1:19
To add an example to the answers already provided:
In WCF/C# you currently have to mark a class object with a service contract attribute to have it operate as a service. There is no such thing as:
public **service** MyService (in relation public **class** MyClass).
A class is a first class citizen in c#, where a service is not.
Hope this helps
‘First-class’ is a meaningless buzzword when it comes to programming language features. Consider:
- ‘First-class functions’ means functions are values like any other and can be passed as arguments, returned, stored in variables, etc.
- ‘First-class’ anything else usually means the feature has dedicated syntax almost, but not quite entirely unlike anything else in the language and has to be considered separately when reasoning about the code.
This term has no consistent meaning other than ‘someone spent a lot of time thinking about this’. Just avoid it entirely. Your thinking will be much clearer for it.