R3-Alpha and Rebol2 could only have functions that were "endable" if the argument they took was quoted. This feature was added primarily for HELP, so that you could say either:
>> help ; (would display generic HELP usage information) >> help topic ; (would display help for the given topic)
It was a very limited form of variadic-ness...generally used only in console-oriented commands (HELP, LS). You couldn't write a function that was evaluative, like:
redbol>> printer 1 + 2 3 redbol>> printer You called the PRINTER function with no arguments ; ^-- not possible to accomplish with an otherwise evaluative argument!
Being able to handle getting to the end of input was entwined with taking quoted arguments.
To facilitate certain demos in Ren Garden, Ren-C could mark an ordinary parameter as being
<end>-able. This would mean that the argument would show up as being NULL if the end was reached before an argument was seen.
This was--however--ambiguous with if you actually passed an evaluative NULL.
ren-c>> printer 1 + 2 3 ren-c>> printer You called the PRINTER function with no arguments ren-c>> printer null You called the PRINTER function with no arguments ; d'oh
This kind of ambiguity wasn't new...the Redbol version had it. The signal for quoted parameters that were endable-and-missing was to make the parameter an UNSET!. Which meant they couldn't tell the difference between help #[unset!] and just-plain-help:
red>> help #[unset!] To use HELP, supply a word or value as its argument: help insert help system help system/script To view all words that...
Interestingly enough, Ren-C has a solution for this with quoted parameters, because NULL cannot appear literally in source...so it can't be at the callsite. Thus NULL can represent a missing quoted argument. Which is neat.
A meta parameter is quoted, but will be a quoted void if the callsite was passing a void:
So if our PRINTER took a ^META argument:
>> printer 1 + 2 3 ; (it actually received '3, quoted) >> printer ' You called the PRINTER function with no arguments ; (it actually received ')
The ambiguity is still there, though...
>> printer void You called the PRINTER function with no arguments ; (again, it actually received ')
But at least you could differentiate NULL from an end. The conflation of an invisible argument with the end doesn't seem as troubling to me, as the problem with HELP is fixed since it quotes and can tell when you say help void vs. plain help
If a quoted parameter tolerates NULL as one of its legal types that's sufficient to say it is "endable"
If an evaluative parameter needs to detect endability, it could be your job to make it a ^META parameter and look for void, and unquote it to handle other results.
The code and typeset flags for
<end> could then be scrapped.
If someone really liked the NULL conflating version of endability they could write something to do it in usermode.
You'd have to see the code to understand why I would think throwing away
<end> is worth it. The way the type checking is done frames have to be filled first, which means if a function doesn't want an actual null but wants just ends to reflect as null... or wants an actual null but doesn't want ends reflected as null... hidden bits need to be grafted onto these nulls at the time of frame fulfillment to say whether it's an "endish" null or a regular null. Various parts of the system then need to test a NULL for this invisible property. ^META parameters pull such invisible state into the light.
Basically take my word for it: meta is much cleaner, and offers a way to expose these distinctions to the user--so I think the odds are that
<end> and its current mechanics need to die.