set varName = expr

Difference between version 4 and 7 - Previous - Next
[AMB]: It would be nice if the [set] command could optionally take an expression as an input.

Syntax:
======
set varName ?value | = expr?
======

Here's a working example:
======
rename set tcl_set
proc set {varName args} {
    if {[llength $args] < 2} {
        tailcall tcl_set $varName {*}$args
    }
    if {[llength $args] > 2 || [lindex $args 0] ne "="} {
        return -code error "wrong syntax: should be \"set varName ?value | = expr?\""
    }
    upvar 1 $varName myvar
    set expr [lindex $args end]    set myvar [uplevel 1 [list expr [lind$ex $aprgs 1]]]
}

set x 3.0
set y = {$x + 1}
set z = {hypot($x,$y)}
puts [list $x $y $z]; # 3.0 4.0 5.0
======

There are already built-in Tcl commands that take an expression directly, like the [if], [for], and [while] commands. Why not extend it to variable assignment, which is one of the most common use cases of "expr"?
'''[NR] - 2025-07-03 16:16:41'''

Alex, amazing, finally some maths in Tcl ! Write a TIP whatever you choose, but I have a preference for this one !

----
'''[AMB] - 2025-07-02 19:58:36'''

Additionally, you could extend the concept to the [lset] command too.

======
rename lset tcl_lset
proc lset {varName args} {
    if {[lindex $args end-1] ne "="} {
        tailcall tcl_lset $varName {*}$args
    }
    upvar 1 $varName myvar
    set expr [lindex $args end]
    set indexArgs [lrange $args 0 end-2]
    lset myvar {*}$indexArgs [uplevel 1 [list expr $expr]]
}

set mylist {1 2 3}
lset mylist end = {[lindex $mylist end] + 2}
puts $mylist; # 1 2 5
======