Tcl Anonymous Functions
A Purely theoretical question on Tcl.
Following this question I was thinking on what would be the best way to implement anonymous functions in Tcl.
The end result should be allowing a developer to pass a full proc as an argument 开发者_运维技巧to anohter proc:
do_something $data {proc {} {input} {
puts $input;
}};
which would be similar to javascript's
do_something(data, function (input) {
alert(input);
});
now, naturally this will not work OOTB. I was thinking on something of this sort:
proc do_something {data anon_function} {
anon_run $anon_function $data
}
proc anon_run {proc args} {
set rand proc_[clock clicks];
set script [lreplace $proc 1 1 $rand];
uplevel 1 $script;
uplevel 1 [concat $rand $args];
uplevel 1 rename $rand {}; //delete the created proc
}
This works. But I was hoping to get suggestions for a better pattern then this, as it's not very elegant and not really using cool Tcl features. Mostly I'd like to get rid of manually calling anon_run
.
In Tcl 8.5, you can use the apply
command.
proc do_something {data anon_function} {
apply $anon_function $data
}
do_something $data {{input} {
puts $input
}}
Of course, if you're structuring your callbacks as command prefixes (recommended!) then you can do this:
proc lambda {arguments body} {
# We'll do this properly and include the optional namespace
set ns [uplevel 1 namespace current]
return [list ::apply [list $arguments $body $ns]]
}
proc do_something {data command} {
{*}$command $data
}
do_something $data [lambda {input} {
puts $input
}]
If you're using 8.4 or before, you need the code from the Tcler's Wiki as a substitute, but be aware that those solutions are only semantically equivalent (at best); they're not performance-equivalent.
精彩评论