Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Associativity of fold-expressions

N4191 proposed fold-expressions to C++. The definition there was that

(args + ...)

is a left-fold (i.e. (((a0 + a1) + a2) + ...), and that

(... + args) 

is a right-fold (i.e. (... + (a8 + (a9 + a10))). However, the revised paper N4295 reversed the definitions of left and right unary folds.

Question: what is the rationale? It seems more intuitive (at least when you are used to left-to-right alphabets) to evaluate (args + ...) from left-to-right.

like image 678
TemplateRex Avatar asked Feb 02 '16 20:02

TemplateRex


1 Answers

From the comment by @cpplearner, here's some archeology from std-discussion

On Wed, Feb 4, 2015 at 1:30 AM, @T.C. wrote:

In N4295, which was actually voted into the standard,

(... op e) is a unary left fold;

(e op ...) is a unary right fold;

In N4191, however,

(e op ...) is called a left fold.

(... op e) is called a right fold.

Why the 180-degree turn?

And the answer by @RichardSmith

The form in the original paper was simply a typo. Here are some reasons why the definition that was voted into the standard is the correct one:

  1. In the standard's formulation, (e op ...) has subexpressions of the form (e_i op <stuff>). It does not have subexpressions of the form (<stuff> op e_i). This is consistent with all other pack expansions, where the expansion comprises repeated instances of the pattern.

  2. (e op ... op eN), where eN is a non-pack, must have eN as the innermost operand in order to be useful -- that is, it must be (e1 op (e2 op (e3 op (... op eN)...))), not (...(((e1 op e2) op e3) op ...) op eN) -- and vice versa for (e0 op ... op e). This allows, for instance, (string() + ... + things) and (std::cout << ... << things) to work. For consistency, (e op ...) must also be (e1 op (e2 op (...))).

like image 116
TemplateRex Avatar answered Oct 20 '22 05:10

TemplateRex