Ladislav Mecir napsal(a):
> Another option is to use a closure ( 
> http://www.fm.tul.cz/~ladislav/rebol/closure.r , which is going to be 
> implemented natively in R3) and the implementation may be: (see, what 
> are the closures good for?)
>
>     collect: closure [
>         {Collects values, returning them as a series.}
>         [throw]
>         emit [word!]  "Word used to collect values"
>         block [block!] "Block to evaluate"
>         /into dest [series!] "Where to append results"
>         /only "Insert series values as series"
>         /local ins
>     ] [
>         ; Create a new context containing just one word (the EMIT
>         ; argument) and set the 'emit word to refer to the new context
>         ; word. Note the care taken to suppress possible conflicts and
>         ; undesired evaluations.
>         emit: reduce [emit]
>         emit: first use emit reduce [emit]
>         dest: any [:dest []]
>         ; make the function used to collect values.
>         ins: either only [[insert/only]] [[insert]]
>         set emit func [value [any-type!]] compose [
>             (ins) tail :dest get/any 'value
>             get/any 'value
>         ]
>         do bind/copy block emit
>         head :dest
>     ]
>
> ; test:
> probe collect 'x [
>     probe collect 'y [
>         foreach i [1 2] [
>             y negate i
>             x i
>         ]
>     ]
> ]
>   
Explanation why reentrancy requires COLLECT to be a CLOSURE:

The COLLECT function defines a new EMIT function, which needs to 
*remember* the DEST value with which it has been created. If COLLECT 
were a FUNC and if it were evaluated during the BLOCK evaluation, the 
'DEST word would "suddenly" change its value, which would cause the EMIT 
function to collect the values to the new DEST.

-L

-- 
To unsubscribe from the list, just send an email to 
lists at rebol.com with unsubscribe as the subject.

Reply via email to