Operator meaning "complete fully"...what is that?


#1

I’d like something to help notice when an operation did not consume all its input.

Something along the lines of:

>> (completely-consume add 1 2)
== 3

>> (completely-consume add 1 2 3)
** Error: ADD did not completely consume args, leftover is [3]

I’ve wanted such a thing for a while, but it’s especially pressing now. The API is getting more solid, so it’s tempting to use it for doing things like calling from C the “System helpers written in Rebol”… a.k.a. what’s in SYS. But the existing mechanisms for doing that have a “no leftovers” flag, something like:

DECLARE_LOCAL (result);
bool leftovers = false;
if (Apply_Throws(result, add_function, leftovers, arg1, arg2, arg3, rebEND))
    fail (Error_No_Catch_For_Throw(result));

I don’t want such flags in the API. It seems useful to have a generic operator.

In the past, I’ve tried “double-bar”, because it would allow for a more forceful kind of separation than just a single bar. Unfortunately, it has to be prefix…as there’s no way at present in usermode to know the left hand side completed exactly one expression:

>> (x: add 1 2 "foo" | print x)
3

>> (|| x: add 1 2 "foo" || print x)
** Error: extra stuff (["foo"])

I’m wondering if the idea of || is sound, but just needs a new piece of machinery. Because this seems superior for the intent:

>> (x: add 1 2 "foo" || print x)
** Error: extra stuff ["foo"]

>> (x: add 1 2 || "foo" print x)
** Error: extra stuff [print x]

>> (x: add 1 2 || print x "foo")
** Error: extra stuff ["foo"]

>> (x: add 1 2 || print x)
3

So what do people think? Better ideas for the prefix operator? Time for a new parameter marker, e.g. <solo>?

This might be something that could be a use for the debated “variadic left enfix”. Maybe it could be possible to take a value from the left, and then tell you if you were at the “tail” or not…while not actually being able to give you more than one value? They’re lost to history, but it wouldn’t be hard to keep just a bit’s worth of memory for this purpose.

As an API client it would be up to you to put it at the beginning or the end (or both?)

REBVAL *v = rebRun("||", whatever, ..., ...);

REBVAL *v = rebRun("whatever", ..., ..., "||");