On Tue, Oct 31, 2017 at 01:44:58AM +0000, codephantom via Digitalmars-d wrote: > On Monday, 30 October 2017 at 23:03:12 UTC, H. S. Teoh wrote: > > > > But in D, UFCS allows obj.func() to work for both member functions > > and free functions, so if the client code uses the obj.func() > > syntax, it won't have to care about the difference. > > > > I don't like it. > > When I see obj.func(), to me, func() is a member function. Why should > I spend any time trying to work out whether it's a member function or > a free function? It doesn't make sense to me.
The point is, you *shouldn't have to care*. If I use a library L that provides some type T, and the library provides operation X that I can perform on type T, all I care about is that variables of type T can have X performed on it. Is X a member function? A free function? Who cares! That's just an implementation detail. As the user of library L, how T and X are implemented are none of my business. X can be a remote procedure call to a network service for all I care -- my code doesn't have to know. All it needs to know is that type T can have operation X performed on it. That's the whole point of encapsulation. You *don't have to know* how something is implemented. In fact, it's better that you don't, because later when you upgrade library L, and X changes from member function to free function, or vice versa, *your code doesn't have to change at all*. That's why we care about encapsulation in the first place. Why should *I* have to change my code just because the upstream authors of library L decides that X is better implemented as a free function vs. a member function, or vice versa? I don't care, and I shouldn't have to care. Having the same interface (i.e., UFCS syntax) to call X regardless of how it's implemented is a big advantage, because it frees me, the downstream user, from needing to care about fiddly details of library L's implementation. Instead of upgrading library L and then having to spend 10 hours fixing all my function calls to X, I can just upgrade library L and let the compiler figure out which calls are member functions and which are free functions. My code doesn't have to change one bit. Let the machine do the grunt work, free up the human to do the higher level stuff. The one case where the difference matters is when you're trying to debug something. In that case, I'd say the onus is really upon the debugger to tell you what kind of function it was. Surely the debugger must have this information; it's just a matter of conveying the information to the user adequately. If current tools don't allow you to do this easily, that's a problem with the tools, not with the concept of encapsulation. T -- Государство делает вид, что платит нам зарплату, а мы делаем вид, что работаем.
