D programming language has an interesting construct, scope(exit), that arranges something to be done when leaving the enclosing block. ====== { auto fd = File("/dev/null"); scope(exit) { close(fd); } ... } ====== The same thing is added easily to TCL: ====== proc scope(exit) {args} { upvar {___ scope guard} guard set guard "" trace add variable guard unset \ [list %scope(exit)onTrace [uplevel 1 {namespace current}] $args] } proc %scope(exit)onTrace {nativeNamespace command name1 name2 op} { namespace eval $nativeNamespace $command } proc test {} { set channel [open [info nameofexecutable] r] scope(exit) close $channel scope(exit) puts "Bye-bye. Channel closed: $channel" } ====== It can be argued that try ... finally or catch ... return may do the same, but the advantage of scope(exit) is that a clean-up command for each resource may be declared near the place where the resource is allocated. Thus using scope(exit) may improve code readability. Two or three bad things about this hack: * When the cleanup command is called, the stack frame of the enclosing procedure is already deleted. Things as scope(exit) { close $fd } are impossible: $fd substitution can not happen in scope exit handler * Errors from the scope exit handlers are silently ignored. * In TCL, a loop/if/eval/catch/etc. body does not have its own scope. Because of this, scope(exit) semantics may be unobvious here: ====== while {$something} { open something... scope(exit) cleanup something ;# doesn't work as expected } ======