TIP #408: Allow Any Command for expr Functions
_____________________________________________________________________________
TIP:	408
Title:	Allow Any Command for expr Functions
Version:	$Revision: 1.1 $
Authors:	Brian Griffin <brian_griffin@mentor.com>
State:	Draft
Type:	Project
Tcl-Version:	8.7
Vote:	Pending
Created:	Fri Aug 17 00:00:00 UTC 2012
Abstract
Proposed expansion of what constitutes a function in an expr expression.
Rationale: Nested expr Calls
The expr command in Tcl is the only way to perform math and comparison operations. Tcl's variable and command substitution rules allow for great flexibility, although the syntax does not lead to great readability, especially due to the ordering imposed on substitutions. For example, in the expression:
 expr [lindex $data $start] > 4
the command substitution ([[...]]) is performed before the expression can be parsed for evaluation, and, in order for the command substitution to be parsed, the variable substitution ($) must be performed. The consequences of this ordering means that arguments to commands cannot themselves be expressions unless the argument is itself a command substitution involving expr. This means, for example, that to compute an index value, expr must be recursively called:
 expr [lindex $data [expr $start + 2]] > 4
However, when using a math function, the command substitution ordering does not apply since the function is part of the expression syntax:
 expr pow($x + 2, 2)
It seems reasonable and useful if any Tcl command can be called using function syntax:
 expr lindex($data, $start + 2) > 4
The common command substitution pattern has lead many developers to end up writing things like:
 if [expr $a+$b] > 7 ...
In hindsight, such statements look ridiculous, but it works and it follows the same pattern as the lindex case above. If subexpressions could be evaluated directly by the enclosing expr operations, this would greatly simplify the overall expression and make it more readable and thereby more maintainable, and hopefully, less error prone.
The goal here is to reduce the instances of recursive expr calls in an expression. It seems overly complex and confusing to read, and to have to use command substitution syntax inside what is already an expr operation.
Proposed Changes
The proposal is to simply apply normal Tcl command resolution rules to expr functions. The one caveat is that tcl::mathfunc namespace is always searched first.
I see this as a continuation to [232].
Rejected Alternatives
This can already be accomplished today by creating alias functions in the tcl::mathfunc namespace, but this mechanism is awkward in that:
1.	It must be defined beforehand for the set of commands used or intended to be used in expressions,
2.	For OO and namespace code, some specialized duplication is also required, and
3.	It can lead to confusion when it's not clear why some commands work as functions and others don't.
Proof of Concept
(Thanks and credit to Frédéric Bonnet)
A quick & dirty proof of concept with unknown handlers:
proc mathproc cmd args 
    if [namespace qualifiers $cmd] eq "tcl::mathfunc" 
        return [uplevel [list [namespace tail $cmd]] $args]
    
    uplevel [list ::unknown $cmd] $args

namespace unknown mathproc

set l [expr list(1,2,3)]
=> 1 2 3

expr lindex($l,2)
=> 3

expr expr(join($l,"+"))
=> 6
Reference Implementation
None currently
Copyright
Copyright (c) 2012 by GriffinTk
This document is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License [http://creativecommons.org/licenses/by-sa/3.0/deed.en_US].
_____________________________________________________________________________
Colophon
TIP AutoGenerator - written by Donal K. Fellows