[Nickle]Twixt and exceptions
Keith Packard
keithp@keithp.com
Tue, 20 Feb 2001 20:22:22 -0800
Two of the unfinished pieces in nickle are exception handling and "critical
sections" -- pieces of code executed on the way out of a stack context
during exeception handling.
* critical sections
A big problem Bart and I have seen with other languages is that the
enter/leave portions of "critical sections" is assymetrical, we usually
have:
lock_mutex ()
try {
... lots of code here ...
} finally {
unlock_mutex ();
}
or some such; this is unpleasing to the eye; the lock and unlock are
separated both by a large distance and are actually at different
indentation levels.
Instead, Bart came up with the following syntax:
twixt (<enter-expr>; <leave-expr>) <statement>
After <enter-expr> is executed, <leave-expr> is guaranteed to be executed.
So, you would do:
twixt (mutex.acquire (m); mutex.release (m))
{
stuff with m locked
}
Questions: how should this work with non-blocking syncronization
primitives (mutex.tryAcquire, semahpore.test)?
Suggestion: initial statement is boolean, entry to twixt is denied if the
first statement evaluates to False.
twixt (mutex.tryAcquire (m); mutex.release (m))
{
stuff with m locked
}
Problem: assymetry returns, need to capture tryAcquire result to learn if
'stuff' was executed.
Alternative: force program to handle this case:
twixt (got = mutex.tryAcquire (m); got ? mutex.release (m) : 0)
{
if (got) {
stuff with m locked;
}
}
or
if (mutex.tryAcquire(m) twixt (; mutex.release (m))
{
stuff with m locked;
}
Problem: Extra scope, or assymetrical usage.
Suggestions are welcome; I'm leaning towards the predicated twixt form.
* Exceptions.
Here's the current plan, it's not implemented but probably will be soon.
Exceptions are symbols declared with function-like syntax that can
be dynamically bound to a particular lamda. Uncaught exceptions terminate
the thread with an error. An example would be helpful here:
exception missing_q (string line);
...
s = "foobar";
try {
if (strings.index (s, "q") < 0)
throw missing_q (s);
} catch missing_q (string line) {
printf ("Hey, bozo, no 'q' found in %s\n", line);
}
Question: the 'catch' and 'throw' keywords are completely gratuitous
syntactic sugar. Can I get rid of them? Or would the alternative be too
confusing?
Would you prefer this syntax instead:
{
catch missing_q (string line)
{
printf ("Hey, bozo, no 'q' found in %s\n", line);
}
if (strings.index (s, "q") < 0)
throw missing_q (s);
}
One I'm not fond of:
catch missing_q (string line)
{
printf ("Hey, bozo, no 'q' found in %s\n", line);
}
{
if (strings.index (s, "q") < 0)
throw missing_q (s);
}
This last form would require the 'catch' keyword to keep it parsable.
Complaints? Comments?
-keith