Why doesn't Rebol 3 honor quoted function para

2019-01-18 00:46发布

问题:

The DO dialect uses series of category PAREN! for precedence, and will usually boil away the underlying parentheses structure prior to invoking a function.

However, it used to be possible in Rebol 2 to specify in a function's definition that you wanted it to suppress evaluation of parentheses at the callsite. You did this by using a "literal word" apostrophe mark on a parameter:

evaluated: func [param] [probe param]

non-evaluated: func ['param] [probe param]

>> evaluated (1 + 2)
3

>> non-evaluated (1 + 2)
(1 + 2)

So you get passed a SERIES! category type, of class PAREN!...in this case with three symbolic elements inside: 1, +, 2. This does not work in Rebol 3:

>> non-evaluated (1 + 2)
3

Is this a bug or a purposeful design decision? Is there a workaround? Note that putting the quote operator at a callsite won't work, because then it's the symbolic word quote that gets quoted, and then the paren! gets evaluated on its own to become the final value of the expression :-/

>> non-evaluated quote (1 + 2)
quote
== 3

回答1:

The behaviour of this argument passing type has been changed on purpose. (Many users including myself requested the change). The advantage is that you can request evaluation for this argument type using parentheses (another way how to request evaluation is to use get-word). If you want truly unevaluated argument passing, see this:

quote: make function! [[
    "Returns the value passed to it without evaluation."
    :value [any-type!]
][
    :value
]]

That is again an improvement compared to R2, where such function does not really behave exactly the same way.

And in case you really want to pass a paren! to your function while not wanting to change its definition to use "truly unevaluated argument passing" you can try this:

non-evaluated (quote (1 + 2))