2010-07-13 7 views
7

A Purely теоретический вопрос о Tcl.Tcl Анонимные функции

this question Я думал о том, что было бы лучшим способом реализовать анонимные функции в Tcl.

Конечный результат должен быть позволяет разработчику пройти полный процедурный в качестве аргумента anohter прок:

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.

ответ

11

В 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 в качестве замены, но имейте в виду, что эти решения являются только семантически эквивалентными (в лучшем случае); они не эквивалентны производительности.

+0

Также обратите внимание, что в отличие от Javascript он не закрывает. Закрытие семантически сложно в Tcl, потому что они действительно не соответствуют модели Datatype Tcl, а термины лямбда, как указано выше, делают эту проблему особенно очевидной (это не большая проблема с процедурами, а просто простая проблема программирования). –

+0

Я ценю подробный и хорошо объясненный ответ. –

+0

И я действительно взломал [ограниченную форму закрытия] (https://chiselapp.com/user/kbk/repository/tclquadcode/artifact/9cd98bc023dd3ef1?ln=353,382) для одного из моих проектов. –

Смежные вопросы