Can I make a function which depends on several arguments which are not independent?

Here's a simple example

Suppose have the permanent relation that z is proportional to xy^2, for real numbers s.

z = s x y^2


Now, we are interested in functions of x,y,z, say:

f[x_,y_,z_] = Sin[x z]-(1-y z Cos[z])^(-1)


Let's say for reasons of interpretation of the system, we do not want to simply replace z by sxy^2 and make a new function always

 g[x_,y_,s_] = Sin[s x^2 y^2] - (1-s x y^3 Cos[s x y^2])^(-1)


This same thing could have been obtained from the first function by just calling:

 f[x, y, s x y^2]


Instead, what I would like to be able to do, is retain the full f[x_,y_,z_], unless I have specifically asked for numerical values of x and y. What I would like is to get

f[x, y, z] = Sin[x z]-(1-y z Cos[z])^(-1)


and

f[2,1,(*something*)] =


to do something a little different. If the first two arguments are numerical, I would like the function to treat the third argument as the proportionality constant s, instead of as z itself.

I suppose I could accomplish this with some kind of If statement? If those arguments are NumberQ false, take the 3rd argument to be z, and if they are both NumberQ True, take the third argument to be s, as in z=s x y^2?

I suppose this question really reduces to can I make a conditional function which differs depending on the argument type?

-

In these situations we use pattern matching instead of conditionals in Mathematica.

You just need to make two definitions:

f[x_?NumericQ, y_?NumericQ, s_] := ...

f[x_, y_, z_] := ...


The first, more specific one will be used if both of the first two arguments are numeric. The second one will be used otherwise.

Personally I consider doing this very bad practice and a "bug-magnet" because it violates the assumption that f[x,y,z] /. {x->1,y->2,z->3} is the same as f[1,2,3] ... but it is possible to do.

-
I appreciate your solution and also your warning. Even as I wrote this question I was cognizant of how shaky a foundation this problem rests on. I will probably spend a fair amount more time on this and perhaps come up with an alternate way of writing my theory altogether. – Steve Mar 5 '14 at 19:10
For what it's worth, the reason for this construction, at all, is that I have expressions which depend on many variable; there is a specific combination of some of the arguments which gives a characteristic scale of energy, and this last argument which is interdependent, we usually wish to examine at precise multiples of this energy quanta, such as 1, 2, or Sqrt[3] times it, for example. Anyway, it may be more trouble than it's worth – Steve Mar 5 '14 at 19:13
@Steve The warning only referred to the two argument types leading to two different types of calculations. I would expect f[x,y,z] /. {x->1,y->2,z->3} to give the same result as f[1,2,3]. Maybe I misunderstood you and you don't actually want these two to return different things. Otherwise using multiple argument "templates" is quite common in Mathematica. – Szabolcs Mar 5 '14 at 19:23