REBOL 3.0

Comments on: Closure Functions

Carl Sassenrath, CTO
REBOL Technologies
24-Apr-2006 16:32 GMT

Article #0012
Main page || Index || Prior Article [0011] || Next Article [0013] || 10 Comments || Send feedback

Closure functions will be provided as a standard part of REBOL 3.0.

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 function:

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.

10 Comments

Comments:

maarten
24-Apr-2006 13:40
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?

Like:

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] ]

maximo
25-Apr-2006 15:15
yay!!! need I say more?
Brian Hawley
26-Apr-2006 16:37
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?

Carl Sassenrath
26-Apr-2006 17:08
3.0 contexts are completely different. The bind/copy is more efficient too.

Indeed, use them wisely. Otherwise, use functions.

Brian Hawley
26-Apr-2006 23:10
I look forward to the upcoming blog entry on the new contexts (hint, hint) :)
Brian Hawley
27-Apr-2006 0:26
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...
maarten
27-Apr-2006 14:01
What about generators and coroutines, any ideas on that?
maarten
27-Apr-2006 16:41
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.

Ladislav Mecir
1-May-2006 12:13
regarding SELFER: no problem with it, you can try it with my http://www.fm.tul.cz/~ladislav/r...rebol/ closure.r
Sunanda
3-May-2006 20:06
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.

Name:

Blog id:

R3-0012


Comment:


 Note: HTML tags allowed for: b i u li ol ul font span div a p br pre tt blockquote
 
 

This is a technical blog related to the above topic. We reserve the right to remove comments that are off-topic, irrelevant links, advertisements, spams, personal attacks, politics, religion, etc.

REBOL 3.0
Updated 28-May-2017 - Edit - Copyright REBOL Technologies - REBOL.net