[GPS]: I'm really sick of the discussion over the expand vs. {} vs. {expand} and so on, so I came up with this. Comments are welcome... #Copyright 2003 George Peter Staplin #You may use this under the same terms as Tcl. proc safe.eval args { set expand 0 set cmd [list] foreach arg $args { if {"~" == $arg} { set expand 1 } else { if {$expand} { set cmd [concat $cmd $arg] } else { lappend cmd $arg } set expand 0 } } uplevel 1 $cmd } proc A {a b c d e f g h} { puts "A:$a $b $c $d $e $f $g $h" } proc B {} { return [list 1 2 3] } proc main {} { set l [B] safe.eval A ~ $l "\"Hello \{\" World" ~ [list a b c] "Bye World" puts "Now testing with a typical Tk usage..." package require Tk pack [button .b] pack [button .b2] pack [button .b3] puts BEFORE:[winfo children .] safe.eval destroy ~ [winfo children .] puts AFTER:[winfo children .] exit } main ---- [GPS]: To help the reader understand this (after a comment in Tcl'ers chat). The ~ token is discarded in a safe.eval call. ~ is like the proposed ` except it must be preceded and followed by whitespace. Any list or string after a ~ token is expanded. Simple no mess solution to a simple problem. The character is easily changed if you like. ---- [GPS]: Here we have revision 3 that solves the problem of passing ~ to a procedure. I've also expanded the tests and they are easier to read. #Copyright 2003 George Peter Staplin #You may use this under the same terms as Tcl. #Thanks to RS and AM for comments via the Tcl'ers Chat. #rev 3 proc safe.eval args { set expand 0 set cmd [list] set lastArg "" foreach arg $args { if {"~" == $arg} { if {"~" == $lastArg} { #we have a double pattern which means ~ is an argument lappend cmd $arg set lastArg "" set expand 0 continue } set expand 1 } else { if {$expand} { set cmd [concat $cmd $arg] } else { lappend cmd $arg } set expand 0 } set lastArg $arg } uplevel 1 $cmd } proc A {a b c d e f g h} { puts "A:" foreach v [list a b c d e f g h] { puts " $v: [set $v]" } } proc B {} { return [list 1 2 3] } proc C {a b c d e f g} { puts "C:" foreach v [list a b c d e f g] { puts " $v: [set $v]" } } proc main {} { set l [B] safe.eval A ~ $l "\[hello\]\"Hello \{\" World" ~ [list a b c] "Bye World" #We can double ~ to pass ~ as an argument. safe.eval C ~ $l ~ ~ ~ $l puts "Now testing with a typical Tk usage..." package require Tk pack [button .b] pack [button .b2] pack [button .b3] puts BEFORE:[winfo children .] safe.eval destroy ~ [winfo children .] puts AFTER:[winfo children .] exit } main