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