Origin of the term "first-class object"

H

Hung Jung Lu

Hi,

Does anybody know where this term comes from?

"First-class object" means "something passable as an argument in a
function call", but I fail to see the connection with "object class"
or with "first-class airplane ticket". I just find the name a bit
strange. Also, if there are first-class objects, what would the
second-class objects or economy/tourist class objects be? :)

Just wondering,

Hung Jung
 
B

Ben Finney

"First-class object" means "something passable as an argument in a
function call", but I fail to see the connection with "object class"
or with "first-class airplane ticket".

The term is analogous to "first-class citizen". It implies that no
other kind of object has privilege to do more than this object, i.e. it
has the most elevated object status -- first-class.
Also, if there are first-class objects, what would the second-class
objects or economy/tourist class objects be? :)

Objects with fewer capabilities. E.g. in many OO-capable languages,
built-in types are not first-class objects; you (variously) can't
inherit from them, pass them as arguments, access their methods, etc.

Using this term implies, by social analogy, that the existence of
objects which are lower than first-class is undesirable and should be
rectified by elevating the status of all objects toward the ideal state:
where all are first-class.

This is why Pythonistas are proud that everything in Python is a
first-class object.
 
J

John Roth

Hung Jung Lu said:
Hi,

Does anybody know where this term comes from?

"First-class object" means "something passable as an argument in a
function call", but I fail to see the connection with "object class"
or with "first-class airplane ticket". I just find the name a bit
strange. Also, if there are first-class objects, what would the
second-class objects or economy/tourist class objects be? :)

Just wondering,

I'm not sure who started to use it, but to me it means that
there are no restrictions on the object's use. It's the same as
any other object. I'm also not sure what being able to pass
it in a function call has to do with it; I'm used to being
able to use them in a lot of other ways.

For example, in Python both classes and functions are
objects (there are no second class citizens in Python...)
This means that I can rebind a class object into another
module at run time, and access it under its new name.
I can thow functions around with wild abandon, and even
add attributes to them for some meta-data scheme, for
example.

In Java, neither classes nor methods are first class
objects, even though you can get a "class" object
if you ask politely, it's simply a special construct
for the reflection mechanism.

In C++, neither is an object, first class or not.

John Roth
 
E

Erik Max Francis

Hung said:
Does anybody know where this term comes from?

"First-class object" means "something passable as an argument in a
function call", but I fail to see the connection with "object class"
or with "first-class airplane ticket".

It doesn't have any connection with the former (since the term long
predates object orientation, so far as I know). It does have a
connection to the latter, in that something going first class has all
the privileges and properties owed to it as a complete and total thing.
So a "first-class object" is a complete entity unto itself, and can be
passed to functions and returned from them, as you suggest.

Think of "first-class object" as "important thing" and maybe it'll make
slightly more sense.

--
Erik Max Francis && (e-mail address removed) && http://www.alcyone.com/max/
__ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
/ \
\__/ The only way to get rid of a temptation is to yield to it.
-- Oscar Wilde
 
M

Mike C. Fletcher

Hung said:
Hi,

Does anybody know where this term comes from?

"First-class object" means "something passable as an argument in a
function call", but I fail to see the connection with "object class"
or with "first-class airplane ticket". I just find the name a bit
strange. Also, if there are first-class objects, what would the
second-class objects or economy/tourist class objects be? :)
"Second class citizens" are those denied the rights afforded to "first
class citizens". In this context, first class objects are those which
can participate in the (object) environment in the same manner as any
other "normal" object. In many languages, classes are not able to be
processed in the same manner as regular objects (e.g. being passed into
functions, introspected for their type, holding properties).

HTH,
Mike

_______________________________________
Mike C. Fletcher
Designer, VR Plumber, Coder
http://members.rogers.com/mcfletch/
 
R

Rainer Deyke

John said:
For example, in Python both classes and functions are
objects (there are no second class citizens in Python...)

I would consider variables to be second-class citizens. You can change
their value, delete them, and get at the object to which they refer, but you
can't do much else with them.
In Java, neither classes nor methods are first class
objects, even though you can get a "class" object
if you ask politely, it's simply a special construct
for the reflection mechanism.

In C++, neither is an object, first class or not.

While you can't create new functions and unbound methods in C++ at runtime,
you can take their address and pass that around as a first class object.
Bound methods are another matter.
 
E

Erik Max Francis

Rainer said:
While you can't create new functions and unbound methods in C++ at
runtime,
you can take their address and pass that around as a first class
object.

True, though that usually devolves into a semantic issue about whether
functions are first-class if you can only manipulate pointers to them.
I usually say C has first-class functions if you squint. C++ doesn't
have first-class bound member function pointers, as you point out, and
another obvious example in C++ is the lack of first-class classes -- a
feature in Python that is extremely powerful, since it almost makes the
"factory" pattern automatic in Python (the class object itself is just a
callable type that creates instances).

--
Erik Max Francis && (e-mail address removed) && http://www.alcyone.com/max/
__ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
/ \
\__/ And there inside our private war / I died the night before
-- Sade
 
B

Ben Finney

I would consider variables to be second-class citizens. You can
change their value, delete them, and get at the object to which they
refer, but you can't do much else with them.

AIUI, there are no "variables" in Python; or rather, the normal usage of
that term is not precise enough in Python, since the task is split.
There are names bound to objects.

Objects are all first-class.

Names are essentually a language device used to refer to an object. You
don't "change their value"; you change the object to which they are
bound.

Names aren't objects, and I don't see what you'd gain if you started
treating a name as an object; you'd merely need some additional way of
referring to *those* objects somehow. (Meta-names, anyone?)

Since names aren't objects, the question of whether they're first-class
objects doesn't arise.
 
J

John Roth

Rainer Deyke said:
I would consider variables to be second-class citizens. You can change
their value, delete them, and get at the object to which they refer, but you
can't do much else with them.

I think I'd disagree with that. In fact, except for the optimization
within function bodies, I can't think of anything I can't do
with a name that I might want to.

John Roth
 
R

Rainer Deyke

John said:
I think I'd disagree with that. In fact, except for the optimization
within function bodies, I can't think of anything I can't do
with a name that I might want to.


I can think of several things. One would be passing a name as an argument
to a function. Given the immutability of certain Python objects, it is
often necessary to write statements in the form of
"x = f(x)". This is a violation of the Once And Only Once principles, since
it mentions the same variable twice.

I'm not saying that the way Python deals with objects and variables is
wrong. Language design is a series of trade-offs, and the simplicity and
clarity of Python may very well make up for its limitations. However, that
doesn't mean that the limitations are not real.
 
T

Terry Reedy

Rainer Deyke said:
I would consider variables to be second-class citizens.

In a sense, 'they' are not even citizens.

In Python, names are syntactic entities, not runtime objects (although
they sometimes get embodied in or represented as strings). They are
part of the code directing computation but are not the subject of
computation themselves (although strings representing them can be).
(But the CPython interpreter usually represents local function names
as C integers instead.) In themselves, names have neither id, type,
nor value, just a current binding to an object that does.

"Variable' is an informal term with multiple meanings even in
mathematics. In named-memory-block languages like C, a 'variable' is
a name associated with a fixed-address, mutable-content (value) block,
which before 'const', was (to my memory) every number (including
chars), array, and structure/union.

Python, being about objects rather than memory, has no direct
equivalent. Nor is there a formal definition of 'variable' for
Python. Python names are used much like C variables, but I think
people sometimes use 'variable' in a way that more refers to objects
than to names. For instance, in Python 'the value of i' is 'the value
of the ojbect currently associated with i' whereas in C it is 'the
value currently in memory block i'.
You can change their value,

You can change the value of objects, but only the binding of names.
delete them,

You can delete objects but only the binding of names. 'Del a' means
unbind 'a' from its currently associated object and if that was the
last remaining binding of that object, make the *object* eligible for
de-existence.

Thus far, you are using 'variable' more to describe objects than
names.
and get at the object to which they refer,

But here you clearly mean 'variable' = 'name' unless you also mean
'variable' = collection slot or object attribute ('dotted name').
but you can't do much else with them.

It is hard to do much with an ill-defined abstraction ;-).

Terry J. Reedy
 
B

Ben Finney

One would be passing a name as an argument
to a function.

To accomplish what? What would you be doing with the name that you
can't do just as easily by passing the object (by reference, as always
happens in Python)?
Given the immutability of certain Python objects, it is
often necessary to write statements in the form of
"x = f(x)".

I don't understand the logic here. What is it that necessitates
"x = f(x)", and why is that undesirable?
This is a violation of the Once And Only Once principles, since it
mentions the same variable twice.

I've never heard of that principle. Surely one of the main advantages
of naming an object is to use that name in multiple places to refer to
the object?

I can't think how you'd write any non-trivial program to work with
objects that *doesn't* "mention the same [object] twice", nor what you'd
gain by doing so.

Perhaps you're referring to a principle sometimes called the Single
Point Of Truth (SPOT), which requires that, ideally, there be one and
only one canonical place where each datum resides. This is quite
separate to the names given to objects within the program -- having a
SPOT for each datum is *enabled* by using the same name multiple times
within the program.
Language design is a series of trade-offs, and the simplicity and
clarity of Python may very well make up for its limitations. However,
that doesn't mean that the limitations are not real.

I'll have to ask you to explain those limitations, I can't understand
them as you've expressed them here.
 
R

Rainer Deyke

Ben said:
To accomplish what? What would you be doing with the name that you
can't do just as easily by passing the object (by reference, as always
happens in Python)?

Binding the name to a different object.
I don't understand the logic here. What is it that necessitates
"x = f(x)",

For example, any "mutating" operation on x, where x is an immutable object.

Trivial and useless example:

def increment(x):
return x + 1

i = increment(i)
and why is that undesirable?

Suppose the 'x' in 'x = f(x)' is not a simple variable, but an element in a
list

l[x * 2 + f(y)] = f(l[x * 2 + f(y)])

This statement contains an obvious redundancy that will make code
maintenance difficult. Python allows me to factor out some of the
redundancy:

index = x * 2 + f(y)
l[index] = f(l[index])

However, Python gives me no way to factor out the remaining redundancy.
 
J

John J. Lee

Erik Max Francis said:
It doesn't have any connection with the former (since the term long
predates object orientation, so far as I know). It does have a
connection to the latter, in that something going first class has all
the privileges and properties owed to it as a complete and total thing.
[...]

Ben is closer to the mark in terms of etymology, I think -- though
maybe "first-class citizen" in turn derives from "first-class ticket"?


John
 
J

John Roth

Ben Finney said:
I've never heard of that principle.

Different authors give it different names. Dave Thomas and
Mike Hunt (the Pragmatic Programmers) call it "DRY":
"Don't repeat yourself." Once and only once comes, I believe,
from XP. There are other names.

The essential concept is that there should only be one
location for something in a system. Complaining about
x = f(x) is, IMO, being excessively anal about it.

John Roth
 
A

Aahz

Suppose the 'x' in 'x = f(x)' is not a simple variable, but an element in a
list

l[x * 2 + f(y)] = f(l[x * 2 + f(y)])

This statement contains an obvious redundancy that will make code
maintenance difficult. Python allows me to factor out some of the
redundancy:

index = x * 2 + f(y)
l[index] = f(l[index])

However, Python gives me no way to factor out the remaining redundancy.

Sure it does: change the immutable to a mutable.
 
P

Peter Hansen

Mel said:
And a good thing, as you and I think. Names are
first-class in natural human languages, and look what
happens:

"...The name of the song is called 'Haddocks'
Eyes'."

"Oh, that's the name of the song, is it?" Alice
said, trying to feel interested.

"No, you don't understand," the Knight said,
looking a little vexed. "That's what the name is
_called_. The name really is 'The Aged Aged Man'."

"Then I ought to have said 'That's what the song is
called'?" Alice corrected herself.

"No, you oughtn't! That's quite another thing!
The song is called 'Ways and Means': but that's only
what it's called, you know."

"Well, what is the song then?" said Alice, who was
by this time completely bewildered.

"I was coming to that," the Knight said. "The song
really is 'A-sitting on a Gate', and the tune's my
own invention."

_Through the Looking Glass_, of course
Lewis Carroll

Wow! That shows just how precise one can sometimes need to be,
especially with things like "names" in Python (which we sometimes
call variables, but which actually are just *bindings* ;-).

-Peter
 
R

Rainer Deyke

Aahz said:
l[x * 2 + f(y)] = f(l[x * 2 + f(y)])

This statement contains an obvious redundancy that will make code
maintenance difficult. Python allows me to factor out some of the
redundancy:

index = x * 2 + f(y)
l[index] = f(l[index])

However, Python gives me no way to factor out the remaining
redundancy.

Sure it does: change the immutable to a mutable.

Not good enough. I'd rather write "l[x] = f(l[x])" with all of its
redundancy than wrap every conceivable immutable object in a mutable
wrapper. Besides, I don't *want* 'f' to change an object (which may also be
referenced elsewhere); I want it to change a binding.

And, really, "l[x] = f(l[x])" isn't that big of a deal. It's a bit of
redundancy that I'd rather not have, but it's not bad enough that I feel the
need to do anything about it.
 
J

John Roth

Rainer Deyke said:
I can think of several things. One would be passing a name as an argument
to a function.

Given your example below, I *think* you're asking to be able
to pass a *something* that allows you to bind an object to an
identifier in another object. I don't think it would be particularly
difficult to create an object that could do this, but I'd really
have to be convinced as to why there isn't any simpler way to
accomplish the (unstated) end result, especially since the potential
for very hard to diagnose coupling and side effects is horrendous.
Given the immutability of certain Python objects, it is
often necessary to write statements in the form of
"x = f(x)". This is a violation of the Once And Only Once principles, since
it mentions the same variable twice.

That's a very weak reason.

John Roth
 
A

Aahz

Aahz said:
Rainer:
l[x * 2 + f(y)] = f(l[x * 2 + f(y)])

This statement contains an obvious redundancy that will make code
maintenance difficult. Python allows me to factor out some of the
redundancy:

index = x * 2 + f(y)
l[index] = f(l[index])

However, Python gives me no way to factor out the remaining
redundancy.

Sure it does: change the immutable to a mutable.

Not good enough.

Why not? Note that you're playing what is IMO an unfair game where you
keep changing the goalposts.
I'd rather write "l[x] = f(l[x])" with all of its redundancy than wrap
every conceivable immutable object in a mutable wrapper. Besides, I
don't *want* 'f' to change an object (which may also be referenced
elsewhere); I want it to change a binding.

Well, you're going to have to pay for what you want in some fashion;
Python's going to keep its default semantics, so you're going to need
*some* kind of wrapper.
And, really, "l[x] = f(l[x])" isn't that big of a deal. It's a bit of
redundancy that I'd rather not have, but it's not bad enough that I
feel the need to do anything about it.

<shrug> It's not a redundancy unless you're using a particular skewed
way of looking at things. If you're going to skew, you might as well
keep skewing until you're using a Pythonic mechanism.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top