Path: utzoo!attcan!uunet!tut.cis.ohio-state.edu!rutgers!bellcore!roland!sjs From: sjs@roland.ctt.bellcore.com (Stan Switzer) Newsgroups: comp.object Subject: Re: code blocks (aka closures) Message-ID: <25212@bellcore.bellcore.com> Date: 11 Jul 90 21:54:14 GMT References: <5305@stpstn.UUCP> <11002@alice.UUCP> <1990Jul3.143743.22901@cbnewsc.att.com> <55700@microsoft.UUCP> <55703@microsoft.UUCP> Sender: news@bellcore.bellcore.com Reply-To: sjs@bellcore.com (Stan Switzer) Organization: Bellcore Lines: 74 In article <55703@microsoft.UUCP> bobatk@microsoft.UUCP (Bob Atkinson) writes: > >Peter Deutsch writes: > >> [paraphrased by rga] "C today lets us take pointers to local variables, > >> even though they are `dangerous'. One can imagine a similar form of > >> `dangerous' closures". > > It seems to me that these form of closures would suffice for a > significant fraction of the situations in which I find myself > using closures in Smalltalk, upwards of 85% or so. Indeed. Even a dangerous closure would be useful. Since a dangerous closure corresponds to an automatic variable, it does raise the questionof whether there should be a form of closure which corresponds to C's heap memory, though. Then again, wantin' and gettin is two different things, and I'm not going to loose sleep thinking about useful extensions to the C language. > But, you say, we already have a mechanism in C++ that supports > these situations: Enumerator classes. An excellent observation. I hadn't thought of it as an enumerator, but of course! In fact, I did something like this once in Objective-C. Basically, I built a coroutine-like environment where individual "tasks" were coded as classes and each step was a method. Invocation of a (sub-)task was in two steps: instantiating the task (with its parameters, etc) and starting it. Instantiation was via the new: method. The "start" method specified which task to continue and at which method (a poor man's continuation). If you deconstruct this admittedly tedious scenario you'll see that "task" object instance records correspond exactly to a stack of activation records, even to the point of containing a previous stack pointer (task to resume), return location (method to invoke), and local variables (instance variables). Fortunately, most of this apparatus could be hidden in a common superclass and subtask invocation could be made reasonably nice looking using a few macros. Bill goes on to describe a few of the difficulties: > This has > always seemed a little strange to me: why should I have to build by > hand that which the system build _for_ me most of the time? Takes a while for these ideas to sink in, I guess. > 2) Each different manner of enumerating some aspect of an object > requires a different enumerator class, since a different "stack frame" > will be required. Yeah, verily. Having nested classes might go a long way in solving this problem and quite a few others. Another problem is that loops don't look like loops since the looping is generally done by setting up the "next" method as a previously executed method. Oldtimers will recognise this as a go-to. Oldtimers will also remember that it is possible to do structured programming with gotos, but if at all possible it is better to have the compiler write your gotos for you. Along these lines, one could write a scripting prepreocessor which transforms reasonable looking control structures into chains of method invocations. I think some company in the Netherlands sells something kinda like this. Anyway, it seems about time that activation records and instance records were completely integrated notions and that closure and object instantiation were similarly unified. Food for thought. > As always, comments and thoughts are most welcome. Likewise, Stan Switzer sjs@bellcore.com