expr* arg ?arg arg ...?
expr* evaluates each of its arguments with expr and returns the list of results.
expr* with a single argument yields the same result as expr with a single argument.
proc expr* args {lmap e $args {uplevel 1 [list expr $e]}}With tailcall:
proc expr* args {tailcall lmap ___e $args {expr $___e}}Implementations by dkf. Idea offered by LEG as one of the responses to the perennial expr discussion in 2023.
expr* differs from expr by its interface. expr concats it's arguments and evaluates the result in it's own little language. This can lead to unwanted results via double substitution. For standard usage and beginners it is recommended to always brace your expr-essions, resulting in general usage of a single argument for expr.
expr* requires each expression to be braced or quoted anyway.
Several quests and TIPs evolve around the perceived unhandyness of expr in certain situations. I contend that some of them can be helped by expr*'s different interface.
Example, taken from the chat: canvas operations involve specification of coordinate lists:
.canvas create rectangle [expr {$w-100}] [expr {$h-40}] [expr {$w+100}] [expr {$h+40}]With expr*:
.canvas create rectangle {*}[expr* {$w-100} {$h-40} {$w+100} {$h+40}]Note: the same with mathop:
.canvas create rectangle [- $w 100] [- $h 40] [+ $w 100] [+ $h 40]
AMB - 2025-07-02 20:43:49
In Expanding the Expansion Prefix, I suggest that the prefix {=} is added, which processes multiple expressions that are comma-separated, like how arguments are processed in math functions, and automatically expands the arguments like the {*} prefix.
Then, the canvas example provided here could be cleaned up even further:
.canvas create rectangle {=}{$w-100, $h-40, $w+100, $h+40}Edit: Alternatively, the prefix {c} could be used to emphasize that it is comma-separated expressions. You could also use it for all arguments in a command if you prefer that syntax, but I see the main use-case to be when you have a lot of math expressions in your command inputs.
.canvas {c}{"create", "rectangle", $w-100, $h-40, $w+100, $h+40}Edit: While I would love to see the {c} prefix added to Tcl, it is something that would require a substantial effort on the source-code level. Further discussion in Expanding the Expansion Prefix led to discussion of introducing a simple math function called ::tcl::mathfunc::list, that would simply return the arguments.
This would allow you do to the following:
proc ::tcl::mathfunc::vec {args} {return $args}
.canvas create rectangle {*}[expr {vec($w-100, $h-40, $w+100, $h+40)}]You could take it a step further, by defining expr* as follows:
proc ::tcl::mathfunc::vec {args} {return $args}
proc ::expr* {args} {uplevel 1 "::expr {vec([join $args])}"}
.canvas create rectangle {*}[expr* {$w-100, $h-40, $w+100, $h+40}]I formalized it in a Tcl package called "exprstar ".