Do non-member functions improve encapsulation in D?
Lars T. Kyllingstad via Digitalmars-d
digitalmars-d at puremagic.com
Mon Apr 21 07:38:51 PDT 2014
On Monday, 21 April 2014 at 14:10:08 UTC, Steven Schveighoffer
wrote:
> [...]
>
> module m1;
> import std.stdio;
>
> class C {}
>
> void foo(C c)
> {
> writeln("C.foo");
> }
>
> void bar(C c)
> {
> writeln("C.bar");
> }
>
> module m2;
> import m1;
> import std.stdio;
>
> void foo(T)(T t)
> {
> writeln("m2.foo");
> }
>
> void bar(T)(T t, int x)
> {
> writeln("m2.bar");
> }
>
> void main()
> {
> auto c = new C;
> c.foo(); // "m2.foo";
> //c.bar(); // error if uncommented!
> }
>
> Basically, I've inadvertently overridden C.foo, without
> intending to. With bar, I've somehow hidden the inherent
> functionality of C!
Wow, I didn't know that. I thought the most specialised function
would always be selected, regardless of which module it's defined
in. What you've demonstrated feels wrong, somehow.
>>> 4. It enforces the "method call" syntax. I.e. you cannot use
>>> foo(obj) call. This may be important for readability.
>>
>> Some would argue that giving users the choice between typing
>> foo(obj) and obj.foo() is a Good Thing, because it doesn't
>> impose your preferences on them. I'm not going to do that,
>> though. ;)
>
> You may recall that I am a big proponent of explicit properties
> because I think the ways of calling functions have strong
> implications to the reader, regardless of the functions. This
> is the same thing. I look at foo(x) much differently than
> x.foo().
And you may recall that I was on the same side as you in the
properties debate, though less vocal about it. (In fact, I think
we didn't go far enough with properties -- we should also forbid
taking their address. But that's another discussion.) The point
is, I lean towards the same view as you when it comes to UFCS,
and only brought up the opposing view for the sake of the
discussion.
I tend to use UFCS only for a few select cases (array range
functions, range chaining, etc.), and to otherwise use the
"normal" function call syntax. If someone sees this in my code:
obj.foo();
I want them to know where to look for further information about
foo(), namely in the class documentation/code.
More information about the Digitalmars-d
mailing list