Nested definition: How can I define a function with a passed-in expression?
Try for example
SetAttributes[def, HoldAll]
def[s_Symbol, v_] := Function[Null, s[x_] := #, HoldFirst][v]
Unnamed functions just don't care :)
Other alternatives that should also work (but I would use the previous approach)
def[s_Symbol, v_] := Identity[SetDelayed][HoldPattern@s[x_], v];
def[s_Symbol, v_] := Unevaluated[s[x_] := "Hello"] /. "Hello" -> v
With your proposed definition style, the user of that function def has to know that v could/should/must depend on x for this to work; x really should be an argument of def. Perhaps something like this were better suited.
ClearAll[def]
ClearAll[f]
(*SetAttributes[def,HoldFirst]*)
def[s_Symbol, v_, vars_List] :=
With[{h = s @@ (Pattern[#, Blank[]] & /@ vars)}, (h := v)]
def[f, x^2, {x}]
f[3]
(* 9 *)
I propose these:
SetAttributes[def, HoldAllComplete]
def[s_Symbol, v_] := SetDelayed @@ Hold[s[x_], v]
def[s_Symbol, v_] := With[{L := s[x_]}, L := v]
def[s_Symbol, v_] := Reverse @ Unevaluated[v := s[x_]]
The HoldAllComplete
(or SequenceHold
) attribute is necessary for an assignment such as:
def[q, Sequence[1, 2, x]]
head[q[5]]
head[1, 2, 5]
Also see:
- Enforcing correct variable bindings and avoiding renamings for conflicting variables in nested scoping constructs