** What's "with" ** It's a construct that can automatically clean up "garbage" after finishing a task. For example, [open] is usually combined with a [chan close]. A "with" construct will automatically close the file descriptor (aka. handle). Reasonably use the "with" construct can make your code visibly clearer. ** One possible implementation ** ====== proc getFinalByOp {op opret} { switch -exact -- $op { open { return [list chan close $opret] } default { return [list] } } } # # op: a command # opargs: @op's arguments # body: code that will be executed # ?_finally?: provide a 'finally' yourself # ?varname?: result of @op # proc with {op opargs body {_finally {}} {varname handle} } { set finally $_finally try { set [set varname] [$op {*}$opargs] if {$finally eq {}} { set finally [getFinalByOp $op [set [set varname]]] } eval $body } finally { eval $finally } } ====== This implementation only supports [open], it's not extensive, and it's buggy (see Discussions below). ** How to use it ** ====== with open {a.txt w} {chan puts $handle "hello world"} with open {a.txt r} {puts [read $fd]} {} fd with puts {"a test"} {set a {hello}} {puts $a} ;# a meaningless example ====== ** A more complex example ** Read in a file (employees.txt) of the following format, ====== name1,salary1 name2,salary2 name3,salary3 ====== The real file is, ====== Mike Foo,10000 Jack Bar,2000 John Doe,3000 ====== If salary < 3000, add 200, and in the end print the result, write it back. A possible implementation (can be easier?), ====== # ... "with" here ... with open {employees.txt r+} { set contents [chan read -nonewline $handle] foreach line [split $contents \n] { set list [split $line ,] if {[lindex $list 1] < 3000} { lset list 1 [expr {200+[lindex $list 1]}] } lappend result "[lindex $list 0],[lindex $list 1]" } chan seek $handle 0 chan truncate $handle 0 puts [join $result \n] chan puts -nonewline $handle [join $result \n] } ====== ** Discussions ** From the IRC channel, ====== I am afraid that 'general with' will not work - not with bodies that try to use variables from the calling env ... nor with commands that resolv differently in the calling env and in the proc's namespace ====== <> Control Structure | Concept cyril: I have a much simpler implementation https://github.com/cyrilthomas/with