# Construct a function that maps strings to functions

The main question is the last 5 lines (including codes) of this article.

A[x_, y_] := Evaluate[ToExpression["x^2+y^2"]]
A[3,4]


Then the output becomes

25


Following is a slight variation :

F[x_] := Evaluate[ToExpression[x]]
B[x_,y_]:=F["x^2+y^2"]
B[3,4]


The output is not 25 this time. The output is

x^2+y^2


Now I want to construct a function 'Want', so that if I define H as follows

H[x_,y_]:=Want["x^2+y^2"]
H[3,4]


then output becomes

25

• Regarding your comments. I doubt there is a perfect solution given how general your question is. Could you add some background and add details like when is the replacement supposed to happen?, do you want to write a package or use it solely in a notebook workflow? etc etc. – Kuba Sep 16 '19 at 19:22
• honestly, I think what you are trying to achieve is not the best solution to your actual problem and I can see plenty of problems going that route. Can you try to explain the problem that you are trying to solve and why you think you do need this? Manipulating strings instead of expressions is almost always an underestimation of Mathematicas potential to manipulate symbolic expressions... – Albert Retey Sep 17 '19 at 5:39
• Thank you. Frankly sometimes I feel that the easiest and surest way to achieve something is to convert everything to string, and do something, and back to real code. Though not elegant at all. I need time to comment more with an example, in 1~2 days. – imida k Sep 18 '19 at 7:49
• Also note that Want function does not works properly if I define H[x_,y_]:= Map[Want, {"x^2", "y^2"}]. – imida k Sep 18 '19 at 7:56
• It is so difficult.. just converting strings to a working expression. – imida k Sep 18 '19 at 8:01

@Kuba's approach works using up-values, which works very nicely for simple cases as the examples given in the question. However, it does not work if the want["..."] expression is nested deeper inside a held expression, as noted in the comments.

Here is an approach using MakeExpression that processes any expressions of the form want["..."] before any evaluation happens:

MakeExpression[RowBox@{"Want", "[", str_, "]"}, StandardForm] :=
ToExpression[ToExpression@str, StandardForm, HoldComplete]


This works for all cases I can think of:

(* example in question *)
G[x_, y_] := Want["x^2+y^2"]

G[3, 4]
(* 25 *)

G[x_, y_] := Want["x^2+y^2"] + 1

G[3, 4]
(* 26 *)

(* with the string stored in a variable *)
str = "x^2+y^2";
G[x_, y_] := Want[str] + 1

G[3, 4]
(* 26 *)


As noted by @Kuba in the comments, this of course only works if MakeExpression is actually called. Notable exceptions where this is not the case are text-based front-ends and package files imported via Get.

• Thank you. But if you define H[x_,y_]:= Map[Want, {"x^2", "y^2"}], and compute H[3,4], the output is not {9,16}. Can you improve more? – imida k Sep 18 '19 at 8:03
• @imidak In the example you give, H[x_,y_]:=Map[Want,{"x^2","y^2"}] does the trick. In general, this is almost impossible: The names of the function arguments are simply no longer available when Want is evaluated, so there is no way to insert the values. Both mine and @Kuba's solution "solve" this partially by forcing Want[…] to evaluate earlier than usual. As noted in the comments below the question: Can you provide an example of what you actually want to do? Because there is almost certainly a better way. – Lukas Lang Sep 18 '19 at 8:19
Want // ClearAll;

x = 111;

Want /: SetDelayed[lhs_, Want[s_String]] := ToExpression[
s,
InputForm,
Function[rhs, SetDelayed @@ Hold[lhs, rhs], HoldAll]
]

H[x_, y_] := Want["x^2+y^2"]
H[3, 4]


25

• Thank you very much Kuba♦. But with function 'Want' you constructed, one cannot go further. G[x_, y_] := Want["x^2+y^2"] + 1 – imida k Sep 16 '19 at 16:35
• Then output of G[3,4] becomes 1 + Want["x^2+y^2"], not 26. – imida k Sep 16 '19 at 16:37
• Can you construct improved 'Want' function, so that any complicated function whose definition contains 'Want', works well? – imida k Sep 16 '19 at 16:37