Tcl 匿名函数

发布于 2024-09-09 20:41:30 字数 868 浏览 3 评论 0原文

关于 Tcl 的纯理论问题。

这个问题之后,我正在思考什么是最好的在Tcl中实现匿名函数的方法。

最终结果应该是允许开发人员将完整的过程作为参数传递给另一个过程:

do_something $data {proc {} {input} {
    puts $input;
}};

这与现在的 javascript 类似

do_something(data, function (input) {
    alert(input);
});

,当然这在 OOTB 中是行不通的。我正在思考这样的事情:

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
}

这可行。但我希望得到比这个更好的模式的建议,因为它不是很优雅,也没有真正使用很酷的 Tcl 功能。大多数情况下,我想摆脱手动调用anon_run

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

獨角戲 2024-09-16 20:41:30

在 Tcl 8.5 中,您可以使用 apply< /a> 命令。

proc do_something {data anon_function} {
    apply $anon_function $data
}
do_something $data {{input} {
    puts $input
}}

当然,如果您将回调构造为命令前缀(推荐!),那么您可以这样做:

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
}]

如果您使用的是 8.4 或之前版本,则需要 来自 Tcler 维基的代码 作为替代,但请注意,这些解决方案仅在语义上等效(充其量);它们的性能并不等同。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文