【问题标题】:Tcl Anonymous FunctionsTcl 匿名函数
【发布时间】:2010-07-13 07:50:56
【问题描述】:

关于 Tcl 的纯理论问题。

this question 之后,我正在考虑在 Tcl 中实现匿名函数的最佳方式。

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

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

【问题讨论】:

    标签: tcl


    【解决方案1】:

    在 Tcl 8.5 中,您可以使用 apply 命令。

    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 或更早版本,则需要 code from the Tcler's Wiki 作为替代,但请注意,这些解决方案仅在语义上是等效的(充其量);它们的性能不等同。

    【讨论】:

    • 另请注意,与 Javascript 不同,它不执行闭包。闭包在 Tcl 中在语义上很棘手,因为它们确实不适合 Tcl 的数据类型模型,并且上面的 lambda 术语使这个问题特别明显(它不是过程的大问题;只是一个简单的编程问题)。
    • 感谢详细且解释清楚的答案。
    • 我实际上已经为我的一个项目破解了limited form of closures
    猜你喜欢
    • 1970-01-01
    • 2011-12-29
    • 1970-01-01
    • 2011-04-20
    • 2015-01-27
    • 1970-01-01
    • 1970-01-01
    • 2014-09-11
    • 1970-01-01
    相关资源
    最近更新 更多