Version 2 of let - a simpler sugar for expr

Updated 2005-12-10 16:53:44

Sarnold 2005-11-10 -- The purpose is to offer a simple let command that works very much like C assignements for basic computations. The goal is not to join the general thing, but rather to keep it simple for everyday work.

Here is how it works :

 % let a = 10
 10
 % let a = $a - 1
 9
 % puts $a
 9
 % let a *= 2
 18

Please note that arguments have to be distinct. You cannot write this:

 let a = $a+2

or this:

 let a= 3 * 4

Warning: You may encounter problems with precision on floating-point values. It is not designed for precision, as the following example shows:

 % let a = 1.0 / 3
 0.333333333333
 % let a *= 3
 0.999999999999
 % set x [expr {1.0/3}]
 0.333333333333
 % set x [expr {$x*3}]
 1.0

Here it is :

 proc let {varname assign args} {
     upvar $varname leftvalue
     if {[llength $args]==3} {
         # args look like : 1 + 3, $a - $b, $c / $d
         foreach {a op b} $args {break}
         set args [expr [string map [list a $a op $op b $b] {a op b}]]
     }
     if {[llength $args]==1} {
         switch -exact -- $assign {
             += {set leftvalue [expr {$leftvalue+$args}]}
             -= {set leftvalue [expr {$leftvalue-$args}]}
             *= {set leftvalue [expr {$leftvalue*$args}]}
             /= {set leftvalue [expr {$leftvalue/$args}]}
             %= {set leftvalue [expr {$leftvalue%$args}]}
             =  {set leftvalue $args}
             default {error "invalid syntax : second argument is not an assignment"}
         }
         return $leftvalue
     }
     if {[llength $args]==0} {
         error "invalid argument number, check you have not put arguments and operators together"
     }
     error "syntax error"
 }

Category Command | Category Syntax