Reputation: 33607
In the following code, we can assign the result of a GET-WORD to p through a SET-WORD, and then use it under the new name:
p: :print
p [{Hello} {World}]
But what if you are using COMPOSE, and you find a situation such as this?
do compose [p: (:print)]
p [{Hello} {World}]
That gives an error:
*** ERROR
** Script error: -unnamed- is missing its value argument
** Where: do
** Near: do compose [p: (:print)] p ["Hello" "World"]
So it's like function values in a block are "live" when seen in the interpreter...whether they were fetched as an evaluative result or not. (It would seem they should be inert unless fetched or applied somehow, otherwise such assignments are not possible from within a COMPOSE or similar.)
It seems you have to quote a get-word, such as:
do compose [p: (quote :print)]
p [{Hello} {World}]
That could do the trick to make p the print function. But can you do it without going through a GET-WORD or similar as a proxy?
Upvotes: 2
Views: 155
Reputation: 41755
Yes, you can "disarm" the active function! value with a feature of the DO-dialect:
>> do probe compose [p: quote (:print)]
[p: quote make native! [[
"Outputs a value followed by a line break."
value [any-type!] "The value to print"
]]]
>> p [{Hello} {World}]
Hello World
They key here is the special argument passing mode used for the single argument of QUOTE:
>> source quote
quote: make function! [[
"Returns the value passed to it without evaluation."
:value [any-type!]
][
:value
]]
This argument passing mode, unimaginatively called "get arguments", inhibits evaluation of the argument value. So in our particular case, it prevents the "active" nature of the function! value to come to bear.
For more details about argument passing modes, you might want to have a look at this recent treatise about literal and get arguments, which compares the differences between Rebol 2 and Rebol 3 to give a historical perspective.
Upvotes: 3
Reputation: 3199
Use the following way to create the get-word, it buys you an additional level of indirection:
>> do compose [p: (to-get-word 'print)]
>> p [{Hello} {World}]
Hello World
If you want the assignment to be done using a DO [...] form, then you need a word assigned to the anonymous function in order to manipulate it in a passive way.
An alternative option is to do the assignment outside of the composed block:
p: first compose [(:print)]
Upvotes: 2
Reputation: 521
The first question is what do you need this for?
Because it works without compose.
Do [p: :print]
P 1
And without a get-word
Do [p: get first [print]]
Edit:
I don't understand the implications for the C++ binding, but 'compose is used to evaluate parts of a block selectively. In your example you want to evaluate a part, but still want it not being evaluated, so you need to stop it from being evaluated too early, for example:
do compose [p1: (to get-word! 'x)]
If you want to use compose, and no get-/lit-word!, you could try quote:
do compose [p4: get quote ( quote print)]
The inner 'quote guards 'print from being evaluated during compose, the outer one guards durng the 'do, so that 'get can get the value.
Upvotes: 0