# Using module to define a function that calls another function: Should i use set-delayed (:=) or set (=)

Suppose that I have a function f[x_,y_,z_]=x*y*z

and now suppose I want to consider a specific application where z is a function of x and y,

For example, suppose I want to consider z=x^2*y^2

Obviously, in this simple example I could just plug in z and define a new function g[x,y]=x^3*y^3.

But in a more complicated example this is not feasible (for example, what if we instead had f[x_,y_,z_]:= x*y^2*z^3 + x^2*y*z^2 + x^(.2)y^(.8) z^(.1)). I figure a more general approach is to define z[x,y] separately and then evaluate f[x,y,z[x,y]]. I am wondering about using a module to do this

Specifically, consider the following way to define z[x,y] and calculate f[x,y,z[x,y]]: (note: this MWE has typo, see bottom of Question for a fixed version)

g[x_,y_]:=Module[{zfunc},
zfunc[x_,y_]:=x^2*y*2;
f[x,y,zfunc[x,y]]
]


My question is, in the above code, is there a reason to use := when define zfunc[x_,y_] as opposed to using =?

   zfunc[x_,y_]:=x^2*y*2;
g[x_,y_]:=f[x,y,zfunc[x,y]]


then I would want to use :=, because if I redefine zfunc then I want g to be evaluated with this new zfunc. However, in the module zfunc is local, so I think every time I call g the module redefines zfunc, even if i use = instead of :=?

Aside: I realize that a different solution could be to use a named pattern for the z argument, i.e.

f[x_,y_, func_Symbol]:=x*y*func[x,y]

I am not asking about this solution though, I am asking whether, when using module to define z[x_,y] as above, using := is different than using =

Edit: MWE had a typo (and I am leaving it unchanged above because some comments might be useful to others, and may not make sense if I remove the typo)

The MWE should be

f[x_,y_,z_]=x*y*z;
g[x_,y_]:=Module[{zfunc},
zfunc=x^2*y*2;
f[x,y,zfunc]
]


I will also try to rephrase my question, since I have not received an answer:

Question: is there a reason to use zfunc:=x^2*y*2 instead of zfunc=x^2*y*2 in the above MWE?

The usual reasons I think of to use = instead of := are

• Computation time
• Possibility that, in something like f[x]=x^2, x may have been defined earlier already (but this can be avoided by using clear or a module or something)

When using a module like in the MWE, the variable zfunc is local.

• It is my understanding that this means, that every time the module is called Mathematica will define a new variable -- i.e. zfunc$1, zfunc$2 etc -- I imagine that this would erase the computation time benefit of using = versus :=.
• Comments are not for extended discussion; this conversation has been moved to chat. – halirutan Feb 27 '20 at 2:41
• The MWE still seems broken to me. – Jason B. Apr 27 '20 at 14:25
• @JasonB. Yeah, I mentioned this in the comment (now it's moved to the chat), but OP doesn't reply. – xzczd Apr 27 '20 at 14:26
• @JasonB. I think that in the third line of the MWE I meant to type f[x,y,zfunc]. I can't see if that fixes it right now, but when I get a chance I'll do so and respond here. @xzczd, I was not aware of chat, and now is frozen. Sorry. – user106860 Apr 27 '20 at 14:33
• @JasonB. @xzczd the MWE should be fixed now (and should be the equivalent to the function h[x_,y_]:= x^3 *2*y^2 – user106860 Apr 28 '20 at 8:30

Consider using a pure function to represent zfunc. Like so:

f[x_, y_, z_] := x y^2 z^3 + x^2 y z^2 + x^.2 y^.8 z^.1
g[x_, y_] := f[x, y, #1^2 #2^2 &[x, y]]


The definition of g is nicely concise and

g[u, v]


evaluates to

u^6 v^5 + u^7 v^8 + u^0.2 v^0.8 (u^2 v^2)^0.1


much more efficiently than any of the module constructs you show in the question.

• This doesn't directly answer my question, but it is elegant and does the job much better than my example. Thank you. The only potential concern I have with this solution is that, for me at least, the equation for the pure function is harder to identify than if the pure function was on a separate line (I don't know if this is possible though). (This might matter if say, we had f[x_,y_,z_,u_,v_] and wanted to substitute pure functions for z,u, and v. Granted such a situation probably occurs rarely if ever) – user106860 Apr 28 '20 at 8:37
• @user106860 If you don't like pure functions like #1^2 * #2^2&, you can instead do zfunc = Function[{x, y}, x^2 * y^2] in your Module, which is more readable. It is also faster than using a pattern-based function definition (like zfunc[x_, y_] := ...). You can speed it up more by using With instead of Module. – Sjoerd Smit Apr 28 '20 at 9:27
• @SjoerdSmit Thank you! – user106860 Apr 28 '20 at 17:02

I will post a (weak) answer myself:

There is at least one reason to use := instead of = (at least some times).

This reason would be if the definition of zfunc included a condition.

For example, if instead of zfunc=x^2*y*2 we had

zfunc:=x^2/; x>y;
zfunc:= y*2/; x<=y;


Then this above code does not work properly if we instead use set (=).

Note, however, that if we instead use If or Piecewise then we might be able to have zfunc include a condition and still use Set (=) -- I have not looked into this.

There are likely better reasons why one use := over = in this context; I am simply trying to put forward one example.