# Keep irrelevant variables outside function arguments

I want to define several functions of variables x,y say

f1[x_,y_]:=x^2+y
f2[x_,y_]:=f1[x_,y_]+x f1[x,y]
f3[x_,y_]:=D[f1[x,y],x]+f2[x+1,y]


Here the x variable is crucial for relation between functions while the other one y kinda just hangs in the background. It is tedious and not instructive to write it out explicitly when defining all these functions. I would like to somehow get rid of this explicit dependence on y in the notation, in the spirit of mathematical notation when one only writes relevant arguments keeping in mind that there may be other. Eventually the final function needs to be called with y specified, but in the intermediate computations it can be assumed fixed. Is there a way to implement this?

Clear["Global*"]

f1[x_, y_ : y] := x^2 + y
f2[x_, y_ : y] := (1 + x) f1[x, y]
f3[x_, y_ : y] := Derivative[1, 0][f1][x, y] + f2[x + 1, y]


In each case, the second argument is optional and defaults to y.

{f1[x, y] == f1[x], f2[x, y] == f2[x], f3[x, y] == f3[x]}

(* {True, True, True} *)

{f1[x], f2[x], f3[x]}

(* {x^2 + y, (1 + x) (x^2 + y), 2 x + (2 + x) ((1 + x)^2 + y)} *)


Note the form of the derivative in the definition of f3. Using D would prevent the function from evaluating if the first argument were numeric.

f3

(* 2 + 3 (4 + y) *)

f3[1, 1]

(* 17 *)


EDIT: If you merely want to treat y as a global variable

Clear["Global*"]

f1[x_] := x^2 + y
f2[x_] := (1 + x) f1[x]
f3[x_] := Derivative[f1][x] + f2[x + 1]

{f1[x], f2[x], f3[x]}

(* {x^2 + y, (1 + x) (x^2 + y), 2 x + (2 + x) ((1 + x)^2 + y)} *)

f3

(* 2 + 3 (4 + y) *)

f3 /. y -> 1

(* 17 *)


Or for efficiency (i.e., to avoid multiple calculations of the derivative) change the definition of f3 by either

Changing SetDelayed to Set

Clear[f3]

f3[x_] = Derivative[f1][x] + f2[x + 1]

(* 2 x + (2 + x) ((1 + x)^2 + y) *)


Or Evaluate the RHS of the SetDelayed

Clear[f3]

f3[x_] := Evaluate[Derivative[f1][x] + f2[x + 1]]

?f3 • Hi! Sorry, but in your code I see more notation, not less (f[x_,y_:y] instead of just f[x_,y_]). Maybe I have not expressed myself clearly. Say I want to make a small package/(piece of code) within which y does not change, the exported function being f3. Is there a way to use call f3[x,y] with y as a normal variable outside the package, but not drag y around in the implementation, say setting it as a global symbolic variable. Maybe this is a different question altogether, sorry then. Aug 7 '20 at 6:59