Author: Florent Merlet <[email protected]>
State: Draft
Type: Project
Vote: Pending
Created: 30-Oct-2026
Tcl-Version: 9.2
Tcl-Branch: tip-759g-tcl91-expand-in-expr
Keywords: expr, expansion, list, function
Post-History:
Abstract
The argument expansion prefix {*} of TIP 293 becomes available in
expressions, before an argument of a function or an element of a list:
expr {max({*}$values)}
expr {hypot({*}$point)}
expr {(0, {*}$row, 0)} ;# a list, see the lists TIP
expr {{*}$a, {*}$b} ;# a list outside of parens
It is the seventh part of TIP 759 (expression syntax in Tcl). Expansion in function arguments needs no other TIP; expansion in lists depends on the lists TIP.
Rationale
Functions such as max, min or hypot, and user functions defined in
tcl::mathfunc with args, take a variable number of arguments. Today, to
call one on the elements of a list, one leaves the expression:
tcl::mathfunc::max {*}$values
expr {max([join $values ,])} ;# wrong, but often seen
With {*}, the expression reads as the command would, with the same prefix
and the same meaning. With the lists TIP, it also gives concatenation inside
an expression, ({*}$a, {*}$b), as [list {*}$a {*}$b].
Specification
In an expression,
{*}immediately followed by the start of an operand (a number,$,[,{,", a name, or() is the expansion prefix. It is allowed only before an argument of a function call or before an element of a list (an operand separated from the others by commas in parentheses that make a list, or by commas outside of any parentheses, which make the whole expression a list:{*}$a, {*}$b).The value of the operand is taken as a list; each element becomes a separate argument of the function, or a separate element of the list, at that position. An empty list adds nothing:
({*}{}, 1)is1, andmax({*}{})fails withnot enough arguments for math function "max".The prefix applies to one operand, not to an expression: in
max(1, {*}$L + 1),{*}is an error.Anywhere else (
expr {{*}$L},({*}$L)without a comma, the target of an assignment), the prefix is an error:{*} is allowed only for the arguments of a function or the elements of a list, error codeTCL PARSE EXPR EXPAND.Tcl_ParseExpr gives a
TCL_TOKEN_OPERATORtoken{*}with one operand, as for a unary operator.
Compatibility
Today {*} in an expression is the braced string *. When it is followed
by white space or an operator ({*} eq "*", {*}eq "*"), it keeps that
meaning. When it is followed directly by an operand, the expression was an
error (missing operator); it now has a meaning. No valid expression
changes meaning.
Implementation
Patch 0007-TIP-759-7-7-argument-expansion-in-expressions.patch:
tclCompExpr.c: a new unary lexemeEXPAND, recognized byParseLexemewhen{*}is followed by the start of an operand;ExpandPlacesValidchecks the positions once the tree is built. A call or a list that contains an expanded operand is compiled withexpandStart,expandStkTopandinvokeExpanded, as a command with{*}(a list calls::list), also for a list outside of parentheses (START_LIST). Without{*}, the bytecode is unchanged.tclCompile.c:TclStartExpanding, a module-scope wrapper ofStartExpanding.- Tests:
tests/exprExpand.test. Documentation:expr.n.
Future work
With tuple assignment (fifth part), the prefix could mark the rest of a
tuple: (first, {*}rest) = $L would set rest to the remaining elements,
as lassign does. It is an error today, so it can be added later.
Copyright
This document has been placed in the public domain.
