How to inject an evaluated expression into a held expression?
Here are a couple of alternatives to Trott-Strzebonski in @R.M's answer:
Hold[{3,4,5|6}] /.
Verbatim[Alternatives][x__] :> RuleCondition@RandomChoice@List@x
Hold[{3, 4, 5}]
Hold[{3,4,5|6}] /.
Verbatim[Alternatives][x__] :> Block[{}, RandomChoice@List@x /; True]
Hold[{3, 4, 6}]
They operate on the same principle as Trott-Strzebonski (i.e. RuleCondition
), but express the effect in different ways.
This is a case where the Trott-Strzebonski in-place evaluation trick is useful. You use With
to inject inside your held expression as:
(Hold[{3, 4, 5 | 6}] /. (Verbatim@Alternatives)[x__] :>
With[{eval = RandomChoice@List@x}, eval /; True])
Out[1]= Hold[{3, 4, 5}]
You should definitely read this post by Leonid, that gives you a good insight into how this works, but in short, using Condition
or /;
forces the evaluation of eval
when the condition is True
(i.e., always) and then injected arbitrarily deep using With
.