'''scripted list''' , by [Poor Yorick] , is a procedure procedure takes a script , but instead of evaluating each "command" as a command, it builds up a list by concatenating all the words of all the "commands" . In other words , what is normally the command name in a script becomes just another item in the resulting list . The advantage is that it isn't necessary to use the backslash character when the list spans multiple lines , and in-line comments are supported . The question often arises: "How can I write a list using command and variable substitution , without having to escape the newline between the elements , and with the ability to make comments in between elements of the list and comment out some elements of the list" ? Scripted lists are the answer . ** Example ** ====== set mylist [sl { one two three ;#this is a comment $somevar #ha ha! a two-line \ comment in the list! [some command] {;} ;#literal semicolons must be escaped {some literal} "some $substituted[value]" }] ====== ** More Complex Example ** ====== set six six proc some {args} { return {seven eight} } proc value {} { return {nine ten} } proc side {args} { upvar var2 var2 set var2 twelve } set substituted eleven set mylist [sl { one two three ;#this is a comment {four five} $six #this is a a two-line \ comment in the list! [some command] {;} ;#literal semicolons must be escaped "[value] $substituted" only the first command in a line get the special scripted list treatment, \ but then only only the value othe last command in a line counts which \ means that this line is like a comment with [side effects] , and its \ result is whatever the last command produces; set var2 }] puts $mylist ====== Output: ======none one two three {four five} six {seven eight} {;} {nine ten eleven} twelve ====== ** Implementation ** ====== proc sl script { set res {} set parts {} foreach part [split $script \n] { lappend parts $part set part [join $parts \n] #add the newline that was stripped because it can make a difference if {[info complete $part\n]} { set parts {} set part [string trim $part] if {$part eq {}} { continue } if {[string index $part 0] eq {#}} { continue } #Here, the double-substitution via uplevel is intended! lappend res {*}[uplevel list $part] } } if {$parts ne {}} { error [list {incomplete parts} [join $parts]] } return $res } ====== ** See Also ** [scripted templates]: a twist on scripted lists <> list