Why doesn't Rebol 3 honor quoted function parameters that are parenthesized?
Asked Answered
M

1

6

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
Marcelina answered 26/1, 2013 at 0:49 Comment(1)
Note that the terminology used in R2 to describe this argument-passing type is "literal arguments". (Also note that a few of the examples in the user's guide behind this link are badly typeset, it's always ' and never `.)Hagbut
C
7

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))
Cluj answered 26/1, 2013 at 1:29 Comment(5)
Ah, hmm. Okay, it is cooler to have a choice of behaviors. Was Red's notion of the return: for functions added with awareness of this decision or is it a separate thing? (I'm hoping Rebol will add return: too...)Marcelina
the return: idea comes from Carl and is planned for R3 (but I cannot guarantee Carl's idea is exactly the same as what Doc is implementing not knowing thoroughly any of them)Cluj
also, return: has been already used in specifications of R2 routines, which you may not have noticed yetCluj
Aha, it seems I did not answer your question whether the return: specification was related. In Rebol it does not look to be related; the only relation is that it is a part of function specification as well.Cluj
The literal-argument vs. get-argument has indeed turned out to be a great choice to be able to make. Props to "many users, including [yourself]" for getting that one in. Tons of applications.Marcelina

© 2022 - 2024 — McMap. All rights reserved.