Анонимные функции Tcl

Чисто теоретический вопрос на Tcl.

После этого вопроса я думал на том, что будет лучшим способом реализовать анонимные функции в 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.

7
задан Community 23 May 2017 в 11:59
поделиться

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

12
ответ дан 6 December 2019 в 21:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: