Updated 2012-05-27 20:24:51 by RLE

Arjen Markus (8 may 2007) Some examples of Maple [1] code inspired me to consider the procedures below. The idea is simple: Suppose you want to compute a series:
```            n      i i
f(x) = Sum (-1) x /(i+1)**2
i=0```

You could write a procedure like this:
```    proc f {x n} {
set sum 0.0
for { set i 0 } { \$i <= \$n } { incr i } {
set sum [expr {\$sum + pow(-\$x,\$i)/((\$i+1)*(\$i+1))}]
}
return \$sum
}```

but in a mathematical application like Maple, it makes more sense to provide a command that takes care of the details:
`    f = series(n, i->(-x)^i/i^2);`

(or something similar, I am not familiar with Maple, just saw some code fragments in an article)

The question arises: can we do that in Tcl too?

Well, that is easy (except for a few nasty details, as using a private namespace and a local variable with an uncommon name):
``` namespace eval ::Maple {
variable count 0
namespace eval v {
}
}

# series --
#     Define a new function that evaluates a series
#
# Arguments:
#     var          Names of the variables that holds the arguments
#     number       number of terms
#     idx          Index variable
#     expression   Expression defining the terms
#
# Result:
#     Name of a new procedure
#
proc ::Maple::series {var number idx expression} {
variable count

set procname ::Maple::v::series_\$count
incr count

set numbern [lindex \$number 0]
puts "numbern  =\$numbern"

proc \$procname [list \$var \$number] [string map \
[list VAR \$var IDX \$idx NUMBER \$numbern EXPR \$expression] {
set _sum_ 0.0
for { set IDX 0 } { \$IDX <= \$NUMBER } { incr IDX } {
set _sum_ [expr {\$_sum_ + EXPR}]
}
return \$_sum_
}]

return \$procname
}```

Now let us try it:
``` #
# The direct definition
#
proc fdir {x {n 100}} {
set sum 0.0
for { set i 0 } { \$i <= \$n } { incr i } {
set sum [expr {\$sum + pow(-\$x,\$i)/((\$i+1)*(\$i+1))}]
}
return \$sum
}

set f [::Maple::series x {n 100} i {pow(-\$x,\$i)/((\$i+1)*(\$i+1))}]

set x 0.0
while { \$x < 0.99 } {
puts "\$x: [\$f \$x] - [fdir \$x]"
set x [expr {\$x + 0.05}]
}```

I leave it as an exercise to expand this little package to other mathematical objects, such as matrices, vectors or definite integrals