On Tuesday, 18 August 2015 at 07:19:02 UTC, BBasile wrote:
On Tuesday, 18 August 2015 at 06:27:53 UTC, Ozan wrote:
On Monday, 17 August 2015 at 06:59:51 UTC, BBasile wrote:
On Monday, 17 August 2015 at 05:57:52 UTC, Ozan wrote:
Hi
[...]
Is there any way to get real OOP with D?
Regards, Ozan
Can you name an OOP oriented language that allows this ? Your
example is eroneous OOP.
The 2 other answers you 've got (the first using an interface
and the second using an abstract class) are valid OOP.
One of the fundamental concept OOP is that a function defined
in a class exists also in its subclasses. So how do you
expect `greeting()` to exist in Family if it's only defined
in its sub-classes ?
You can verify that with the 'Liskov substitution principle'
(https://en.wikipedia.org/wiki/Liskov_substitution_principle).
Actually your sample violates this principle.
Languages like Groovy or JavaScript (with the help of
frameworks ;-)
And I believe many more the newer ones. But that's not the
point.
And... This was not a criticism against D (... "bad D, has no
understanding of OOP. Boahh" ;-)
It was only a question about handling of a typical OOP problem
in a class-typed implementation of OOP like D has. Thanks to
every existing or new creative programming language, today we
have so many other ways to solve our programming problems.
Regards Ozan
You example is not valid strongly-typed OOP. In D you could do
something similar but not with the OO paradigm but rather with
compile-time refexion (introspection):
---
import std.stdio;
static bool isFamilyMember(T)()
{
import std.traits: isCallable;
return __traits(hasMember, T, "greeting");
}
void FamilyMemberSayHello(T)(ref T t)
{
static if (isFamilyMember!T)
t.greeting;
}
struct Dad{
void greeting(){"hello from a Dad".writeln;}
}
struct Boy{
void greeting(){"hello from a Boy".writeln;}
}
struct IdiotDuBled{}
void main()
{
auto dad = new Dad;
auto boy = new Boy;
auto idiotDuBled = new IdiotDuBled;
FamilyMemberSayHello(dad);
FamilyMemberSayHello(boy);
FamilyMemberSayHello(idiotDuBled);
}
---
The idea is rather to check at compile time if a variable will
have the "trait" which characterizes a FamilyMember, without
using inheritence.
I believe D allows what you want to do using generic programming.
Being a compiled and strongly typed language, the information
about the type, needs to be available during compilation, but
this makes no difference from a theoretic OOP view.
BBasiles example can also be done without the trait. Then the
check for greeting() will be done by the compiler.
void FamilyMemberSayHello(T)(ref T t)
{
t.greeting;
}
struct Dad{
void greeting(){"hello from a Dad".writeln;}
}
struct Boy{
void greeting(){"hello from a Boy".writeln;}
}
struct IdiotDuBled{}
void main()
{
auto dad = new Dad;
auto boy = new Boy;
auto idiotDuBled = new IdiotDuBled;
FamilyMemberSayHello(dad);
FamilyMemberSayHello(boy);
FamilyMemberSayHello(idiotDuBled); //will not compile
}
The OOP Model of D is fairly close to that of Eiffel which I
consider pretty pure Object Oriented. The only exception is
multiple inheritance, which I do not miss at all.
In my Opinion D is a great language for Object Oriented Design
and Programming.
It awesomely supports Contracts and Constraint Generics, which
many languages lack.
I never missed multiple inheritance, as I was able to cover all
my use cases with mixins.
The support for functional programming and CTFE allows to
elegantly handle the cases, where inheritance based OOP feels
awkward.
Actually I urge all the people who say: "Smalltalk was the last
(only) good OOP language!" to try out D.