Strictly, if one knows in advance that y is a function of x, then one should write f(x, y(x)) to make the dependency clear. This just gets unwieldy, though, as anyone who's ever programmed in Mathematica can tell you. However, what if a priori we only know that f is a function of two variables, and then we decide to evaluate it along a path {(x, y(x)): x in reals}? Under your scheme, we'd have to define a new function g(x) = f(x, y(x)) and reason only about g, which is even more painful, not least because maybe g(x) only depends on x through y and could be written more succinctly as g(y(x)).
The current notation is simply more flexible and easier to use, and it remains unambiguous because we have access to these two operators $\dfrac{\partial}{\partial x}$ and $\dfrac{d}{dx}$.