'''[http://www.tcl.tk/man/tcl/TclCmd/linsert.htm%|%linsert]''' inserts words into a [list]. ** Synopsis ** : '''linsert''' ''list index word1'' ?''word2 word3 ...''? This returns a list that consists of ''list'' with the given ''word''s inserted at ''index''. It does not modify ''list'' itself. ** Description ** `linsert` returns a new list, leaving the original list unmodified. To "modify" a list: ====== set list [linsert $list 0 myvalue] ====== or, if the list is large make sure the list is unshared for `linsert` so that the internal [Tcl_Obj] can be re-used for the return value: ====== set list [linsert $list[set list {}] 0 myvalue] ====== The following proc makes it a little easier: ====== proc lipinsert {_list index args} { upvar $_list list set list [linsert [K $list [set list ""]] $index {*}$args] } > set A [list 1 2 3] 1 2 3 > lipinsert A 1 a b c 1 a b c 2 3 ====== ** Prepend ** [DKF] 2004-10-26: `linsert` can be used to create a `lprepend` command that is like [lappend] except that it puts the values at the start of the list: ====== proc lprepend {var args} { upvar 1 $var v lappend v ;# Used as a an "is a list" check and to do var creation set v [linsert $v[set v {}] 0 {*}$args] } ====== [Lars H]: Has the above any advantage in comparison with ====== set v [linsert $v [set v 0] {*}$args] ====== which is anyway slightly shorter? (OK, it can be used also where there isn't another argument to place the `set v ` in, but what about those cases where an alternative exists? Is the idea of the example to establish a new idiom?) [PYK] 2014-02-09: [Lars H] was spot-on back in 2004. A new idiom has indeed been established. ** Append ** `[linsert]` can be used to append words to a list. In contrast with `[lappend]`, the list must already exist. ** Unshared pure list ** [AMG]: `linsert` always returns an unshared pure list. This fact may be helpful for performance measuring, as I recently showed on the [Additional list functions] page. Just give your list-to-be as the first argument, any valid index (e.g. 0) as the second, and no further arguments. (I'm not sure if it's always, always pure, i.e. lacking in string representation, but it was when I tested it earlier today.) ** Documentation Bug: end-relative index ** [http://sourceforge.net/tracker/?func=detail&aid=3045123&group_id=10894&atid=110894%|%This documentation bug], reported by [amg], [http://tcl.cvs.sourceforge.net/viewvc/tcl/tcl/doc/linsert.n?r1=1.17&r2=1.18%|%was fixed in 2010]. [AMG]: According to the man page, "`linsert` produces a new list from ''list'' by inserting all of the ''word'' arguments just before the ''index''’th word of ''list''." When doing '''end'''-relative indexing, this definition doesn't match the actual behavior. To explain how ''index'' is interpreted, the `linsert` man page refers to the `[string index]` man page, which says that '''end''' indicates the last word. From this I expect that '''`linsert {0 1 2} end x`''' will return `0 1 x 2`, the result of inserting `x` just before the '''end''' word of the list, which is '''2'''. However, it actually returns '''{0 1 2 x}''', so when doing '''end'''-relative indexing it inserts the new words ''just after'' the indicated index. An alternative, more plausible explanation is that it inserts the new words such that the first or last of the inserted words will occupy the indicated index. Please see my related comments on the [lreplace] page. ** See also ** [list]: contains links to all the other list commands <> Command | Tcl syntax | Arts and crafts of Tcl-Tk programming