By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,691 Members | 1,123 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,691 IT Pros & Developers. It's quick & easy.

Origin of the term "first-class object"

P: n/a
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
Jul 18 '05 #1
Share this Question
Share on Google+
24 Replies


P: n/a
Hung Jung Lu wrote:
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 && ma*@alcyone.com && 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
Jul 18 '05 #2

P: n/a
On 17 Nov 2003 13:35:36 -0800, Hung Jung Lu wrote:
"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.

--
\ "If you get invited to your first orgy, don't just show up |
`\ nude. That's a common mistake. You have to let nudity |
_o__) 'happen.'" -- Jack Handey |
Ben Finney <http://bignose.squidly.org/>
Jul 18 '05 #3

P: n/a

"Hung Jung Lu" <hu********@yahoo.com> wrote in message
news:8e**************************@posting.google.c om...
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


Hung Jung

Jul 18 '05 #4

P: n/a
Hung Jung Lu wrote:
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/


Jul 18 '05 #5

P: n/a
John Roth wrote:
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.
--
Rainer Deyke - ra*****@eldwood.com - http://eldwood.com
Jul 18 '05 #6

P: n/a
Rainer Deyke wrote:
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 && ma*@alcyone.com && 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
Jul 18 '05 #7

P: n/a
On Mon, 17 Nov 2003 23:18:52 GMT, Rainer Deyke wrote:
John Roth wrote:
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.


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.

--
\ "We must respect the other fellow's religion, but only in the |
`\ sense and to the extent that we respect his theory that his |
_o__) wife is beautiful and his children smart." -- Henry L. Mencken |
Ben Finney <http://bignose.squidly.org/>
Jul 18 '05 #8

P: n/a

"Rainer Deyke" <ra*****@eldwood.com> wrote in message
news:wHcub.227649$Tr4.672235@attbi_s03...
John Roth wrote:
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.


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
Jul 18 '05 #9

P: n/a
John Roth wrote:
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.

--
Rainer Deyke - ra*****@eldwood.com - http://eldwood.com
Jul 18 '05 #10

P: n/a

"Rainer Deyke" <ra*****@eldwood.com> wrote in message
news:wHcub.227649$Tr4.672235@attbi_s03...
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

Jul 18 '05 #11

P: n/a
On Tue, 18 Nov 2003 03:01:35 GMT, Rainer Deyke wrote:
John Roth wrote:
I can't think of anything I can't do with a name that I might want
to.
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.

--
\ "Kissing a smoker is like licking an ashtray." -- Anonymous |
`\ |
_o__) |
Ben Finney <http://bignose.squidly.org/>
Jul 18 '05 #12

P: n/a
Ben Finney wrote:
On Tue, 18 Nov 2003 03:01:35 GMT, Rainer Deyke wrote:
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)?


Binding the name to a different object.
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)",


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.
--
Rainer Deyke - ra*****@eldwood.com - http://eldwood.com
Jul 18 '05 #13

P: n/a
Erik Max Francis <ma*@alcyone.com> writes:
Hung Jung Lu wrote:
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.

[...]

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
Jul 18 '05 #14

P: n/a

"Ben Finney" <bi****************@and-benfinney-does-too.id.au> wrote in
message news:sl*******************************@rose.locald omain.fake...
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.


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
Jul 18 '05 #15

P: n/a
In article <wmkub.177225$9E1.927898@attbi_s52>,
Rainer Deyke <ra*****@eldwood.com> wrote:

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.
--
Aahz (aa**@pythoncraft.com) <*> http://www.pythoncraft.com/

Weinberg's Second Law: If builders built buildings the way programmers wrote
programs, then the first woodpecker that came along would destroy civilization.
Jul 18 '05 #16

P: n/a
In article <sl*******************************@rose.localdomai n.fake>,
Ben Finney <bi****************@and-benfinney-does-too.id.au> wrote:
On Tue, 18 Nov 2003 03:01:35 GMT, Rainer Deyke wrote:
John Roth wrote:
I can't think of anything I can't do with a name that I might want
to.


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)?


That's rather beside the point, isn't it? People
continually come to c.l.p asking how to get the names of
function parameters. Some are trying to write diagnostic
routines. Some people want to know how to make data names
out of user input strings; we tell them to for heaven's sake
use a dictionary.

It's not unreasonable to give names as an example of
second-class objects in Python.

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

Regards. Mel.
Jul 18 '05 #17

P: n/a
Mel Wilson wrote:

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
Jul 18 '05 #18

P: n/a
Aahz wrote:
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.
--
Rainer Deyke - ra*****@eldwood.com - http://eldwood.com
Jul 18 '05 #19

P: n/a

"Rainer Deyke" <ra*****@eldwood.com> wrote in message
news:jYfub.229477$Tr4.681061@attbi_s03...
John Roth wrote:
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 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
--
Rainer Deyke - ra*****@eldwood.com - http://eldwood.com

Jul 18 '05 #20

P: n/a
In article <m8uub.235682$HS4.2034763@attbi_s01>,
Rainer Deyke <ra*****@eldwood.com> wrote:
Aahz wrote:
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.
--
Aahz (aa**@pythoncraft.com) <*> http://www.pythoncraft.com/

Weinberg's Second Law: If builders built buildings the way programmers wrote
programs, then the first woodpecker that came along would destroy civilization.
Jul 18 '05 #21

P: n/a
On Mon, Nov 24, 2003 at 12:33:40PM -0500, Aahz wrote:
In article <m8uub.235682$HS4.2034763@attbi_s01>,
Rainer Deyke <ra*****@eldwood.com> wrote:
Aahz wrote:
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.


Up for a new operator?

l[index] ()= f

<1.5-wink>, Jp

Jul 18 '05 #22

P: n/a
In article <ma*************************************@python.or g>,
Jp Calderone <ex*****@intarweb.us> wrote:
On Mon, Nov 24, 2003 at 12:33:40PM -0500, Aahz wrote:
In article <m8uub.235682$HS4.2034763@attbi_s01>,
Rainer Deyke <ra*****@eldwood.com> wrote:

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.


Up for a new operator?

l[index] ()= f


"Boot to the head. <thump>"
--
Aahz (aa**@pythoncraft.com) <*> http://www.pythoncraft.com/

Weinberg's Second Law: If builders built buildings the way programmers wrote
programs, then the first woodpecker that came along would destroy civilization.
Jul 18 '05 #23

P: n/a
Jp Calderone wrote:
Up for a new operator?

l[index] ()= f


I like it! :-)

I suppose you should be able to put extra args in, too, e.g.

l[index] (foo, 42)= f

--
Greg Ewing, Computer Science Dept,
University of Canterbury,
Christchurch, New Zealand
http://www.cosc.canterbury.ac.nz/~greg

Jul 18 '05 #24

P: n/a
On Tue, 25 Nov 2003 15:07:22 +1300, "Greg Ewing (using news.cis.dfn.de)" <g2********@sneakemail.com> wrote:
Jp Calderone wrote:
Up for a new operator?

l[index] ()= f
I like it! :-)

Me too ;-)
But I wonder if =()= wouldn't read more clearly, e.g.,

l[index] =()= f

and see below.
I suppose you should be able to put extra args in, too, e.g.

l[index] (foo, 42)= f

I presume that would imply that f had all optional args after the first.
What if you wanted to pass the update target in another position? E.g.,

l[index] =(foo, ??, 42)= f

where ?? is some kind of indicator for where to plug in the arg. I guess you
could use packing/unpacking if you had a tuple left side and several ??'s to match, e.g.,

a, l[index] =(foo, ??, 42, ??)= f

meaning

a, l[index] = f(foo, a, 42, l[index])

or course the targets could be simple as well

a, b =(foo, ??, ??, 42)= f

meaning

a, b = f(foo, a, b, 42)

Hm, I wonder about * for pack/unpack into arg tuple in this context

a, b =(foo, *??, 42)= f

maybe meaning

a, b = f(foo, (a,b), 42)

or did I get that backwards?

Sorry, can't help it ;-)

Regards,
Bengt Richter
Jul 18 '05 #25

This discussion thread is closed

Replies have been disabled for this discussion.