Guarded proc

Richard Suchenwirth 1999-07-19 - In more complex Tcl software, it may happen that a procedure is defined twice with different body and/or args, causing hard-to-track errors. The Tcl command 'proc' itself doesn't complain if it is called with an existing name. Here's one way to add this functionality. Early in your code, you overload the proc command like this:

  rename proc _proc
  _proc proc {name args body} {
    if {[info commands $name]!=""} {
        puts stderr "warning: [info script] redefines $name"
    }
    _proc $name $args $body   
  }

From the time that is sourced, any attempt to override a proc name will be reported to stderr (on Win-wish, it would show on the console in red). You may make it really strict by adding an "exit" after the "puts stderr ...", or throw an error.

Known feature: proc names with wildcards will run into this trap, e.g.

   proc * args {expr [join $args *]*1}

will always lead to a complaint because "*" fits any proc name. Fix (some regsub magic on 'name') left as an exercise.


Tcl/Tk is a wish come true ;-)


NEM 2008-01-08: The title of this page also brings to mind guarded function clauses in various languages. For instance, in Haskell you see code like:

max x y
    | x >= y    = x
    | otherwise = y

Here the '|' character introduces a guard clause and can be read as "when". We can mimick this in Tcl easily enough:

proc | args {
    if {[uplevel 1 [lrange $args 0 end-2]]} {
        return -code return [uplevel 1 [list expr [lindex $args end]]]
    }
}
proc otherwise {} { return 1 }

With this we can then write code like:

proc max {x y} {
    | >= $x $y  = $x
    | otherwise = $y
}
proc >= {a b} { expr {$a >= $b} }