[FM] https://core.tcl-lang.org/tips/doc/trunk/tip/759.md%|%TIP 759%|% is a proposition whose goal is to facilitate arithmetic calculations with Tcl. The prototype can be found at its dedicated https://core.tcl-lang.org/tcl/timeline?r=tip-759_tcl90%|%branch%|%
The features offered fall into three categories:
* Extensions to the expr language :
** An ability to assign values to variables ('''TIP 282 Assignment operator''')
** An ability to chain calculations ('''TIP 282 Separating operator''')
** Simplifying the definition of lists of numbers ('''Parentheses-comma list operator''')
** Recognizing arithmetic substitution ('''Arithmetic TOKEN''')
* More direct access from the command line ('''Arithmetic substitution''')
* An ability to define arithmetic scripts : ('''Arithmetic compilation''')
You can refer to the text of the TIP to see more details.
It came out during a very long discussion whith [AMB] in the page [https://wiki.tcl-lang.org/page/A+Better+way+to+do+calculations]. I have to thank Eric Taylor also ([ET]), who gave me great insights on the Tcl core code style.
**Examples **
* [Quaternion]
* [Quaternion made simple]
* [3D polyhedra with simple tk canvas] (adapted from)
----
'''[NR] - 2026-09-18 17:55:12'''
Hello Florent, I think the idea is interesting, especially for numerical and mathematical code. My main concern is more about readability.
Looking at the complete [3D polyhedra with simple tk canvas] example, I find that there is quite a lot of Tcl and mathematical syntax mixed together. With (...), \[(...)], \[foreach {()}], substitutions and regular Tcl scripts appearing within the same procedures, it can sometimes be difficult to tell at a glance where Tcl ends and the mathematical syntax begins.
I actually have a math package myself, so I know the problem you are trying to address. There are places in my own code where expressing mathematical operations in Tcl becomes quite cumbersome. For example, I have this line in one of my quaternion tests:
======
set q29 [[[[[[[[$q2 * $q2] * $q2] * $q2] * $q2] * $q2] * $q2] * $q2] * $q2]
======
This is quite extreme just to express repeated multiplication, and it is a good example of why I understand the motivation behind TIP 759.
Interestingly, I already have a ^ operator in my Quaternion package, so this particular example could simply be written as:
======
set q29 [$q2 ^ 9]
======
At the same time, I don’t really have a better solution myself, and I certainly wouldn’t have been able to come up with something like your approach.
I wonder if the concept might also work well as a separate package, perhaps with something like a ‘math::proc’ construct. This could provide a clearer boundary between regular Tcl code and the mathematical part, while still offering the benefits of the new syntax.
For example:
======
math::proc CrossProduct {x1 y1 z1 x2 y2 z2} {(
$y1*$z2 - $y2*$z1,
$z1*$x2 - $z2*$x1,
$x1*$y2 - $x2*$y1
)}
======
In a function like this, I actually wouldn’t want to have other Tcl commands mixed into the mathematical expression. I would prefer the whole body to clearly be “the mathematical part”, with the boundary to regular Tcl being explicit.
Of course, my opinion is just one perspective here. I can clearly see how enthusiastic you are about the idea, especially from the amount of existing Tcl code you have already transformed using the concept. That’s actually what made me look more closely at the result and think about how it feels in a larger, real-world example.
For me, the interesting question is perhaps less about whether the mathematical syntax is useful, and more about how clearly we can separate the two worlds. In the current examples, I feel there is quite a lot of mixing between Tcl and math.
And of course, I may simply have misunderstood the intent of the TIP. If so, I apologize in advance!
----
Hi [NR]. You understood pretty well the intent of the TIP. What you are explaining is true. We can mix command syntax in arithmetic syntax, and arithmetic syntax in command syntax. So we may shift from one syntax to another frequently. It can be disturbing. But '''Subscripts must be recognized''' in arithmetic syntax. If they were not, something as simple as retrieving an element of a list would become impossible.
======
# Arithmetic Syntax :
...
v = [lindex $L 0];
...
======
We have not choice : we must allow to cross the bounderies... So, if the TIP is accepted, there should be a "good practice" guideline. The number of nested levels should be minimized.
Something I found displeasant is when I have to use the arithmetic substitution again in a nested command script
======
# Arithmetic Syntax :
...
v = [lindex $L [($i*2)] ];
...
======
Maybe a solution would be to have a special mode of command parsing, when this command is parsed from a arithmetic script. Let's say, in this situation, `)` will be taken as a word terminator, and then a word like `(...)` would be parsed as an expression :
======
# Arithmetic Syntax :
...
v = [lindex $L ($i*2)];
...
======
A variant would be to ''reverse the parentheses''.
======
# Arithmetic Syntax :
...
v = [lindex $L )$i*2(];
r = [lrange $L )$i*2()$j+3(];
...
======
But what is working now, is to use '''variables''' to communicate between these two worlds.
======
# Arithmetic Syntax :
...
j = $i*2;
v = [lindex $L $j];
...
======
About the abondance of symboles like in `\[foreach ... {()}];`
First idea was to create a `Foreach` mathfunc, with a body in arithmetic syntax, we then would write : `Foreach("i",$L,{ ... });`
But this is slow (`uplevel`). We have to use comas, we to quote the arguments... There is no gain, finally.
So A new idea came to me : it should be possible to define "COMMAND" leaf lexem type and make expr to call Tcl_ParseCommand (but not nested ..), which would then make a parse... in command syntax till the next newline or semi-colon. Then we can write :
======
proc test {} {(
A = (1,2,3);
foreach i $A {(
...
)};
B = (4,5,6);
...
)}
======
It would be a lot more clear !
Of course the set of commands to be recognized like this should be in a limited number, mainly restricted to commands that control the flow (for, while, switch, if, foreach, lmap).
Would you prefer it like this ?
----
'''[NR] - 2026-09-19 08:12:20'''
Thanks, I think I understand the idea better now.
If I understand correctly, with your new approach the mathematical syntax remains the main context, and when the parser encounters one of the recognized Tcl commands, such as `foreach`, it switches temporarily to Tcl command syntax, then returns to the mathematical syntax afterwards.
So your example:
======
proc test {} {(
A = (1,2,3);
foreach i $A {(
...
)};
)}
======
would roughly mean:
* `{(` enters the mathematical syntax;
* `A = (1,2,3);` is a mathematical statement;
* `foreach i $A` is parsed as a Tcl command, and `{(` then switches back to mathematical syntax for its body;
* `)}` returns from the mathematical syntax to Tcl;
* `;` terminates the `foreach` command, and the parser then resumes the surrounding mathematical syntax;
* `)}` finally leaves the outer mathematical syntax.
Is that the intended interpretation?
<[FM]> : '''yes Sir !''' </[FM]>
There is one thing about the `;` that I am still wondering about. In Tcl, `;` already has a very specific meaning: it terminates a Tcl command, for example:
======
set x 1; set y 2
======
So if `;` is also used as the marker telling the math parser to resume after a Tcl command, what happens with multiple Tcl commands on the same line?
For example, would something like this be possible?
======
foreach i $A {( ... )}; set x 10; set y 20
======
<[FM]> Tcl_parseCommand will return at the terminator, which is ''';'''. So expr will get a TCL_TOKEN_SCRIPT containing "`foreach i $A {( ... )};`". After the semi-colon, we are back to expr syntax, so there will be an error like "invalid barewords set". You'll have to write :
======
foreach i $A {( ... )}; x=10; y=20
======
</[FM]>
And more generally, would a sequence of mathematical statements be allowed on the same line, or does the parser require a newline after each one?
<[FM]> TIP 759 introduce ";" as a separator. So you must separate instructions by ";". On the other end, newline has no meaning at all in expr.</[FM]>
I am also wondering about comments. Would normal Tcl comments still work in the Tcl parts, for example:
======
foreach i $A {(
# some Tcl comment
...
)};
======
Or would comments need special handling once the parser is inside the mathematical syntax?
<[FM]> comments were already implemented in expr. All they need is to be followed by a newline. So you can add coments, as the examples are showing it.</[FM]>
I ask because one thing I really like about Tcl is that newlines and semicolons are generally interchangeable as command separators, and comments can appear naturally in the code. I am curious how those existing Tcl rules would interact with this parser-switching mechanism.
One other thing I was wondering about with your new `COMMAND` lexeme idea: once we are already inside the arithmetic syntax, could the body of a recognized Tcl command use just parentheses instead of `{(` and `)}`?
For example:
======
proc test {} {(
A = (1,2,3);
foreach i $A (
...
);
)}
======
Would the parser be able to determine from the context that the `(` after `foreach i $A` starts the command body, while the parentheses in something like:
======
A = (1,2,3)
======
are part of the mathematical expression?
Or is there a parsing reason why the `{(` and `)}` would still be necessary?
<[FM]> the reason lay in the logic of the implementation. To compile it's body, the foreach command is calling the function Tcl_CompileScript. In this function, I made things so that if a script begins by ( and finish by ), then it will be compiled as an arithmetic expression. So we always have :
======
foreach i $L {
# command syntax
}
foreach i $L {(
# arithmetic syntax
)}
======
To implement what you ask :
======
proc test {} {(
A = (1,2,3);
foreach i $A (
...
);
)}
======
I would have to signal to Tcl_ParseCommand that it is parsing a command from expr. That should be possible with the ''nested'' parameter of this procedure. Then Tcl_ParseCommand would have to treat parentheses as braces, as a simple word. I'm sure it is quite possible. What i don't know is how this will interact with array syntax, which use parentheses also
</[FM]>
----
'''[NR] - 2026-09-19 13:57:09'''
Thanks again for the detailed explanations. I understand the implementation much better now.
There is one more thing I would like to clarify. Outside of a proc body or another command body, would the following forms also work with the current implementation?
======
set value [(1 + 2)]
======
<[FM]> this works </[FM]>
With the opening parenthesis on the following line:
======
set value [(
1 + 2
)]
======
<[FM]> this works. ParseExpr will parse till the closing paren., followed by the bracket. Newlines don't matter in expr </[FM]>
And, since `;` can be used to chain several arithmetic instructions, would this also work?
======
set value [(A = 1; B = 2; $A + $B)]
======
<[FM]> this works and returns `$A+$B`<<br>>
What you should know here : a trailling `;` will mute the expression. If you write :
======
set value [(A = 1; B = 2; $A + $B;)]
======
value is set to ""<<br>>
</[FM]>
And, in particular, would this multiline form work as well?
======
set value [
(
A = 1;
B = 2;
$A + $B
)
]
======
<[FM]> this '''won't''' work. The opening parenthesis must immediately follow an open bracket, and the closing parenthesis must be immediately followed by a close bracket.
You will get an error "unknown command '('"
</[FM]>
I am asking because I have seen similar expression-block constructs in other languages, where a parenthesized block can contain several statements and the value of the block is the value of its final expression.
I am mainly curious whether the last form is already possible with the current implementation, or whether the arithmetic parser requires the opening `(` to be immediately after the `[` in an arithmetic substitution.
<[FM]> Must be immediately after. The other way is doable, just have to add a loop on spaces to skip it. But i didn't want : If someone has a proc '(', he can shift it one space away from the bracket to use it</[FM]>
I also noticed that you use `{(...)}` for arithmetic bodies in cases such as `foreach` and `proc`, for example:
======
foreach i $A {(
...
)}
======
and:
======
proc test {} {(
...
)}
======
So I was wondering why the same idea is not used for a direct arithmetic block, for example:
======
set value {(
A = 1;
B = 2;
$A + $B
)}
======
I assume this may be related to the fact that braces have an established meaning in Tcl, particularly with respect to substitutions. Is that the reason you use `\[(...)]` for arithmetic substitution instead?
<[FM]> i have to speak about the internals of Tcl to answer... There is the parser, and there is the compiler.
The parser split a commands in words. Each word is the site of a set of substitutions (eventually empty) to produce one Tcl_Obj, collected in arrays which are then transmitted to commands. As the Tcl Parser takes words in braces like simple words, it doesn't make any substitution in it.
There is the compiler. It works only on already parsed strings. Some commands, like `foreach`, `proc`, `if`...etc are compiling some of there arguments (their body). I made in sure that, if this argument to be compiled is enclosed by parentheses, then it will be compiled as an expression, with arithmetic syntax (-> arithmetic compilation)
It turns out that the command `set` doesn't compile it's second argument. So the variable 'value' will get exactly the string that was written between the braces. To get this string substituted, you must use arithmetic substitution, aka : `\[(...)]`, so that the parser knows what it has to do.
</[FM]>----
'''[NR] - 2026-09-19 15:58:27'''
Thanks for the clarifications. I understand the TIP much better now, as well as the way you rewrote the [3D polyhedra with simple tk canvas] example.