Message Boards Message Boards

5 Replies
6 Total Likes
View groups...
Share this post:

How to convert an expression to a function?

Posted 11 years ago
I often develop expressions 'by hand' in MMA by solving, substituting and simplifying. Often I find that I want to use the resulting expression as a function. A very simple example, which doesn't work, would be

In[2]:= expr = Solve[y == a x + b, x][[1, 1, 2]]
Out[2]= (y-b)/a

In[3]:= func[y_, a_, b_] := expr

In[4]:= func[1, 1, 1]
Out[4]= (y-b)/a

The arguments 1, 1, 1 are not evaluated in the function definition. I can paste the expression into the function definition statement after :=, but I want create the function programmatically, as shown above.

I've read the documentation & experimented quite bit, with no success.

Thanks in advance.
POSTED BY: Doug Burkett
5 Replies
Posted 11 years ago
Thanks Nasser; understood.

My example may have been too simple (but your points still stand). After I get the function, I always use it for more than just evaluating a single set of input arguments. I will use it to Plot, or optimize, or generate numerical tables for export, or to build up more complicated functions. Even so, there is probably are better ways in Mathematica to do that, too ...
POSTED BY: Doug Burkett
One can eliminate many "issues" in programming with Mathematica by using a simple rule: Avoid global variables, and build your program from smaller functions up.

In your example, "func[]" was not really function. The example I gave for "func[]" was not a real function either. A real function, is like a mathematical function, it will accept all its input via arguments, and return its output by its final result (what it evaluates to).  If you look at how "func[]" is used above, you will see it updates a global variable called "expr".  So half its input comes via arguments, and then it uses these inputs and applies them on a global variable called "expr". A real function will take all its input from the argument list and would have no side effects other than its result (what it evaluates to).

In your simple example, there was actually no need for a function at all, since the whole operation just needs one computational step and using a function seems a little awkward here. But if you need to do many more computations, then you can start thinking about making a function then. This is really no different than when programming in Fortran or many other languages. (except in Mathematica it takes much less code to do the same thing emoticon
POSTED BY: Nasser M. Abbasi
Posted 11 years ago
Nasser, Shenghui Yang,

Thanks much for the fast responses; obviously helpful & just what I needed.

Nasser, thanks also for the alternatives with transform rules. Even as  beginner, I've used those a bit but not in this context. Also good to learn about Evaluate[], First[] and the @ syntax.

With a prehistoric background in Algol, FORTRAN & various assemblers, it's really challenging (in a good way) for me to learn to code in a MMA-appropriate way. The most frustrating thing now is that I know that there is usually a very simple way to accomplish what I want in Mathematica; my problem is finding it or figuring out. But it is certainly a lot of fun.

I'm sure I'll be back ...
POSTED BY: Doug Burkett
If you wanted to do as you started with, then you need to tell Mathematica to evaluate `expr` in the RHS, like this
expr = x /. First@Solve[y == a x + b, x];
func[y_, a_, b_] := Evaluate@expr;
func[1, 1, 1]
(*  0 *)
Another option is to use transformation Rules, like this
expr = x /. First@Solve[y == a x + b, x];
expr /. {y -> 1, a -> 1, b -> 1}
(* 0 *)
and if you really still want to use a function, you can use transformation rules with that as well. The good thing about using rules is that you do not have to worry about mixing the order of parameters, and it is more clear when reading the code which is a,b and y
 Clear[a, b, y, x]
 expr = x /. First@Solve[y == a x + b, x];
 func[parm_List] := expr /. parm;
 func[{a -> 1, b -> 1, y -> 1}]
 (* 0 *)
 func[{b -> 1, a -> 1, y -> 1}]
 (* 0 *)
 func[{b -> 1, y -> 1, a -> 1}]
(* 0 *)
POSTED BY: Nasser M. Abbasi
 You may use Set(=) instead of Set Delay (:=) here:
f[y_, a_, b_] = expr
In[5]:= f[1, 1, 1]
Out[5]= 0
POSTED BY: Shenghui Yang
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
or Discard

Group Abstract Group Abstract