开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜