Yesterday I checked my account's question list again and find this question lying inside. After a year wrestling mostly with Hold
stuffs, I think I finally found a, well, not that elegant solution. Any suggestions or new answers are surely welcomed!!!
It seems that this question is not that bad, actually I may say that It's quite hard for one to solve this problem using all sorts of evaluation manipulation techniques. and it has real applications sometimes.
As usual, my code first:
SetAttributes[adddebug, HoldFirst]
adddebug[orig_, func_: Echo, level_: {2}] :=
Module[{$count = 1, tempf},
Replace[
Replace[Hold[orig], HoldPattern[CompoundExpression[comp__]] :>
Block[{},
tempf @@
Riffle[List @@ (Hold /@ Hold[comp]),
With[{$func = func, q = #}, Hold@$func@q] & /@
Range[$count, ($count = $count + Length@Hold[comp] + 1) -
1], {2, -1, 2}] /; True],level],
tempf[seg__] :>
Block[{},
tempf[Hold[CompoundExpression]] @@ (tempf /@ {seg}) /; True],level] /. tempf[Hold[seg_]] :> seg
]
adddebug[Do[j = i^2; Thread[{{1}, {2, 3}}], {i, 3}]]
The result is satisfying
Hold[Do[j = i^2; Echo[1]; Thread[{{1}, {2, 3}}]; Echo[2], {i, 3}]]
Some additional notes:
Why I say this question is not that trivial is because I should protect CompoundExpression
and its content from evaluating while still need to operate on CompoundExpression
's structure and use in place evaluation techniques extensively.
So I install protection in the following ways:
When pattern-matching, Use HoldPattern
Use unique symbol tempf
as a medium to mark Where CompoundExpression
previoulsly existed. Use tempf[Hold[CompoundExpression]]
.
make every element of CompoundExpression Hold at all times, and mark them using tempf[Hold[expr]]
I'm quite satisfied by the last ReplaceAll
's design, as previously I’ve already make where should be CompoundExpression
tempf[Hold[CompoundExpression]]
and where should be CompoundExpression
's element tempf[Hold[element]]
, Now I can safely use ReplaceAll
once to make those stuffs back to their original form!
I still am looking foward to a better solution, so if anyone has any idea, post something, Thanks!