I want to do this:
>> SET [a b] reduce [(ask "a: ") (ask "b: ")]
a: 1
b: 2
== ["1" "2"]
>>
Programmatically:
args: [a b]
block: copy []
foreach arg args [
append block to-word "("
append block 'ask
append block rejoin [arg ": "]
append block to-word ")"
]
set args reduce block
But I get this error:
>> foreach arg args [
[ append block to-word "("
[ append block 'ask
[ append block rejoin [arg ": "]
[ append block to-word ")"
[ ]
== [( ask "a: " ) ( ask "b: " )]
>> set args reduce block
** Script Error: ( has no value
** Near: ( ask "a: " ) (
>>
What you’ve discovered is that parentheses are not
word!s. They are built-in to Rebol, and the parser makes sure they match up for you—just likeblock!does.This is a good thing—otherwise all around the system would be code handling the
()))()mismatches. You’ve been saved from that pain! But if you want then you can reinvent this pain in your own dialects, and use words like BEGIN and END instead of leveraging the ever-helpfulparen!. 😛Here’s a minimalist patch to your code:
Note that you cannot write
copy (). Generally speaking, parentheses are a little trickier to work with in thedodialect than blocks—they are serving double-duty for precedence! The interpreter thinkscopy ()means you’re trying to parenthesize an expression whose results you want to copy. 🙁You can save yourself some headaches by building things up as blocks, and then converting them only at the last minute:
P.S. I didn’t want to distract from your question by pointing out that the parentheses weren’t actually necessary:
But the good news about that is that if you’re willing to let parens serve a “higher purpose” in this case, there’s always
composeComposing is like using a “templating dialect”, which only reduces the expressions contained in parens, leaving everything else as-is. It’s a good way to create code by example, but definitely does run into trouble if your generated code uses parentheses already for precedence! Still…goes to show that your dialects can use parentheses for any purpose, just like they can give meaning to words.