This is not necessarily the current version of this TIP.
| TIP: | 33 |
| Title: | Add 'lset' command to assign to list elements. |
| Version: | $Revision: 1.7 $ |
| Author: | Kevin Kenny <kennykb at acm dot org> |
| State: | Draft |
| Type: | Project |
| Tcl-Version: | 8.4 |
| Vote: | Pending |
| Created: | Tuesday, 15 May 2001 |
| Discussions To: | news:comp.lang.tcl |
| Discussions To: | mailto:kennykb@acm.org |
Most popular programming languages provide some sort of indexed array construct, where array subscripts are integers. Tcl's lists are implemented internally as indexed arrays, but it is difficult to use them as such because there is no convenient way to assign to individual elements. This TIP proposes a new command, lset, to rectify this limitation.
TIP: 33 Title: Add 'lset' command to assign to list elements. Version: $Revision: 1.7 $i as a list of indices, and shimmers it to the list. This discards the internal rep, parses the string rep into a list, and then reconverts its first element to an integer.
OK, now the 'lset' is happy, and no further shimmering occurs...
... until we get to the {incr i}. Now we go back to the string rep once again, shimmer it to an integer (yet another call to strtol), and invalidate the string rep because we've incremented the integer.
Now we get back into the [lindex] once again, and need a list rep. This time, we have to format the integer as a string, parse it as a list, take the object representing element 0, and reparse that as an integer.
This sequence has converted the integer to and from a string, and performed four calls to ckalloc, but resulted in the same integer that we started with!
It is possible for a sufficiently smart compromise implementation to avoid all this shimmering. In the case where objc==4, the lset command must:
Test whether objv[ 2 ] designates an object whose internal representation holds an integer. If so, simply use it as an index.
Test whether objv[ 2 ] designates an object whose internal representation holds a list. If so, perform the recursive extraction of indexed elements from sublists described above.
Form the string representation of objv[ 2 ] and test whether it is end or end- followed by an integer. If so, use it as an index.
Attempt to coerce objv[ 2 ] to an integer; if successful, use the result as an integer.
Attempt to coerce objv[ 2 ] to a list; if successful, use the result as an index list.
Report a malformed index argument; the indexList parameter is not a well-formed list.
This logic handles all the cases of singleton lists transparently; it is effectively a simple-minded type inference that optimizes away needless conversions. With it in place, none of the lset examples shown in this TIP will suffer from type shimmering.
In the event that the related TIP #22 is approved, the logic for parsing an index list will likely be combined with that used in the lindex command.
Bytecoding variadic commands like lset presents some interesting technical challenges; a discussion in progress on the Tcl'ers Wiki (http://purl.org/thecliff/tcl/wiki/1604) is recording the design decisions being made for bytecoding lset so that they can be applied to similar commands in the future.
This TIP has undergone several revisions by the original author. The most significant was made on 20 May 2001, where the syntax was revised to allow for either several indices inline on the command line or a list of indices.
This document has been placed in the public domain.
This is not necessarily the current version of this TIP.