Newsgroups: comp.std.c++
Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!sol.ctr.columbia.edu!ucselx!petunia!kestrel.edu!gyro
From: gyro@kestrel.edu (Scott Layson Burson)
Subject: Re: Proposed: "closures"
Message-ID: <1991Apr13.080757.1427@kestrel.edu>
Keywords: proposal, closures, function pointers
Organization: Kestrel Institute, Palo Alto, CA
References: <1991Apr12.081539.22690@kestrel.edu> <11489@exodus.Eng.Sun.COM>
Distribution: comp.std.c++
Date: Sat, 13 Apr 1991 08:07:57 GMT

In article <11489@exodus.Eng.Sun.COM> chased@rbbb.Eng.Sun.COM (David Chase) writes:
>There's one more way to implement closures, though it is less workable
>in this age of parameter-passing in registers and split (inconsistent)
>instruction and data caches -- one can generate code at run time to
>implement a closure, and this pass a "closure pointer" in the same
>style currently used to implement a "function pointer".

This possibility occurred to me, but I don't think it's a good idea,
because it means closure creation would require heap allocation; in
C++ (unlike Lisp) it is really not acceptable for a fundamental
language construct to use heap allocation for its implementation.
Consider also that not only would they have to be heap-allocated, but
a reference count scheme (like the `string' example in Stroustrup's
original C++ book -- sorry, I don't have the page number handy) would
be required to ensure that the allocated closures would be freed at
the right time.  This is really quite a lot of overhead just to keep
closure pointers one word long; I don't think it could ever be a
worthwhile tradeoff.

(Note that the trick doesn't require heap allocation for nested
functions, because the "object" (stack frame) being closed over is
itself necessarily stack-allocated.)

>And yes, I think closures are a good idea.  I have no special sympathy
>for existing code that uses pointers to member functions; first, I've
>never come across such code, and second, it wouldn't be the first time
>that a change to the language broke existing code.  I'm certain that
>I'd have more use for this than for (say) multiple inheritance (why
>so?  because I've needed to use this a couple of times already and
>simulated it clumsily, and because I haven't ever used multiple
>inheritance, even though it is already in the language.)

Oh dear, I left out a whole section from the proposal!  To summarize:
the inclusion of closures as I propose them would break NO existing
portable C++ code (I'll explain the "portable" in a moment).  First,
closures and pointers to member functions do not overlap
syntactically.  The notation for creating a pointer to member function
is not the simple `&f' (or just `f'); it is `&C::f' where C is the
class; similarly, the notation for declaring one also includes the
`C::'.  Second, the language does not currently define `&f' (or just
`f') when f is a member function of a class.  Thirdly, closures of
normal (nonmember) functions would behave exactly like pointers to
those functions do currently.  The only thing that would break is
conversions between pointers to functions and `void*', but these are
not portable anyway (E&S p. 36: "A pointer to function may be
converted to a `void*' provided a `void*' has sufficient bits to hold
it.")

Personally, I would like to see pointers to members deleted from the
language, but this issue is orthogonal to the closure proposal and can
be considered entirely independently.

-- Scott
Gyro@Reasoning.COM


