In the question of whether or not APIs should quote spliced values, the answer is...
Only if you ask it to ...but... make it really easy to ask.
Previously this was considered to be undesirable:
const char *spelling = rebSpell(rebQ(word));
To mitigate that, instead go ahead and offer a "Q" version of every variadic evaluating API:
const char *spelling = rebSpellQ(word)
You can choose either way, and you can also switch back and forth with rebQ() to add a quoting level to your splices and rebU() to remove one.
Looks good enough AND makes people feel in control
People may grumble when rebValue("append [copy reduce]", word);
acts like:
do compose [append [copy reduce] (word)]
They may have forgotten they were in C (or JavaScript, or whatever), and at runtime in that language the variable names are gone. There is no "word"...just as "word" is gone after the COMPOSE is finished.
Though they may grumble...at least they'd understand. On the other hand, they might get pretty mad if they get ['10 '20] out of the following if x and y are plain INTEGER!
REBVAL *coordinate = rebValue("reduce [", x, y, "]");
This is why I think the Q is important to have somewhere . If they'd used rebValueQ()
, they feel more like "oh, I asked for that...didn't I!"
So the way I look at it is that if someone studies the issues and decides they want to use the Q APIs by default and never touch the non-Q ones, then that's their business. If someone goes the other way, they can do that. But I think looking at what kind of code you're writing and choosing appropriately makes the most sense...which was the direction I'd been headed in.
COMPOSE may be able to benefit from this, too
COMPOSE can use .QUOTE (today, /QUOTE) as a "predicate" to tell it to quote the things it put in slots:
>> word: first [print]
>> compose .quote [append [copy reduce] (word)]
== [append [copy reduce] 'print]
Though it's pretty lightweight as is to say '(...)
on your slots instead of just (...)
, you still might want a specialization for this if you had a lot of them. Maybe called composeQ to line up with the API (I've wondered about doing mixed-case names like that, as I'm not crazy about compose-q
or composeq
or qcompose
.)
In any case, working with compose lately got me seeing it through the lens of "how much better do you expect a C API to a language to be than the language itself." I think it's gotten to right about where it can be, and at this point there's more value in having the API stable than in tweaking it more. So this is what I'm ready to commit to for Beta/One.