John Porter wrote:
> 
> [EMAIL PROTECTED] wrote:
> >
> > Hmmm. If there's such an "always" block, I'd like to see it on
> > all blocks, including the continue [1]. But then, it becomes
> > hard to figure out to which block the always belongs....
> 
> That's precisely why these things should be shoved inside rather
> than dangling off the end.  JMHO.

I think "always" should be part of an explicit statement, such
as "try", not some implied property of block structure introduced
by a dangling clause (inside or outside).

Once you have an always clause, it has to be invoked during stack
unwinding caused by the raising of an exception.  This means there
is an implied goto-on-exception pending throughout the scope
affected by the always clause.  This is not like if/else, for, or
while, which are all marked up front, and only have explicit variant
flow control.  It is like eval, but note that eval is marked up
front too.

Like eval, the beginning of the scope for non-local flow control
(such as always and catch) should be explicitly delimited, typically
by using a keyword like try.  Consider the following two cases:

    foreach ... { try { ... } catch { ... } finally { ... } }

    try { foreach ... { ... } } catch { ... } finally { ... }

now take out the statement keyword and use magic dangling clauses:

    foreach ... { { ... } catch { ... } finally { ... } }

    { foreach ... { ... } } catch { ... } finally { ... }

The signal to noise ratio has gone down, no?

In fact, the cross product of these cases and the alternatives for
dangling always block placement produce these four cases:

    foreach ... { ... catch { ... } always { ... } }

    { foreach ... { ... } catch { ... } always { ... } }

    foreach ... { ... } catch { ... } always { ... }

    { foreach ... { ... } } catch { ... } always { ... }

Now play the problem backwards.  Say you run into one of the
cross-product constructs in some code.  Is it clear to you what
the scope and semantics are?  Is it clear when always applies
to the foreach block, and when it applies to the catch block,
and when it applies to the foreach statement?

What about the try/finally cases?  It's pretty clear, IMHO,
that the catch and finally clauses apply to the try statement,
simply because try is a statement of which they are part.  At that
point, the body of the try block and any previous catch or finally
blocks that are part of the same try statement are apparent.  The
previous blocks are critical, because under various circumstances
blocks need to be triggered by exceptions raised in previous
blocks.

>From a psychology of programming languages perspective, wrapping the
whole mechanism up into a statement per se provides the foundation
upon which we can attempt to avoid the conceptual disaster produced
by dangling clauses.  Mixing up traditional sequential flow-control
constructs and non-local stack-unwinding flow-control constructs,
without clearly delimiting what you're doing, is (I think) a less
than optimal idea.

Remember that one of the main uses for catch and always clauses is
error handling (as in, close file if opened even if error during
processing thereof).  I don't like language constructs that obfuscate
my attempts to get error handling right (such as they are) because
errors in error handling tend to make my code behave relatively poorly.

Yours, &c, Tony Olekshy

PS: since we're completely off subject, can we continue this under
http:[EMAIL PROTECTED]/msg05604.html

Reply via email to