spent a little while in number theory class thinking about the discussion we had here regarding exceptions the other day. got to thinking that there's a powerful generalization lurking here. I've recently been stupendously impressed with the flexibility and clarity of sather's iterator abstraction, which neatly handles all repetitive control flow mechanisms in a single, clean form; so I got to wondering if there's a similarly lucid way of describing things which stack-local-objects are used for (in good C++). Especially when considering jwz's salient comment about general purpose macros for transforming control, I think there is:
what I'm thinking of is a way to subsume the try,
catch, throw, finally,
return and
synchronized
statements in Java; as well as the concept
of auto_ptr and the
resource-aquisition-is-initialization pattern in C++. The
way to do this is to introduce a language-supported
parametric type akin to this:
template <class Inner,Class Outer> Frame {
void enter(Thread me);
Outer leave(Thread me, Inner retval);
};
Then you introduce a new language keyword frame and
construct of the following form:
frame (<Frame-Expr>) {
...
}
The enter method is called when a
thread enters the frame, and the leave method is
called when a thread leaves the frame, implicitly
transforming the Inner return value of the block
contained in the frame into the Outer return
value of the frame. then augment the return keyword
to take an argument specifying which containing frame the
return should return to. Omission of the parameter
implicitly means "current method", otherwise a named
Frame is expected.
This approach accomodates a lot of strategies.
You can, for instance, have a virtual method which produces a Frame which handles "appropriate synchronization" of an object, and let subclasses decide if that means a local mutex, a static mutex, a semaphore, or nothing at all. You can do exception handling by constructing a frame of type Frame<union<ExceptionType,ReturnType>,ReturnType>, or you can do exception propagation by constructing a frame of type Frame<union<ExceptionType,ReturnType>,union<ExceptionType,ReturnType>> You can (as Ankh suggested) pass an error reporting object into a method, and have it used as a Frame around a sensitive block of code.You can factor out a whole class of exception handling code into a Frame produced from a common method implemented in a mixin class. You can make a finalizer which cleans up objects when it exits, like an auto_ptr.
There are at least 3 advantages to this approach over stack objects in C++:
- it works with a references-only language like java
- it requires that programmers be aware of it, and eases them into the task of writing their own Frames, since they already use it for synchronization and exception handling. many C++ people don't actually know any methodology involving stack-local objects
- it's possible to parameterize behaviour more easily. stack-local objects must have concrete type (must be named by their constructor), but a frame block must simply typecheck. the Frame object it uses can be a subtype of the checked type.
Comments? I'm curious if anyone either (a) has seen this before, or (b) thinks it would work.
fatjim: go see a chiropractor. it's probably your neck. my arms were killing me, I got a chiro to adjust my neck, a pinched nerve became unpinched -- now my arms don't hurt anymore.
dria: I rank someone a master if either (a) I have already learned something really significant from them, or else (b) their work leads me to believe that if/when I sit down and get to know them, I'll learn something really significant from them.