Author: Jan Nijtmans <jan.nijtmans@gmail.com>
State: Draft
Type: Project
Created: 8-June-2020
Post-History:
Keywords: Tcl index
Tcl-Version: 8.7
Tcl-Branch: strict-index
Abstract
Various commands handle errors in "index" values differently. This TIP attempts to treat the different uses of index values (in both Tcl and Tk) to a more uniform way.
Rationale
Some examples (Tk):
$ wish8.6 % listbox .l % menu .m % .l index 0 0 % .l index none bad listbox index "none": must be active, anchor, end, @x,y, or a number % .m index none none % .m index 0 none % .m index foo bad menu entry index "foo"
More examples (Tcl):
$ tclsh8.6 % lreplace {a b c} -1 -1 d d a b c % lreplace {a b c} -2 -2 d d a b c % set x {a b c} a b c % lset x 0 d d b c % lset x -1 d list index out of range
Changing any of the above examples to give a different answer is not possible in the Tcl 8.x timeline,
as it could cause applications to break unexpectedly. But this examples make it clear that the
responses -1
and none
are used often to mean the same thing. For Tcl 9 more can be done, but
more investigation is needed to determine whether none
or maybe the empty string would be a
better fit here. Also, whether a command gives an error-message on an invalid index or bails out
cannot be changed in the Tcl 8.x timeline.
Since they are often causes of bugs, this TIP makes the step to deprecate
the use of indices < -1
and > end+1
. Such indices normally result from
code loops which don't properly check for the end condition. Therefore,
those indices will no longer be valid indices in Tcl 9.
It would be tempting to change Tcl 9 such that none
or the empty string is used
as return value in stead of -1
. That change is not made yet in this TIP,
more experimenting is needed to determine the impact that would have.
Specification
- The C function
Tcl_GetIntForIndex()
will get an additionalflags
parameter, which holds any combination of 3 possible flags (could be extended further in the future):TCL_INDEX_ERROR
: Handle-2
(and lower) andend+2
(and higher) as invalid index.TCL_INDEX_NOMIN
: Handle-1
as invalid index (whenTCL_INDEX_ERROR
is set), or as the same as index "0".TCL_INDEX_NOMAX
: Handleend+1
as invalid index (whenTCL_INDEX_ERROR
is set), or as the same as index "end". The default flag value 0, will behave as-is now, accepting all forms as valid. Starting with Tcl 9.0, all internalTcl_GetIntForIndex()
calls will at least supply theTCL_INDEX_ERROR
flag value to this function.
- Values
none
and the empty string are now valid indices, representing "just before the first". Commands that accept either a single index or a list of indices will handle the empty string as empty list, not as a single index. - New functions "string is none" and "string is index".
- Starting with Tcl 9.0, integers <
-1
and formsend+x
where x > 1 will no longer be valid indexes any more. - For Tk, start accepting all those same values as indices for entries, listboxes, menus .....
and also for button and menu-related
-underline
options. A newTK_OPTION_INDEX
option is implemented, which is almost the same asTK_OPTION_INT
, but in stead of only integers, accepts all index forms as well. See:widgets indices enhancement
Compatibility
For Tcl 8.7 this is almost 100% compatible, previous error-situations become valid now:
Index value none
can now be used in place of -1
, just as the empty string "".
Since, starting with Tcl 9.0, some index forms are no longer valid, this is a potential
incompatibility. Indices like -2
and end+2
can no longer be used in scripts: they
will immediately result in an "index out of range" error, in stead of being silently ignore.
Implementation
See the strict-index
branch.
For Tk, see the strict-index
branch.
Copyright
This document has been placed in the public domain.