if { 0 } { [Arjen Markus] (18 february 2004) Several languages, among which Fortran 90, have array operations, to use Fortran 90 syntax: real, dimension(1:100) :: a, b, c b = 1.0 do i = 1,size(a) a(i) = i enddo c= b / a would fill the array '''b''' with the value 1.0, in the do-loop each element of '''a''' is given a value (otherwise the last assignment is pretty dull) and each element of the array '''c''' is assigned the reciprocal value of the corresponding element of '''a'''. In other words: arrays need not be manipulated only through do-loops (or for-loops, if you like). This intrigued me: can we get the same thing into Tcl? The answer is obvious: yes! The script below does very little error handling and it is currently limited to one-dimensional arrays (i.e. Tcl lists of simple numbers) only. But it is just a proof of concept :) ---- Note that [array]s here are not Tcl's hash tables, but numerically indexed collections - fow which one best uses [list]s in Tcl. ---- } # numarray.tcl -- # Array operations on lists of numbers # proc merge { list1 list2 } { set result {} foreach e1 $list1 e2 $list2 { lappend result $e1 $e2 } return $result } proc numrange { varname vmin vmax vstep } { upvar $varname var if { $vmax < $vmin } { return -code error "Minimum must be smaller than maximum" } if { $vstep <= 0.0 } { return -code error "Step must be positive" } set value $vmin set var {} while { $value < $vmax+0.5*$vstep } { lappend var $value set value [expr {$value+$vstep}] } } proc numset { varname expression } { upvar $varname var # # Replace the substrings "$var" by a corresponding # list value - if the variable is a list # set _length_ 1 while { [string first \$ $expression] >= 0 } { regexp {\$(\w+)} $expression ==> _v_ catch { upvar $_v_ $_v_ } if { [llength [set $_v_]] > 1 } { set _length_ [llength [set $_v_]] regsub {\$\w+} $expression "\[lindex \@$_v_ @_i_\]" expression } else { regsub {\$\w+} $expression "@$_v_" expression } } set expression [string map {@ $} $expression] set _result_ {} for { set _i_ 0 } { $_i_ < $_length_ } { incr _i_ } { lappend _result_ [expr $expression] } set var $_result_ } # # Simple test cases # catch { console show } numrange v 0.0 10.0 1.1 puts "v: $v" numset w {$v*$v} set p 1.0 numset v {$v+$w+$p} puts "w: $w" puts "v: $v" # # Now some graphics # package require Tk numrange phi 0.0 [expr {2.0*3.1415926}] [expr {0.02*3.1415926}] numset rad {1.0+cos($phi)} numset x {100 + 100 * $rad * cos($phi)} numset y {200 + 100 * $rad * sin($phi)} pack [canvas .c -bg white -width 400 -height 400] .c create line [merge $x $y] ---- [[ [Category Concept] | [Category Language] ]]