Version 13 of Simple implementation of Real Number

Updated 2007-02-05 02:10:10

Suggested by Numerical Analysis in Tcl; how to implement numerical statements such as a=b*c. I have removed my own prodding code which has satisfactorily produced some good responses to show implementations that already exist such as Gadgets.

slebetman Notwithstanding the fact that a real number in mathematics means something completely different (see Computers and real numbers) I've implemented this concept a bit more intuitively (and if you consider lines of code, also more simply). Unlike the implementation (removed by original author), my variables exist as both variables and commands. Personally I would call it a C-like syntax for numbers:

GWM yes real numbers in maths are different but as this is a numerical analysis related item, real means whatever a compiled computer program uses as a real (especially the C language) - as used in numerical analysis. I agree that C-like syntax is a more appropriate term. I like this implementation by slebetman as it is simple, and allows local variables and recursion.

    proc cleanupVar {name1 name2 op} {
        if {![uplevel 1 [list info exists $name1]]} {
            rename $name1 {}
        }
    }

    proc var {name {= =} args} {
        upvar 1 $name x
        if {[llength $args]} {
            set x [expr $args]
        } else {
            set x {}
        }
        proc $name args "
            upvar 1 $name $name
            if {\[llength \$args\]} {
                set $name \[expr \[lrange \$args 1 end\]\]
            } else {
                return \$[set name]
            }
        "
        uplevel 1 [list trace add variable $name unset cleanupVar]
    }

The following is an example of how to use var:

    proc test {} {
        var x
        var y = 10

        x = $y*2

        return $x
    }
    puts [test]

Another feature is that the variables actually exists in local scope even though their associated commands exists in global scope. This means that the variables can be used recursively:

    proc recursiveTest {x} {
        var y = $x - 1

        if {$y > 0} {
            recursiveTest $y
        }
        puts $y
    }
    recursiveTest 10

should output the numbers 0 to 9. Another test:

    proc test2 {} {
        var x = 10
        puts "this x belongs to test2 = $x"
    }

    proc test3 {} {
        var x = 100
        test2
        puts "this x belongs to test3 = $x"
    }

    test3

output:

  this x belongs to test2 = 10
  this x belongs to test3 = 100

Another, even more powerful, implementation of this concept is Let unknown know.

Larry Smith All of this would be so much tidier if it were possible to declare local procs.


slebetman 5 Feb 2007: Modified the code to not delete the associated proc unless there are no more variables which may need the proc. The following is a test which the old version failed but the new version handles correctly:

    proc test2 {} {
        var x = 10
        puts "this x belongs to test2 = $x"
        # the old implementation would have deleted the
        # proc "x" at the end of this proc.
    }

    proc test3 {} {
        var x
        test2
        x = 100 ;# old implementation fails here!
        puts "this x belongs to test3 = $x"
    }

    test3

Category Core , Category Example , Category Mathematics