1
$\begingroup$

I wish to define a function interleaveWithX[statements__] with behavior such that evaluating, for example,

interleaveWithX[a, b, c, d]

produces the same results as evaluating

a; x; b; x; c; x; d

Getting the arguments interwoven is no problem; something like

interleaveWithX[statements__] := Riffle[List@statements, x]

does the job fine. But assuming that the statements and x are already defined, I'm struggling to figure out what combination of SetAttribute, Hold, Unevaluated, ReleaseHold, Evaluate, etc. I need to incorporate in my function definition, and where, in order to delay evaluation of the arguments until I've interwoven them into the desired order.

$\endgroup$
0
2
$\begingroup$

I think this does the job. Probably not in the most elegant way:

ClearAll[interleaveWithX];
SetAttributes[interleaveWithX, HoldAll];
interleaveWithX[statements__] := 
 With[{list = Riffle[{Hold /@ Unevaluated[statements]}, x]},
  CompoundExpression @@@ HoldComplete[list] /. Hold[y_] :> y
  ]

interleaveWithX[1+1, b, c, d]

HoldComplete[1 + 1; x; b; x; c; x; d]

The HoldComplete is there to show you the unevaluated output. The final function would be wrapped with ReleaseHold:

ClearAll[interleaveWithX];
SetAttributes[interleaveWithX, HoldAll];
interleaveWithX[statements__] := 
 ReleaseHold @ With[{list = Riffle[{Hold /@ Unevaluated[statements]}, x]},
  CompoundExpression @@@ HoldComplete[list] /. Hold[y_] :> y
  ]
$\endgroup$
1
  • $\begingroup$ I had to use Hold @ x instead of x since I also want x to remain unevaluated prior to riffling, but other than that this does the job! Apart from the evaluation stuff, CompoundExpression is very helpful to know about, thanks! $\endgroup$ – thecommexokid Apr 3 '20 at 22:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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