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 2007-08-17: This is known as "memoization" - there are several Wiki pages on the subject.AMG: Here's a link: memoizingwdb: Thanks for the hint ... before writing this page, I searched "delayed", "freeze" etc. Memoizing ... ok, I've learned a new word!

