Version 1 of lindex forward compatibility

Updated 2005-09-03 11:39:49

Originated by KMG 3-Sep-2005

For those of us who for various reasons cannot move up to 8.4, it's useful to:

  • have access to some of the enhancements
  • be able to write code that will be forward compatible and won't need rewriting to gain performance or syntax improvements when run on post-8.3 Tcl
  • have tools to help us back-port to useful stuff to 8.3 (caveat emptor!)

Here is an implementation for pre-Tcl8.4 that supports the multiple index extension. This implementation passes all of the reference test cases on the 8.4 help page for 'lindex'.

I tend to put it in a file lindex.tcl bracketed inside the following predicate:

 if { $tcl_version < 8.4  } {
 }

Here t'is:

 # Hide the default lindex command
 rename lindex _lindex

 # Define the new command
 proc lindex { theList args } {

     switch -exact [llength $args] {
         0 {
             # lindex l  (get l)
             return $theList
         }

         1 {
             # lindex l i        (get i'th element of l)
             # lindex l {}       (get l)
             # lindex l {i j k}  (get the k'th element of the j'th element of the i'th element of l)
             set indexList [_lindex $args 0]
             switch -exact [llength $indexList] {
                 0 {
                     # lindex l {}
                     return $theList
                 }

                 1 {
                     # lindex l i
                     # lindex l {i}
                     return [_lindex $theList $indexList]
                 }

                 default {
                     # lindex l {i j k}  (get the k'th element of the j'th element of the i'th element of l)
                     set index   [_lindex $indexList 0]
                     set subList [_lindex $theList $index]
                     return [lindex $subList [lrange $indexList 1 end]]
                 }
             }
         }

         default {
             # lindex l i j k
             set indexList $args
             set index   [_lindex $indexList 0]
             set subList [_lindex $theList $index]
             return [lindex $subList [lrange $indexList 1 end]]
         }
     }

     return $theList
 }