|REBOL 3 Docs||Guide||Concepts||Functions||Datatypes||Errors|
|TOC < Back Next >||Updated: 12-Aug-2010 Edit History|
Evaluates expressions and returns multiple results.
/no-set - Keep set-words as-is. Do not set them.
/only - Only evaluate words and paths, not functions
words [block! none!] - Optional words that are not evaluated (keywords)
/into - Output results into a block with no intermediate storage
The reduce function evaluates multiple expressions and returns a block of results. This is one of the most useful functions in REBOL.
values: reduce [1 + 2 3 + 4] probe values [3 7]
Compare this with do, which only returns the result of the last expression:
values: do [1 + 2 3 + 4] probe values 7
The reduce function is important because it enables you to create blocks of expressions that are evaluated and passed to other functions. Some functions, like print, use reduce as part of their operation, as shown in the following example:
print [1 + 2 3 + 4] 3 7
rejoin ["example" 1 + 2] example3
str: copy "example" repend str [1 + 2] ; modifies (uses append) example3
reform ["example 1 + 2] example 3
remold ["example" 1 + 2] ["example" 3]
For convenience, expressions that are fully evaluated simply pass-through the reduce function.
reduce 123 123
reduce "example" example
This makes it possible to use reduce in cases where other datatypes may be passed. For example, here is a common function for building HTML strings that relies on this behavior:
html: make string! 1000 emit: func [data] [repend html data] emit "test... " emit ["number is: " 10] print html test... number is: 10
When you reduce blocks that contain set-words, those words will be set. For example:
a: 1 reduce [a: 2] print a 2
There are times when you do not want this to occur. For example, if you're building a header for a file, you may want to leave the set-words alone.
The /no-set refinement can be used to handle this case.
full-name: "Bob Smith" reduce/no-set [name: full-name time: now + 10] [name: "Bob Smith" time: 15-Aug-2010/16:10:50-7:00]
For most blocks you don't need to worry about memory because REBOL's automatic storage manager will efficiently handle it; however, when building large block series with reduce, you can manage memory even more carefully.
For example, it is common to write:
repend series [a b c]
which is shorthand for:
append series reduce [a b c]
The evaluated results of a, b, and c are appended to the series.
If this is done a lot, a large number of temporary series are generated, which take memory and also must be garbage collected later.
The /into refinement helps optimize the situation:
reduce/into [a b c] tail series
It requires no intermediate storage.
Although reduce will create a new outer block, all other series (blocks, strings, etc.) are referenced, not copied. If you modify those values, they will change in all blocks that reference them.
str: "name" probe result: reduce [str] ["name"]
insert str "new-" probe result ["new-name"]
You can see that it's the same string. To change that behavior use the copy function:
result: reduce [copy str]
or, for blocks that contain multiple strings or other values:
result: copy/deep reduce [str]
|TOC < Back Next >||REBOL.com - WIP Wiki||Feedback Admin|