Consider this example: given an option for a function func as "x" :> (a&), how can one assign different values to a locally inside func?

a = False; (* global value of a *)
func[opt_] := With[{a = True}, Evaluate["x" /. opt]]; (* oversimplified function *)

func["x" :> (a &)]    (* ==> a & *)

No amount of Evaluate seems to help here. The problem with With is that in this case it is interpreted as With[{a$ = 1}, a&], thus no replacement will be done. If I use Block instead of With the problem boils down to this (as Block won't replace variables inside Function):

 Block[{a = True}, a &]   (* ==> a & *)

I do not want to define the option to be a function depending explicitly on a: I expect the user to write his own pure function for "x" where he can also use a that should acquire its local value when the With/Block is evaluated. Also, the problem disappears, if the code is simplified, but of course this is a no-go, as I need a function:

opt = "x" :> (a &);
With[{a = True}, Evaluate["x" /. opt]]   (* ==> True & *)

I've checked the following posts (mostly by Leonid and Mr.W), none of which offered a clear solution: this, this and this.

  • 1
    $\begingroup$ How about something like f[opt_] := "x" /. (opt /. HoldPattern[a] -> True)? $\endgroup$
    – ssch
    Commented Oct 19, 2013 at 11:36
  • $\begingroup$ A variation on @ssch: func[opt_] := Block[{a = True}, "x" /. opt /. HoldPattern[a] -> a] $\endgroup$
    – Michael E2
    Commented Oct 19, 2013 at 12:09
  • $\begingroup$ @MichaelE2 Well, your version is a special case of what my code does in general. For the record, I haven't seen the comment of ssch before posting my code. $\endgroup$ Commented Oct 19, 2013 at 12:14
  • $\begingroup$ @LeonidShifrin Yes, I see that now. I was working on it myself and worked my way around to ssch's. But I thought pointing out the use of Block worth a comment, since Istvan mentioned a taking on local values. I saw you had answered, and saw it was general, but it took a while for me to figure out what it was doing. I wish I was as fluent as you (as you seem to be) in thinking about these problems, which is why I try to solve them. (Upvoted your answer, btw.) $\endgroup$
    – Michael E2
    Commented Oct 19, 2013 at 12:33
  • $\begingroup$ @MichaelE2 Thanks :) I realize that some of my solutions can be cryptic, and it would probably have taken me quite some time to decipher such code, should I run across one written by someone else. But from the pure language viewpoint, I think that this type of code is rather economical. It just needs some time to get used to this style. $\endgroup$ Commented Oct 19, 2013 at 12:36

4 Answers 4


To avoid those scoping constructs being recognized as such and having their variables renamed, I like wrapping their heads with Identity. In your case,

func[opt_] := Identity[With][{a = True}, "x" /. opt]

This question is a subset of: Enforcing correct variable bindings and avoiding renamings for conflicting variables in nested scoping constructs and related to: Nested definition: How can I define a function with a passed-in expression?

In this case, since you explicitly evaluated the body of With anyway, I would simply use Function as ybeltukov did, but without the Options method (though I like his way too):

func[opt_] := With[{a = True}, #] &["x" /. opt]

In a more general case, if you needed to hold the body of With unevaluated I would Apply With:

func[opt_] := With @@ Hold[{a = True}, "x" /. opt]

I find this a bit more intelligible than using Identity[With] as Rojo did. If intelligibility is not a priority here are some other methods for the sake of curiosity:

func[opt_] := With[Unevaluated[{a = True}], "x" /. opt]

func[opt_] := With[{L := {a = True}}, With[L, "x" /. opt]]
  • $\begingroup$ +1. Nice, I like the application of With $\endgroup$
    – RunnyKine
    Commented Oct 20, 2013 at 3:05

A quick solution by ssch

For the case at hand, you can do

f[opt_] := "x" /. (opt /. HoldPattern[a] -> True)

A general solution to this class of problems

Here is a general way to perform this type of tasks, also based on replacement rules.

It looks like you are after some function which would rebind certain bindings captured in e.g. closure (bindings to the enclosing environment). Here is a possibility:

SetAttributes[rebind, HoldAll];
rebind[vars : {__Set}, code_] :=
    code /. Flatten[
          HoldPattern[sym_Symbol = _] :> OwnValues[sym], 

This will create dynamic bindings for a given set of variables, using Block, and then inject them lexically into the body of the code, using replacement rules. The use of replacement rules here is preferable to the use of With, because the former don't care about the variable collisions in inner scoping constructs - which seems to be what we need here.

Here is your example:

func[opt_] := rebind[{a = True}, "x" /. opt];



(* True & *)

Note that this is still a rather exotic construct, so I would make sure that there is a real need to use things like this.

  • $\begingroup$ @ssch, Leonid Somehow I thought that this could be solved with a scoping construct and did not thought of direct replacements. Silly me, thanks for the answer. I think it would be useful to edit in ssch's shorter form as well as a quick fix! $\endgroup$ Commented Oct 19, 2013 at 12:18
  • $\begingroup$ @IstvánZachar All right, edited that in. $\endgroup$ Commented Oct 19, 2013 at 12:25
  • $\begingroup$ That Cases and OwnValues combination is really neat! $\endgroup$
    – ssch
    Commented Oct 19, 2013 at 12:47
  • $\begingroup$ @ssch Thanks, I like this bit too. $\endgroup$ Commented Oct 19, 2013 at 14:44

Solution with Options:

Options[func] = {"x" -> None};  (* some default value *)

func[OptionsPattern[]] := With[{a = True}, #] & @@ 
          OptionValue[Automatic, Automatic, "x", Hold];

func["x" :> (a &)]

True &


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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