lindex forward compatibility

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 useful stuff to 8.3 (caveat emptor!)

Here is an implementation for pre-Tcl8.4 that supports the multiple index extension. It was written for clarity and simplicity so there is bound to be room for performance improvements if anyone thinks it's really necessary.

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  } {
     # the code below goes here
 }

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
 }

See Also: lset forward compatibility, sugar for Tcl/Tk 8.3