Article View: comp.lang.misc
Article #2635Re: On whether C has first-class composable functions
From: Lennart Augustsson
Date: Wed, 09 Jan 1991 17:35
Date: Wed, 09 Jan 1991 17:35
125 lines
6418 bytes
6418 bytes
My unnamed C-functions seems to have caused some misunderstandings
and controversy so here is an explanation. (I now promise that
this is my last posting on this subject, no matter how badly it will
be misunderstood.)
When I explained unnamed C-functions in C i said:
The C-function expression should also behave as a normal C expression,
i.e. it can be sent as an argument, returned etc.
This clearly states that returning an unnamed function is ok.
This means that my compose example works. (If we play a game and I define
the rules and then follow them, you cannot accuse me of cheating,
but you *can* complain about the rules). It may be unreasonable to
require anonymous C-functions to be returnable, but that's another
matter. To forestall a discussion of this I'll give a few of the
objections to having unnamed returnable C-functions:
- It's unimplementable.
This is clearly wrong since many languages have them.
- It's to hard to implement.
I think not, but that's a matter of opinion.
- It goes against the "spirit" of C.
This is an argument I could buy, an implementation of them
would be somewhat alien in C, but not more than some of the things
in C++.
Since the unnamed functions caused some confusion I'll present some
interpretations on what they could mean. I must now return to my
nitpick mode and distinguish between C-functions and pointers to
C-functions. (I should never have stopped nitpicking.)
What does "return int ANONYMOUS(int x) { return x+1; };" mean?
1. C has "first class" (whatever that is) pointers to functions,
but not functions (i.e. functions cannot be sent, returned etc.)
1a. "int ANONYMOUS(int x) { return x+1; };" represents a C-function value.
This means that the return statement has a type error (you can only
return pointers to functions), so this cannot be the intended meaning.
1b. "int ANONYMOUS(int x) { return x+1; };" follows the C rule that
a function automatically gets the "&" (address-of) operator inserted
to get a pointer.
This would also be an error if "int ANONYMOUS(int x) { return x+1; };"
is a function value. It would be like saying "return &5;", since
you cannot apply & to a value, only to an lvalue.
1c. The value "int ANONYMOUS(int x) { return x+1; };" is automagically
somehow turned into an lvalue (by allocating space for it and
storing it and then giving this address as the result).
This makes unnamed C-functions into a special case, but if you want them
to work this is the way to go. Memory can be allocated on the stack or in
the heap (or more generally: somewhere that is automatically deallocated
when leaving the function or where the extent is unlimited). Memory
cannot be allocated on the stack since this would make it impossible to
return the pointer to it. This seems to be the version that Dan and
Karl thought I meant. Memory can also be alloacted in the heap so that
the address is valid after returning, this is a solution that works.
(If C has no heap then returnable pointers to unnamed C-functions
cannot be implemented.)
Notice that I agree entirely with Dan(!!) that allocatablity is the crucial
point here (but also see 2). The point I'm trying to make is that if
you add unnamed C-functions that can be returned (I don't think this
is unreasonable since you can return unnamed ints), this implies
allocatability (or whatever you like to call it).
2. C has "first class" C-functions (not just pointers to them).
This means that function values are now all right and need not be
turned into pointers to be returned etc. This is the status that
structs have in C (but you cannot have unnamed struct).
The meaning of returning a C-function is now simply that you return
the value of it.
A small example may illustrate the point
/* mkaddc takes an int and returns a function that adds this */
typedef int intintfun(int);
intintfun mkaddc(int c) {
return intintfun ANONYMOUS(int x) { return x+c; }
}
compare this with a function returning a struct
typedef struct { int z; } intstruct;
intstruct makec(int c) {
intstruct s;
s.z = c;
return s;
}
(in GCC which allows unnamed structs you can write
typedef struct { int z; } intstruct;
intstruct makec(int c) {
return (intstruct){ c };
}
)
Notice that the struct example is very much like the functions example:
- the returned value contains the value of an argument.
- the returned value is not a pointer.
In solution 2 there is no need to add special rules that converts
function values to pointers, the values themselfes can be returned.
I think Dan (maybe) misunderstood my posting that said that unnamed
C-functions would add semantic power. First, I was speaking about
unnamed C-functions specifically, unnamed structs would add no power.
Second, I did not want to imply that unnamed functions could be
added without further implications, i.e. if you choose 1 you have
to make them automatically allocated, if you choose 2 you have to
introduce C-functions (not pointers) as first class objects.
In my article that said that unnamed functions would give extra power
I think I said (I've lost the article) that they should be added in a
reasonable way, without explaining what I meant by reasonable. What I
meant was that unnamed C-functions should not be inferiour to other
unnamed values in C, e.g. they should be returnable. This has, as we
can see, rather big implications. Since a (working) extension of C
would entail so big changes you might have objections to making it.
-- Lennart Augustsson
[This signature is intentionally left blank.]
Technical Details
Message-ID:
<1991Jan9.173503.22914@mathrt0.math.chalmers.se>Path:
arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!usc!snorkelwacker.mit.edu!bloom-beacon!eru!hagbard!sunic!chalmers.se!mathrt0.math.chalmers.se!augustssReferences:
<1991Jan5.182428.615@mathrt0.math.chalmers.se> <1991Jan05.222639.6387@dirtydog.ima.isc.com> <1991Jan6.205005.4579@mathrt0.math.chalmers.se> <1988:Jan703:32:5191@kramden.acf.nyu.edu>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!usc!snorkelwacker.mit.edu!bloom-beacon!eru!hagbard!sunic!chalmers.se!mathrt0.math.chalmers.se!augustss From: augustss@cs.chalmers.se (Lennart Augustsson) Newsgroups: comp.lang.misc Subject: Re: On whether C has first-class composable functions Message-ID: <1991Jan9.173503.22914@mathrt0.math.chalmers.se> Date: 9 Jan 91 17:35:03 GMT References: <1991Jan5.182428.615@mathrt0.math.chalmers.se> <1991Jan05.222639.6387@dirtydog.ima.isc.com> <1991Jan6.205005.4579@mathrt0.math.chalmers.se> <1988:Jan703:32:5191@kramden.acf.nyu.edu> Sender: news@mathrt0.math.chalmers.se (Evald Nyhetsson) Organization: Dept. of CS, Chalmers, Sweden Lines: 125