TIP 323: Do Nothing Gracefully

Author:		Colin McCormack <[email protected]>
Author:		Don Porter <[email protected]>
Author:		Kevin B. Kenny <[email protected]>
State:		Final
Type:		Project
Vote:		Done
Created:	06-Aug-2008
Tcl-Version:	8.6


A number of Tcl's built-in commands currently raise errors when given arguments that would cause them to do nothing. This proposal asks that they instead simply do nothing gracefully.


With the introduction of {*} syntax in Tcl 8.5 and its ability to convert one original word into zero words when an empty list is expanded, scripts using the syntax are forced to check for the empty list when passing expanded arguments to a command taking variable numbers of arguments, but arbitrarily rejecting zero arguments. For example,

 variable {*}$dict

will currently fail if $dict has no entries. Letting no-ops simply be no-ops rather than errors greatly lightens the programming burden on callers. There may be some marginal performance benefits as well.

Furthermore, there is no sound reason to constrain the argument count of these commands to be positive when an argument count of zero has a natural interpretation as a no-op. There is an elegance in permitting a function to range coherently over the complete domain.


The syntax of the following commands shall be revised as described:

  1. file delete - accept zero pathnames.

  2. file mkdir - accept zero directories.

  3. global - accept zero variable names.

  4. glob - accept zero patterns, returning list of zero matching files (with -nocomplain) or "no matches" error.

  5. lassign - accept zero variable names. https://sourceforge.net/support/tracker.php?aid=1671880

  6. linsert - accept zero elements. https://sourceforge.net/support/tracker.php?aid=1672056

  7. lrepeat - accept both number = 0 and zero elements. https://sourceforge.net/support/tracker.php?aid=1671951

  8. my variable - accept zero variable names.

  9. namespace upvar - accept zero variable names.

  10. tcl::tm::path add - accept zero paths.

  11. tcl::tm::path remove - accept zero paths.

  12. variable - accept zero variable names. https://sourceforge.net/support/tracker.php?aid=1881284


The proposed changes convert errors into no-ops. There should be no compatibility concerns with those.


When an implementation patch is completed, it will be logged in the SF Tracker and noted here.


Some other candidates for this treatment are intentionally left out of this proposal where for various reasons their conversion is complicated in some way, or the benefits of conversion are not as clear cut. These other commands might still be revised in a similar way, but are left for other TIPs to accomplish it so that this TIP can focus only on the low-hanging fruit.

  1. after idle

  2. dict exists

  3. dict set d val (no key argument)

  4. dict unset d val (no key argument)

  5. dict update d script (no key varName arguments)

  6. eval

  7. expr

  8. file join

  9. interp eval

  10. namespace eval

  11. parray https://sourceforge.net/support/tracker.php?aid=1739221 This feature request is more about tolerating errors than about expanding acceptance over a complete input domain. Not in the spirit of this TIP.

  12. uplevel

  13. upvar - presence of the optional level argument makes this one messy.


Proposed changes to string first, string last, and string replace in earlier revisions of the TIP that were approved by the vote have been rescinded after testing during the implementation phase revealed greater than expected issues with the incompatibilities those changes introduced.


This document has been placed in the public domain.