|
From: Twylite <tw...@cr...> - 2008-11-22 13:06:05
|
Hi,
> From: Magentus <mag...@gm...>
>
> The [finally script] usage is trivial to implement using unset traces
> (although not quite as clean, mostly since it uses a magic variable
> name).
>
This works for [proc] and [apply], but is not completely reliable.
There is no guarantee that the magic finally variable will be the last
to be unset, so a script like 'finally [list close $f]' is safe but
'finally { close $f }' may not behave as expected.
Also [try] is not a separate scope for variables, so it would have to
have a special interaction with the magic finally variable such that
[finally] scripts added inside the context of [try] are executed at the
end of the [try].
Example:
proc dostuff {} {
set f [open {c:/boot.ini} r]
trace add variable --finally--trap-- unset [list apply [list args {
close $f ; puts done }]]
}
dostuff
chan names ;# -> stdout stderr filed27ae8 stdin
proc dostuff {} {
set f [open {c:/boot.ini} r]
trace add variable --finally--trap-- unset [list apply [list args
[list close $f]]]
}
dostuff
chan names ;# -> stdout stderr stdin
> The [try] command for matching on something other than the return code
> is excellent. Especially if it can match on return values as well as
> errorcodes. How about this for a twist on the idea...
>
> try {
> script
> } catch {
> var ?opts?
> } then {
> script
> } handler .....and so on.....
>
This fits with extending [catch], e.g.
catch { ... } em opts then { ... } handler {...}
The feedback I've had so far on this approach has not been favorable.
It seems that developers would prefer to keep the args/vars in the
context of the handler body.
> Regardless, why not have the handler clause evaluate an expression in
> the context of a [dict with $opts]? Then you can use whatever matching
> function you wish, the only minor pain is that you have to use some
> ugly bracketing of the option names { ${-code} == 2 }. But maybe
> there's a way around that, too, especially if the [dict with] is
> doable read-only and non-destructively somehow.
>
In a word, performance. I have been having conversations with other Tcl
developers off-list, and proposed exactly this. It is unquestionably
the most flexible option, but it forces a sequential consideration of
each handler's expression, preventing any sort of heuristic to improve
the performance of the construct. Since one of the uses of this [try]
will be to build other language constructs, performance is something
that deserves reasonable consideration.
The tradeoff may be to have "pluggable handler matching" where some
handlers can use exact matching ( O(1) time), some can use glob, some
can use expr, etc. Doing this in a manner that maintains a simple
syntax is quite difficult however.
> And finally for over-all syntax, what'd be wrong with tagging the
> try clauses onto the end of the present [catch] command. Make the
> options variable mandatory in this usage, and bring it into scope for
> the evaluations as above.
>
See above. I'm not necessarily against it, but it doesn't seem to be a
popular option.
>> > handle {code ?resultVar ?optionsVar??} { script }
>>
> Is there any actual practical use to putting code in the braces?
Not that I'm aware of, no. My current thinking is that it will be
outside the brackets, e.g.
handle code/expr {?resultvar? ?optionsvar?} { body }
> Something like a:
> withvars {resultVar ?optionsVar?}
> following the main try script indicating where to stash the variables.
>
One advantage of having the vars with the handler script is that it
allows you to reuse handlers. e.g.
set GENERAL_IO_HANDLER {{em opts} { log "Problem: $em" }}
...
try {
# some IO routine
} handle error * {*}$GENERAL_IO_HANDLER
And in this case its no coincidence that the GENERAL_IO_HANDLER looks
like an anonymous function that can be used with [apply]
> For the blending with [if] option, there was chatter a while back about
> fast [expr]-local variables intended mostly to hold partial results
> during an expression; the main terms of the options dict could quite
> readily be pre-loaded as [expr]-local variables.
I'm very interesting in the idea of extending [expr] in various ways,
especially to make pattern matching easier and somehow bind the error
options as variables into the expr. It's just not going to happen by 10
December, so we can't use any approach that relies on it.
Regards,
Twylite
|