How do you provide default arguments to a Tcl procedure that are evaluated at call-time?
Here’s an example of what I’ve tried:
> tclsh
% proc test { {def [expr 4 + 3]} } { puts $def }
too many fields in argument specifier "def [expr 4 + 3]"
% proc test { {def {[expr 4 + 3]}} } {puts $def}
% test
[expr 4 + 3]
% test 5
5
% proc test { {def {[expr 4 + 3]}} } {puts [$def]}
% test
invalid command name "[expr 4 + 3]"
% proc test { {def {[expr 4 + 3]}} } {puts [eval $def]}
% test
invalid command name "7"
The example is just to simplify code. Of course in this simple example one would just use {def 7} to set the proc’s default value.
However, the goal is to be able to call some more complex function that delivers a good default value whenever the procedure test is being called. So the defaults can vary.
My current solution is to default to the empty string and check that:
% proc test { {def {}} } { if {$def == {}} { set def [expr 4 + 3] } ; puts $def }
% test
7
% test 5
5
However I consider this not elegant enough: There ought to be a way to put declarations where they belong: In the header.
Also, possibly, the empty string might be a perfectly fine value given by a caller that is not to be replaced with the default call.
Another workaround could be to just use args as a parameter and then inspect that one. But that provides even less explicit declarative style.
Any ideas how I can incorporate the eval into the declarative proc header?
(I’m on Tcl8.4 with no way to upgrade because of use in a commercial tool environment. But for the sake of this site I’d also encourage answers for more modern tcl versions)
What about this one (which is just slightly different from your tries):