I don't understand what you mean by "causal" in this context. A.f(B) is just a syntax sugar around f(A, B) unless dynamic dispatch comes into play. Then it's usually syntax sugar around something like:
A._vtable[f](A, B)
It really is just a function of two arguments, even when the privileged first argument looks like it's outside of the parens.
> I don't understand what you mean by "causal" in this context.
I mean that if you want contextual autocompletion (e.g. have only the relevant functions being shown given the type of an argument) then at some point you have to give your IDE this type information before typing the function - however you look at it it will always be [context] [function] instead of [function] [context].
> A.f(B) is just a syntax sugar around f(A, B) unless dynamic dispatch comes into play.
this is a complete implementation detail of your operating system ABI and the way OO languages compile down to it, and in no way a "general truth" (of course there is an equivalence between both). There used to be some CPUs with hardware instructions for OO method calls in the 80s for instance - you may want to call that syntax sugar around electrons, but I would respectfully disagree :-)
(even then, for instance Microsoft has the __thiscall calling convention for C++ methods which differs from __cdecl used for C functions - so even there there are fundamental differences between a.f(b) and f(a, b) as arguments will be passed differently to the method.)