Do non-member functions improve encapsulation in D?
Steven Schveighoffer via Digitalmars-d
digitalmars-d at puremagic.com
Mon Apr 21 07:10:08 PDT 2014
On Mon, 21 Apr 2014 09:46:18 -0400, Lars T. Kyllingstad
<public at kyllingen.net> wrote:
> On Monday, 21 April 2014 at 12:45:12 UTC, Steven Schveighoffer wrote:
>> 3. There is zero chance of a conflict with another type's similarly
>> named method.
>
> How? If you have the following functions:
>
> void foo(A a);
> void foo(B b);
>
> and you write
>
> foo(new B);
>
> there is also zero chance of conflict -- even if B happens to be a
> subclass of A, since the most specialised function is always called.
Demonstration:
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!
>
>> 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().
It's the same (though not quite as important) as choosing a good name for
a function.
-Steve
More information about the Digitalmars-d
mailing list