This really simple procedure is intended for long-running calculations: array set delayed {} proc calcOnlyOnce args { set args1\ [concat [uplevel 1 namespace origin [lindex $args 0]] [lrange $args 1 end]] variable delayed if {[info exists delayed($args1)]} then { set delayed($args1) } else { set delayed($args1) [uplevel 1 $args] } } Example usage -- this proc is slow: proc fib n { if {$n <= 1} then { return 1 } else { set n1 [expr {$n-1}] set n2 [expr {$n-2}] expr {[fib $n1] + [fib $n2]} } } Now test: % time {calcOnlyOnce fib 25} 1 246325 microseconds per iteration % time {calcOnlyOnce fib 25} 1 39 microseconds per iteration % The second call on same procedure was faster due to the fact that it was not re-calculated but "remembered" instead. ---- [AM] (17 august 2007) This is known as "memoization" - there are several Wiki pages on the subject.