## Complex math with TOOT

Richard Suchenwirth 2005-03-25 - TOOT is "transparent OO for Tcl" - a "pure-value" approach, where a value (a listable string) like

` {Foo | bar grill}`

is interpreted to be of class Foo (so Foo's methods can be applied to it), with the "instance variable" values bar and ''grill'. (In fact, they aren't "variable" - values are immutable).

The "|" as second element just identifies this as a TOOT value. "Transparent" means that a TOOT has nothing to hide - its state is fully visible in the string representation. For a "constructor", list is sufficient:

`set c [list Complex | \$real \$imag]`

but a few keystrokes add "constructor sugar", so you might as well call

`set c [Complex | \$real \$imag]`

No garbage collection is necessary: like all Tcl values, TOOT values just go away when nobody wants them any more (e.g. on return when associated with a local variable).

Methods are called as usual, with the method name (which can also look like "+") after the object, and then possibly more arguments. The example with the multiplication method named, evidently, "*" shows that the appearance of infix arithmetics comes as a by-product:

```set i {Complex | 0 1}         ;#-- imaginary unit i
\$i * \$i  ==> {Complex | -1 0} ;#-- such that i*i == -1```

Reinventing Complex math made simple, here's my experiments. Binary operators take one argument, which can be another Complex, or a real number x, which then gets "upgraded" to [Complex | \$x 0]. A single proc contains all methods for the Complex "class":

``` proc Complex {| r i {method ""} args} {
if {[llength \$args]==1} {
set operand [lindex \$args 0]
if [string is double -strict \$operand] {
set r2 \$operand; set i2 0
} else {foreach {Complex | r2 i2} \$operand break}
}
switch -- \$method {
""   {list Complex | \$r \$i ;#--constructor sugar}
real {set r}
imag {set i}
abs  {expr {hypot(\$i,\$r)}}
arg  {expr {atan2(\$i,\$r)}}
format {expr {\$i ? "\$r+i*\$i" : \$r}}
==   {expr {\$r==\$r2 && \$i==\$i2}}
!=   {expr {!(\$r==\$r2 && \$i==\$i2)}}
+    {Complex | [+ \$r \$r2] [+ \$i \$i2]}
-    {Complex | [- \$r \$r2] [- \$i \$i2]}
*    {Complex | [expr {\$r*\$r2 - \$i*\$i2}] \
[expr {\$r*\$i2 + \$r2*\$i}]
}
/    {set div [expr {\$r2*\$r2 + \$i2*\$i2}]
Complex | [expr {(\$r*\$r2 + \$i*\$i2) / \$div}] \
[expr {(\$r2*\$i - \$r*\$i2) / \$div}]
}
default {error "unknown method \$method"}
}
}
#-- For convenience, [expr] operators are exported as commands:
foreach op {+ - * /} {proc \$op {a b} "expr {\\$a \$op \\$b}"}```

To make this flavor of TOOT work, we let unknown know it shall auto-expand the first word if its second element is "|" :

``` proc know what {proc unknown args \$what\n[info body unknown]}
know {
if {[lindex \$args 0 1] eq "|"} {
return [uplevel 1 [lindex \$args 0] [lrange \$args 1 end]]
}
}
#-- This little tester reports the unexpected
proc ? {cmd expected} {
catch {uplevel 1 \$cmd} res
if {\$res ne \$expected} {puts "\$cmd -> \$res, expected \$expected"}
}
#-- The test suite passes silently when all goes well:
set i {Complex | 0 1}     ;# flat value
set b [Complex | 3 4] ;# constructor sugar
? {\$b format} {3+i*4}
? {\$b abs}     5.0
? {\$b real}    3
? {\$b imag}    4
? {\$i == \$i}   1
? {\$i == \$b}   0
? {\$i != \$b}   1
? {\$i + \$b}    {Complex | 3 5}
? {\$b - \$i}    {Complex | 3 3}
? {\$b + 1}     {Complex | 4 4}
? {\$i * \$i}    {Complex | -1 0} ;# i**2 == -1?
? {[\$i * \$i] format} -1
set r   [\$b abs]
set phi [\$b arg]
? {[[Complex | [expr cos(\$phi)] [expr sin(\$phi)]] * \$r] == \$b} 1
? {\$b / 0}               "divide by zero"
? {\$b / {Complex | 0 0}} "divide by zero"
? {\$a foo}               "unknown method foo"```

See also Straightforward implementation of complex numbers which is included in recent Tcllib

 Category Object Orientation Arts and Crafts of Tcl-Tk Programming