3

I'm trying to create a function that returns only the second argument of Reap. Here's my naive guess of how it would go : Reap2[x_]:= Flatten[Reap[x][[2]],1]

However, even when X contains Sow, my function always returns empty. I've made a simplified version here, which shows what I mean.

Reap[Sow[1]]
{1, {{1}}}

Clear[Reap2];
Reap2[x_] := Reap[x]
Reap2[Sow[1]]
{1, {}}

Can anyone explain this behavior? How would I go about building this function?

Lokdal
  • 405
  • 2
  • 8
  • 1
    You are only missing HoldFirst. Try: SetAttributes[Reap2, HoldFirst]. – Mr.Wizard Dec 12 '14 at 19:05
  • 1
    Reap is not a simple function. It is closer to scoping constructs in spirit. It has a Hold attribute, so that the code evaluates only inside of it, but not before being passed. You need to set HoldAll or HoldFirst attribute to your Reap2, if you want it to behave properly. – Leonid Shifrin Dec 12 '14 at 19:05
  • Lokdal, I am glad you have your solution but there is no need to include it in the question. In fact it is unnecessary clutter and draws attention away from the Accepted answer. By the way I do not believe that you will need to use both Join and Flatten. – Mr.Wizard Dec 12 '14 at 19:38
  • Mr.Wizard : edited accordingly! And you're right, for my specific need I had to use Flatten because I Sow lists, and using Join removed the structure. – Lokdal Dec 13 '14 at 02:36

1 Answers1

8

The issue is lack of HoldFirst in attributes of your function, Sow is being called too early otherwise before Reap can capture

ClearAll[reap2]
SetAttributes[reap2,HoldFirst]
reap2[x_]:=Join @@ Reap[x][[2]]

idea to use Join@@ taken from @Mr.Wizard from here What is shorthand way of Reap list that may be empty because of zero Sow

Manuel --Moe-- G
  • 1,057
  • 1
  • 8
  • 16