TIP 266: Numbers are Commands

Login
Bounty program for improvements to Tcl and certain Tcl packages.
Author:         Kristoffer Lawson <setok@fishpool.com>
Author:         Michal Malecki <ethouris@gmail.com>
Author:         Wolf-Dieter Busch <wolf-dieter.busch@gmx.de>
Author:         Paul Nash <webscool@ihug.co.nz>
State:          Rejected
Type:           Project
Vote:           Done
Created:        11-Apr-2006
Post-History:   
Keywords:       Tcl,unknown,expression
Tcl-Version:    8.5

Abstract

This TIP describes a change to Tcl's command dispatch which would allow every number to act as a command.

Rationale

Maths in Tcl are continuously a stumbling block. The expr command is ugly and cumbersome. It adds a new C-like syntax within Tcl and easily makes lines less readable, especially with the most common use of simple arithmetic. In addition it is confusing to the programmer to have to remember there is a completely separate set of commands, or functions, which are only available to the expr command.

This proposal offers a clean solution which could eventually totally replace expr, yet offers few or no backward compatibility problems and fits in with the Tcl philosophy of "every piece of executable code is a command".

This addition is easy to build as a separate extension using the mechanisms provided by Tcl. However, this will not be widely used unless it is stamped as part of the language and part of its unique philosophy. In addition, implementations in the core can gain from many forms of optimisation that would not be possible with a normal extension.

There is an existing proposal for making operands into commands. That proposal is still a valid one, but the description in this TIP leads to syntax which will be more familiar to most programmers. It does not have operator precedence, which is a difference from normal mathematics, but one that should be easier to grasp than the reversed notation that operator commands offer. In fact, there are many claims which state operator precedence is a mistake anyway.

Specification

Every number that can be handled by Tcl is a command.

The format for number commands is:

number operation ?arg1 arg2 ...?

For example:

 8 * 5 + 2

The first argument must be an operator, and can be one of any specified for the expr command (+, -, *, /, ...)

Subsequent arguments can be either numbers or operators.

The command evaluates its arguments from left-to-right (no precedence) with the result of the left used as the operand for the next operation. e.g. to get 242 a simple addition can be made:

 200 + 42

If multiple numbers are given without operators between them, the last operator is used. e.g. for the result "42" the following can be used:

 20 + 10 10 2

To get "23", the following can be used:

 20 + 10 10 2 / 2 + 2

Normal Tcl brackets can be used for grouping purposes. e.g. the result "31337" can be reached with the following:

 62674 / [1 + 1]

Number commands act just like any other commands in Tcl. They can be nested with brackets, aliased, replaced and even removed. The only difference is that they do not appear in the list returned by info commands. However, any replacements made on them do.

Compatibility

Because of the ability to replace number-commands, there are no real backwards compatibility issues. There are very few, if any, extensions that make numbers into commands and any that do will still work with the only exception being software that would mix extensions that would depend on the functionality in this TIP and extensions that create their own commands which are only numbers. In any case, the author is not aware of any extensions that create commands in that manner.

The only other area where incompatibilities would arise would be if someone is using an unknown mechanism which creates similar functionality to the one presented here. These extensions do exist, but are mostly presented as brain-twisters instead of for serious use.

Additionally, Tcl does not and cannot guarantee that new commands will not appear in the global namespace. Indeed, every new release does this.

For these reasons, this proposal can be implemented with a minor version bump.

Implementation Discussion

The first natural step is to add a detection phase before the normal unknown mechanism. In fact, a prototype implementation can easily and trivially be built with Tcl's unknown command. The detection should work by checking if the unknown command is a number and if so, it will run the number command functionality. Otherwise, the normal Tcl chain of events is followed.

If the command is replaced, this number mechanism is never reached, as a normal command exists to handle the situation.

If the command is removed, a special flag should be set to specify that the number in question cannot be used as a command.

At a later date, further integration with the bytecode engine can be made. The details of such optimizations are outside the scope of this TIP.

Some may argue that it is not good to disable defining commands with numbers by users. For example, someone would like to "overload" 0 and 1 to use [!file exists $f] && { puts "File not found"; exit }. This also does not look like a good solution for 'expr' command; this will be still not the same as expressions in other languages (required spaces between operators etc.)

Alternative Approaches

Instead of allowing multiple number arguments to use the same operator, a requirement could be made that every other argument must be an operator and every other one an operand. This might make the specification somewhat clearer, but would mean a mathematical operation on a list would not be as easy.

Comments

This is a change to the "eleven rules", so please do not do it. It takes the possibility that I can do it myself by changing the procedure unknown.

Copyright

This document has been placed in the public domain.

History