lappend varName ?value value ...? ---- http://www.purl.org/tcl/home/man/tcl8.4/TclCmd/lappend.htm ---- Appends each ''value'' as a list [element] onto the end of the list stored in ''varName''. ''lappend'' used to be the only list-command which requires the '''name of a variable containing a list''' rather than the list itself, but in Tcl 8.4 the [lset] command was introduced. lappend listName rather than lappend $listName This command differs from [append] in that values are appended as list elements rather than raw text. ---- lappend will not ''make'' varName a list ; if it is one before the command, it will continue to be one. [AJD] Uh? [lappend] *will* attempt to make varName's value into a list. The docs say "This command treats the variable given by varName as a list." ie. if it isn't a list to begin with, tcl will attempt to convert it to one, giving an error this is not possible: % set x "a \{" ;# string a { % lappend x b ;# treat it as list unmatched open brace in list ;# it wasn't a proper list! [LV] Actually, the example here of x and b demonstrates that Tcl does not try to make varName into a list, but instead presumes that it is a valid list. If it ''attempted'' to turn the variable into a list, it would surely succeed; in this case, however the basic assumption of (nearly?) all the '''l*''' commands is that ''list'' arguments are proper lists and that no attempt will be made to second guess the caller. [Lars H]: It seems you disagree about what it means to "attempt" something. What lappend does is that it ''attempts'' to generate a list internal representation for the current value of the variable (i.e., it calls tclListType.setFromAnyProc [http://www.tcl.tk/man/tcl8.4/TclLib/ObjectType.htm]), and then appends the element(s) to that. This attempt will fail when the string representation cannot be interpreted as a list. [LV] Actually, what I was disagreeing with was the idea the phrase "make varName's value into a list". This was based on my interpretation of the docs - which was a mistake on my part. However, user of '''lappend''' needs to understand that lappend will not turn a string value ''into'' a list; if the string is not a list, then a call to lappend fails. And that's really the bottom line of the discussion. Sorry for the digression. ---- You do not need to assign the results of lappend to varName; lappend modifies varName directly. ---- How would one append an item to the beginning of a list? Since ''append'' means ''to the end of'', one wouldn't append to the beginning of a list. Instead, for a way to perform the equivalent of ''prepend'', see [linsert] -- jfr [LV] [[tried proposing a couple ways to prepend, all of which failed... [RS] [[provided the comment that...]]]] set a [concat $toPrepend $a] results in the 4-element list (maybe via shimmering over string reps) xyz 1 2 3 [linsert] would keep an existing list representation, so I presume its faster to do set a [linsert $a 0 $toPrepend] [slebetman] - If I'm not mistaken, [concat] have been optimised in 8.4 to not shimmer when processing pure lists. In fact it is even faster than [linsert]: % set a [list a b c] % time {set a [linsert $a 0 d]} 10000 41.1639 microseconds per iteration % set a [list a b c] % time {set a [concat d $a]} 10000 4.8214 microseconds per iteration [Lars H]: As far as I can tell, this is not using the [pure list] optimisations of [concat] -- you're seeing the string performance of that command! If you try it with larger list elements, performance should start to favour [linsert] instead. You might also want to check what happens if you rewrite the above using the "[K] combinator" to let [linsert] operate on an unshared [Tcl_Obj]; this appears to be the case that [linsert] is optimised for (even though it is probably rather rare, hmm...). [slebetman] - Quite right, testing with large 100 character strings gives me 36.7218 microseconds per iteration for [linsert] but a staggering 1609.4685 microseconds per iteration for [concat] - yikes! ---- [RS] 2006-10-01: [jcw] contributed this (for me) surprising [idiom]: lappend var does nothing, but creates ''var'' if it doesn't exist. Similar to, but simpler than: if {![info exists var]} {set var ""} This may however fail if $var holds a string that cannot be parsed as a list. [wdb] It works, but it is some kind of ''dirty trick'' as it is based on some Tcl-internal optimizing located far out of documented behaviour. The greater danger is '''not''' to throw an error. Exemplum gratia, here [lappend] works as you describe: % set a "a {b} c" a {b} c % lappend a a {b} c but here not: % set a "a {b} c" a {b} c % lappend a x a b c x Unintended side effect: element b has "forgotten" its surrounding braces as they are not necessary for identifying b as a list element. I don't think that this will fit to the category [quick'n'dirty] as it is perhaps dirty enough but not quick if you are hunting the resulting bugs on friday afternoon ;-) [Lars H]: Well, if you care about the braces, then apparently you don't merely see the value as a list, and in that case using [lappend] probably isn't the right thing to do (as ''it'' will only respect the list interpretation of the value). [jcw] has also been seen using [append] in the same way, when the value is a more general string. ---- See also [list], [lindex], [linsert], [llength], [lrange], [lreplace], [lsearch], [lsort] . ---- [Tcl syntax help] - [Arts and crafts of Tcl-tk programming] - [Category Command]