metaeducation / ren-c

Library for embedding a Rebol interpreter into C codebases
GNU Lesser General Public License v3.0
128 stars 27 forks source link

Semantic inconsistency in Left Variadic Enfix #787

Open hostilefork opened 6 years ago

hostilefork commented 6 years ago

A change was made which allows a function with a variadic first parameter to be enfixed. But because the Rebol evaluator proceeds from left to right--discarding intermediate results along the way--it is not possible to gather more than one "variadic" parameter from the left. e.g.:

1 + 2 10 + 20 left-variadic-op

By the time the lookahead is done to notice that left-variadic-op is interested in its left argument, the "3" result from 1 + 2 has been discarded.

So mechanically, the left hand side can only be a source of 0 or 1 arguments. This was made to appear as a variadic feed which can provide at most one value.

But the general gist of variadic parameters is that they are "held in waiting" until they are TAKE'd. Yet the left hand stream...already processed...doesn't have this property. e.g.:

f: does [print "after" | 10]
prefix: func [v [integer! <...>]] [
    print "before"
    while [not tail? v] [print [take v]]
]

postfix: enfix :prefix

With do [prefix f] you will get

before
after
10

And with do [f postfix] you will get

after
before
10

In fact, it doesn't matter if you TAKE at all... f gets run regardless.

Various forms of clarification could be used here...for instance, marking frames that have left variadic input, and making sure that by the time they complete they have TAKE'd the input.

Previously I wrote on this topic:

The thought experiment we are having here, is that the person who wrote the varargs function wrote it to what we think of non-enfixed varargs semantics.

Then, someone after the fact, decides to enfix that function whose first argument is variadic.

It's a question of bias. Do you bias it to honor the contract under which the non-enfixed variadic function was written (let's say imagining the author wrote it in a world with no enfix). Or do you bias it to the worldview of a sly enfixer who thinks themselves above the black-box universe of this variadic function author who hypothetically doesn't know enfix even exists.

Mark-hi commented 6 years ago

I think you meant postfix: enfix :prefix ...

Mark-hi commented 6 years ago

I don't see why it has to be necessary to force postfix functions to TAKE (the output of) their left hand arguments ... if they don't, it will simply be discarded, like it would have been in the non-postfix case anyway.