Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tcl Anonymous Functions

Tags:

tcl

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.

like image 487
Nir Levy Avatar asked Jul 13 '10 07:07

Nir Levy


People also ask

What is anonymous function with example?

An anonymous function is a function that was declared without any named identifier to refer to it. As such, an anonymous function is usually not accessible after its initial creation. Normal function definition: function hello() { alert('Hello world'); } hello();

What are anonymous functions used for?

Anonymous functions, also known as closures , allow the creation of functions which have no specified name. They are most useful as the value of callable parameters, but they have many other uses. Anonymous functions are implemented using the Closure class.

Which function is called anonymous?

In Python, an anonymous function is a function that is defined without a name. While normal functions are defined using the def keyword in Python, anonymous functions are defined using the lambda keyword. Hence, anonymous functions are also called lambda functions.


1 Answers

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.

like image 191
Donal Fellows Avatar answered Oct 09 '22 07:10

Donal Fellows