Posted to tcl by cgm at Fri Dec 05 17:54:50 GMT 2025view pretty

Arjen asked:
cgm, question about your [=] command. Since braces are not needed, what happens if you would  have a code fragment like:
		
		set sum 0
		foreach e $list {
		    set sum [= sum [string length $e]]
		}
		
		This gets compiled time and again, as the actual expression would change, wouldn't it, unlike the [expr] equivalent with braces?
=================================================================
Answer - See the four test procs below:

proc arjen_eq_comp {} {
    set list [lseq 10000]
    set sum 0
    foreach e $list {
        set sum [= sum + [string length $e]]
    }
    return $sum
}

proc arjen_eq_noncomp {} {
    set list [lseq 10000]
    set sum 0
    foreach e $list {
        set sum [= sum+[string length $e]]
    }
    return $sum
}

proc arjen_expr {} {
    set list [lseq 10000]
    set sum 0
    foreach e $list {
        set sum [expr {$sum + [string length $e]}]
    }
    return $sum
}

proc arjen_expr_unbraced {} {
    set list [lseq 10000]
    set sum 0
    foreach e $list {
        set sum [expr $sum + [string length $e]]
    }
    return $sum
}

Timings:

% timerate arjen_eq_comp
1998.69 µs/# 500 # 500.33 #/sec 999.347 net-ms
% timerate arjen_eq_noncomp
7791.25 µs/# 128 # 128.35 #/sec 997.280 net-ms
% timerate arjen_expr
1625.94 µs/# 615 # 615.03 #/sec 999.951 net-ms
% timerate arjen_expr_unbraced
10227.6 µs/# 97 # 97.775 #/sec 992.075 net-ms


When the [string length $e] command is given as a separate argument to =,
it does get compiled to code which is almost as fast as expr.
When it is not separated from the rest of the expression this is not possible
and = falls back to a slower implementation, but this is still faster than
unbraced expr.