On Wed, Oct 28, 2020 at 2:20 AM Paul Backus via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
On Tuesday, 27 October 2020 at 10:54:46 UTC, Mike Parker wrote:
> This is the feedback thread for the first round of Community
> Review of DIP 1037, "Add Unary Operator ...".

Given the map form, `expr ...`, it seems like it would be quite
easy to implement the fold form, `expr BinOp ...`, using only
library code. For example, the example in the DIP:

     (Tup == 10) || ...

Could also be written as

     any(only(Tup == 10 ...))

Or without Phobos:

     bool any(bool args[]...)
     {
         bool result = false;
         foreach (arg; args)
             result ||= arg;
         return result;
     }

     any(Tup == 10 ...)

The library versions require at worst O(1) template
instantiations, and have the advantage that they are not limited
to built-in operators. What are the advantages of `expr BinOp
...` compared to this approach?

The fold semantic is about 3 extra lines of code in the implementation compared to the map form.
The main advantage is that it's terse and easy to read, less work for the compiler (even if negligible).

Your example implementation above makes me uncomfortable; I wouldn't expect that to inline reliably, and if it doesn't inline, then it will generate very bad code. It won't constant-fold properly anymore, all terms will become runtime evaluated even where they're constant, etc.
Consider `Tup && ...`, where the tuple contains a single constant `false` element. In that (common) case, the entire expression collapses to `false` at compile time. If, for any reason whatsoever, the compiler emits a call to that function (inlining disabled?); the arguments will be assembled into an array (including the constant `false`), and it will be runtime evaluated. Same applies for `Tup || ...` with a single constant `true` element. These are super-common cases. The entire expression reliably collapses to a constant as per the spec, and that is not driven or dependent on extra compiler or optimiser work at later phases.

As a user, I would be surprised if the fold expression didn't work when I tried to type it... the rule of least surprise dictates to me that it should exist.
Anyway, I agree what you say is possible, but I don't like it. Tuple expansion is about static expansion; the entire point is that it's a static expression, and your suggestion undermines the goal of this DIP as I see it.

If the DIP were going to be rejected on the basis of the fold feature, I would consider removing the fold feature. It makes no material difference to language complexity, or to the implementation; it's about 3 lines of code.