Comments on: Closure Functions
Closure functions will be provided as a standard part of REBOL
The concept of function closures is nothing new (30 years at least), and can be found in most types of functional languages.
A closure is a special type of, or characteristic of, a function
that keeps the local environment (arguments and local variables) of
the function "alive", even after the function has returned.
| ||Advantages:||The environment of the function (words and data) remains valid after the function returns (which is not true
of normal functions). This is useful if you
want to return words or other data from the function, and you want
to still access the values of the words.
| ||Disadvantages:||They evaluate slower than normal functions
because they are allocated and bound at run
time. Also, closures often require more memory (and cause more
recycling), depending on how you use and store their results.
In REBOL 3.0, closure functions are implemented with the closure!
datatype and a new mezzanine function called closure. Here is
an example that defines a new closure function called hash-name:
hash-name: closure [name [string!] /local hash] [
hash: checksum/secure name
return [name hash] ; note: returns words, not values
When a closure is defined a REBOL object is created and the function
body is bound to that object. When the function is evaluated, the
original function object is cloned and the body is deep copied and
rebound to the newly cloned object.
You call closure functions in the same way as you would any
result: hash-name "Bob"
print second result
You can test for a closure function with:
if closure? :hash-name [print "It is true"]
and, this expression is also true:
if any-function? :hash-name [print "It is true"]
To read more about the concept of closures, see
Function Closure in the Wikipedia, and also Ladislav Mecir
provides useful methods and examples of REBOL closures (that work in
current versions of REBOL) in his "Bind A Function
Yourself" tutorials and code.
What happens with something like this:
self: closure [ spec body][
return closure spec body]
selfer: self [spec body][return closure spec body]
Will this kill the eval loop?
Or a return value that consists of a set of data modifying closures?
data-mod: closure [ d1 d2 /local d4 d5][
d4: closure [ e1 ][ return join d1 e1]
d5: closure [ e2 ] [return join d2 e2]
return [ d4 d5]
yay!!! need I say more?|
This sounds useful for constructor functions, but seems a little heavy-handed for most usage. In most cases it seems like you are replacing a simple reduce with a full bind/copy of the function body. Still, behavior like this might be needed for thread-safety so why not make it visible.
Are contexts being implemented differently?
3.0 contexts are completely different. The bind/copy is more efficient too.
Indeed, use them wisely. Otherwise, use functions.
I look forward to the upcoming blog entry on the new contexts (hint, hint) :)|
Would it be possible to have the local variables in functions none'd out when the function finishes executing so that any memory they are referencing can be reclaimed? I'm aware that this wasn't done before for speed reasons, but perhaps there will be a quick way to do this with the new contexts. It's kind of the opposite problem to that which closures solve I suppose...|
What about generators and coroutines, any ideas on that?|
nevermind, now I know better. Coroutines are just a subset of threads. Python seems to add it in 2.5, but look at this in the what's new section:
"We'll have to figure out patterns for using coroutines effectively in Python. "
Feature without a cause.
regarding SELFER: no problem with it, you can try it with my http://www.fm.tul.cz/~ladislav/r...rebol/
Whenever I've needed a closure-type function, I've faked it inelegantly.
An elegant way to do them authentically would be grand.
Post a Comment:
You can post a comment here. Keep it on-topic.