Consider the following trivial example:

{Sow[1]; 2; Sow[3]; 4; 5} // (Reap /* Last)
(* Output: {} *)

{Sow[1]; 2; Sow[3]; 4; 5} // Reap // Last
(* Output: {{1, 3}} *)

Moreoever, if I first build an expression containing Sow and then Reap it, I get an empty list both times:

expr = {Sow[1]; 2; Sow[3]; 4; 5};

expr // (Reap /* Last)
(* Output: {} *)

expr // Reap // Last
(* Output: {} *)

What is the reason for this anomalous behaviour?

  • 3
    $\begingroup$ Reap must hold the code inside. The postfix function application operator // does not affect that, but the composition operator does - since it does not hold the arguments in intermediate function applications. Try Composition[Hold, Hold][Print[1]] and you will see that 1 gets printed. You would need a holding version of Composition (or RightComposition) for this to work. $\endgroup$ Apr 13 '21 at 21:43
  • 2
    $\begingroup$ What makes you think they are "the same expression"? $\endgroup$
    – ciao
    Apr 13 '21 at 21:44
  • $\begingroup$ @ciao In this case there may be some special syntactical rules at play, which Leonid Shifrin explains in his comment above. But I think the onus would be on anyone claiming that the resulting expressions are not the same to explain why that is so. Within the "normal" rules of Wolfram Language, it is perfectly reasonable to assume that the expressions are the same. $\endgroup$ Apr 13 '21 at 21:56
  • 1
    $\begingroup$ @Shredderroy The expressions are certainly not the same, since Composition or RightComposition are separate functions, which prompt chained function application as a result of evaluation of expression, while // is just another syntax for function application, which is resolved at parse time, not evaluation time - so for all intents and purposes is equivalent to just func[expr] (one just need to pay attention to precedence). Wrap each expression in Hold and inspect the FullForm of the results, to see the difference. $\endgroup$ Apr 13 '21 at 22:04
  • $\begingroup$ Actually, on closer scrutiny, I now understand why the expressions are not the same. My apologies to @ciao. And thanks to Leonid Shifrin. $\endgroup$ Apr 13 '21 at 22:20

You play a syntax puzzle. In order to see what is going on:

{Sow[1]; 2; Sow[3]; 4; 5} // (Reap1 /* Last1)
(* Last1[Reap1[{5}]] *)

The Last of a Reap that sows nothing is obviously the empty list.

{Sow[1]; 2; Sow[3]; 4; 5} // Reap // Last1
Last1[{{5}, {{1, 3}}}]

Not the answer you're looking for? Browse other questions tagged or ask your own question.