Stroustrup is disappointed with D :(

2015-09-22 Thread Tourist via Digitalmars-d

"D disappointed me so much when it went the Java way".
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#to-do-unclassified-proto-rules

It's something about virtual calls, but I didn't understand what 
he means. What does he mean?


Re: Stroustrup is disappointed with D :(

2015-09-22 Thread Freddy via Digitalmars-d

On Tuesday, 22 September 2015 at 18:58:31 UTC, Tourist wrote:

"D disappointed me so much when it went the Java way".
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#to-do-unclassified-proto-rules

It's something about virtual calls, but I didn't understand 
what he means. What does he mean?


I doubt he is talking about the whole language. From my skimming 
it seems he is talking about how D copies java's classes.


Re: Stroustrup is disappointed with D :(

2015-09-22 Thread Ziad Hatahet via Digitalmars-d
Perhaps he meant how in Java, methods are virtual by default, unlike C++
where they are final by default.

--
Ziad

On Tue, Sep 22, 2015 at 12:15 PM, Freddy via Digitalmars-d <
digitalmars-d@puremagic.com> wrote:

> On Tuesday, 22 September 2015 at 18:58:31 UTC, Tourist wrote:
>
>> "D disappointed me so much when it went the Java way".
>>
>> https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#to-do-unclassified-proto-rules
>>
>> It's something about virtual calls, but I didn't understand what he
>> means. What does he mean?
>>
>
> I doubt he is talking about the whole language. From my skimming it seems
> he is talking about how D copies java's classes.
>


Re: Stroustrup is disappointed with D :(

2015-09-22 Thread Ali Çehreli via Digitalmars-d

On 09/22/2015 11:58 AM, Tourist wrote:

"D disappointed me so much when it went the Java way".
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#to-do-unclassified-proto-rules


It's something about virtual calls, but I didn't understand what he
means. What does he mean?


It is about virtual calls in ctors and dtors. Here is the problem:

import std.stdio;

class B {
this() {
foo();
}

void foo() {
writeln("base");
}
}

class D : B {
this() {
writeln("derived is only now complete");
}
override void foo() {
writeln("derived");
}
}

void main() {
auto b = new D;
}

Although we are in the middle of consructing a D, the call foo() inside 
B's ctor is dispatched to D's virtual foo() even though the D part of 
the object has not been constructed yet. This is in contrast to C++, 
where the object goes through multiple personalities during its 
construction: First B, then D, etc.


The program above prints

derived
derived is only now complete

As can be seen, D.foo is called before D is ready for use.

Here is the equivalent C++ program:

#include 

using std::cout;

class B {
public:

B() {
foo();
}

virtual ~B() {}

virtual void foo() {
cout << "base\n";
}
};

class D : public B {
public:

D() {
cout << "derived is only now complete\n";
}

virtual void foo() {
cout << "derived\n";
}
};

int main()
{
D d;
}

The output of the C++ program:

base
derived is only now complete

C++'s approach is better from the point of view of corretness. However, 
it is slower because the object's vtbl pointer must be stamped several 
times during construction. (I am not aware of available compiler 
optimizations there.)


Ali



Re: Stroustrup is disappointed with D :(

2015-09-22 Thread Ola Fosheim Grøstad via Digitalmars-d

On Tuesday, 22 September 2015 at 19:38:35 UTC, Ali Çehreli wrote:
C++'s approach is better from the point of view of corretness. 
However, it is slower because the object's vtbl pointer must be 
stamped several times during construction. (I am not aware of 
available compiler optimizations there.)


No dispatch needed if calls it's own functions, so no vtable 
needed for the constructor. But neither approach is good for 
correctness.


(OP: The guidelines have 30 committers or something, I somehow 
doubt Stroustrup wrote all that...)


Re: Stroustrup is disappointed with D :(

2015-09-22 Thread Ali Çehreli via Digitalmars-d

On 09/22/2015 12:52 PM, Ola Fosheim Grøstad wrote:

On Tuesday, 22 September 2015 at 19:38:35 UTC, Ali Çehreli wrote:

C++'s approach is better from the point of view of corretness.
However, it is slower because the object's vtbl pointer must be
stamped several times during construction. (I am not aware of
available compiler optimizations there.)


No dispatch needed if calls it's own functions, so no vtable needed for
the constructor. But neither approach is good for correctness.


Agreed. Only if all potential virtual uses of the object inside the ctor 
can be proven to be to the base's type, then yes, setting the vtbl 
pointer can be elided.


However, it is not possible in general e.g. if the object is passed to a 
function by reference, that function can call any virtual method on it 
so the vtbl pointer must have been set upon entry to the constructor, at 
every level of the hierarchy.



(OP: The guidelines have 30 committers or something, I somehow doubt
Stroustrup wrote all that...)


I tried to determine the actual author. It was not easy and I still 
don't know. :)


Ali



Re: Stroustrup is disappointed with D :(

2015-09-22 Thread John Carter via Digitalmars-d
On Tuesday, 22 September 2015 at 19:52:48 UTC, Ola Fosheim 
Grøstad wrote:

But neither approach is good for correctness.



The approach that would be "Good for Correctness" is "Hey! You're 
doing to much work in a constructor, that's a code smell anyway. 
And invoking virtual methods in a constructor is bound to be 
flaky no matter what the language designer chooses... so don't do 
that."




Re: Stroustrup is disappointed with D :(

2015-09-22 Thread Brad Roberts via Digitalmars-d

On 9/22/15 12:38 PM, Ali Çehreli via Digitalmars-d wrote:

On 09/22/2015 11:58 AM, Tourist wrote:

"D disappointed me so much when it went the Java way".
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#to-do-unclassified-proto-rules



It's something about virtual calls, but I didn't understand what he
means. What does he mean?


It is about virtual calls in ctors and dtors. Here is the problem:


snip for length


Although we are in the middle of consructing a D, the call foo() inside B's 
ctor is dispatched to
D's virtual foo() even though the D part of the object has not been constructed 
yet. This is in
contrast to C++, where the object goes through multiple personalities during 
its construction: First
B, then D, etc.

The program above prints

derived
derived is only now complete

As can be seen, D.foo is called before D is ready for use.

The output of the C++ program:

base
derived is only now complete

C++'s approach is better from the point of view of correctness. However, it is 
slower because the
object's vtbl pointer must be stamped several times during construction. (I am 
not aware of
available compiler optimizations there.)

Ali


Keep in mind there's another core difference between c++ and d here and that is: when member 
variables are set their initial values.  In D, it's before any ctors are called for the full object. 
 In c++ they're split into the parts associated with each step in the hierarchy and set as 
effectively line 0 of the ctor (even though syntactically outside the body of the ctor).  These 
differences are subtle, but can be critical for code that's doing what many would say is too much in 
the ctor.


Re: Stroustrup is disappointed with D :(

2015-09-22 Thread deadalnix via Digitalmars-d
On Tuesday, 22 September 2015 at 19:52:48 UTC, Ola Fosheim 
Grøstad wrote:
On Tuesday, 22 September 2015 at 19:38:35 UTC, Ali Çehreli 
wrote:
C++'s approach is better from the point of view of corretness. 
However, it is slower because the object's vtbl pointer must 
be stamped several times during construction. (I am not aware 
of available compiler optimizations there.)


No dispatch needed if calls it's own functions, so no vtable 
needed for the constructor. But neither approach is good for 
correctness.




You can call super, so you need the virtual dispatch.


Re: Stroustrup is disappointed with D :(

2015-09-22 Thread Ola Fosheim Grøstad via Digitalmars-d

On Tuesday, 22 September 2015 at 20:42:44 UTC, Ali Çehreli wrote:
However, it is not possible in general e.g. if the object is 
passed to a function by reference, that function can call any 
virtual method on it so the vtbl pointer must have been set 
upon entry to the constructor, at every level of the hierarchy.


Ugh, yes, but using "this" externally on a partially constructed 
object is  reeelly ugly... If we want to get closer to 
something not horribly flawed we would have to do something like:


constructor() {
   super();
   this.vtable = super::vtable
   dostuff( this cast as super)
   fully_init_myself()
   this.vtable = myself::vtable;
   domorestuff(this)
}

What a mess...

BTW, the language Beta had type variables that could be virtual. 
It was used for things like the element types for containers. In 
that case the super class could instantiate a specialized type 
provided by subclasses as a virtual type. Kind of neat, but I 
never used it much...


I tried to determine the actual author. It was not easy and I 
still don't know. :)


Me neither. I'm getting the impression that I am looking at a 
wall of guidelines-graffiti.




Re: Stroustrup is disappointed with D :(

2015-09-22 Thread Ola Fosheim Grostad via Digitalmars-d

On Tuesday, 22 September 2015 at 21:25:06 UTC, deadalnix wrote:

You can call super, so you need the virtual dispatch.


I understand Ali's argument about setting local vtable before 
calling external functions in C++, but other than that it should 
be sufficient to set vtable in the new() or equivalent topmost 
call?


Re: Stroustrup is disappointed with D :(

2015-09-22 Thread deadalnix via Digitalmars-d
On Tuesday, 22 September 2015 at 22:09:59 UTC, Ola Fosheim 
Grostad wrote:

On Tuesday, 22 September 2015 at 21:25:06 UTC, deadalnix wrote:

You can call super, so you need the virtual dispatch.


I understand Ali's argument about setting local vtable before 
calling external functions in C++, but other than that it 
should be sufficient to set vtable in the new() or equivalent 
topmost call?


It is part of the .init, so the compiler would set it BEFORE 
calling the constructor. constructor can then call each other and 
rely on the fact that the vtable is initialized.


However, constructor need to do the virtual dispatch as one can 
call super.


Re: Stroustrup is disappointed with D :(

2015-09-22 Thread Steven Schveighoffer via Digitalmars-d

On 9/22/15 3:38 PM, Ali Çehreli wrote:

On 09/22/2015 11:58 AM, Tourist wrote:

"D disappointed me so much when it went the Java way".
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#to-do-unclassified-proto-rules



It's something about virtual calls, but I didn't understand what he
means. What does he mean?


It is about virtual calls in ctors and dtors. Here is the problem:

import std.stdio;

class B {
 this() {
 foo();
 }

 void foo() {
 writeln("base");
 }
}

class D : B {
 this() {
 writeln("derived is only now complete");
 }
 override void foo() {
 writeln("derived");
 }
}

void main() {
 auto b = new D;
}

Although we are in the middle of consructing a D, the call foo() inside
B's ctor is dispatched to D's virtual foo() even though the D part of
the object has not been constructed yet. This is in contrast to C++,
where the object goes through multiple personalities during its
construction: First B, then D, etc.

The program above prints

derived
derived is only now complete

As can be seen, D.foo is called before D is ready for use.

Here is the equivalent C++ program:

#include 

using std::cout;

class B {
public:

 B() {
 foo();
 }

 virtual ~B() {}

 virtual void foo() {
 cout << "base\n";
 }
};

class D : public B {
public:

 D() {
 cout << "derived is only now complete\n";
 }

 virtual void foo() {
 cout << "derived\n";
 }
};

int main()
{
 D d;
}

The output of the C++ program:

base
derived is only now complete

C++'s approach is better from the point of view of corretness. However,
it is slower because the object's vtbl pointer must be stamped several
times during construction. (I am not aware of available compiler
optimizations there.)

Ali



Yeah, but you can't do this in C++ though:

class D : B {
   this()
   {
  writeln("derived is only now complete");
  super();
   }
}

I find the ability to control the construction order far more important 
than virtual calls for base constructors.


-Steve


Re: Stroustrup is disappointed with D :(

2015-09-22 Thread Ola Fosheim Grostad via Digitalmars-d

On Tuesday, 22 September 2015 at 22:14:56 UTC, deadalnix wrote:
It is part of the .init, so the compiler would set it BEFORE 
calling the constructor. constructor can then call each other 
and rely on the fact that the vtable is initialized.


We were discussing  the cost if doing it like c++, where virtual 
calls during construction acts as if the object isn't subclassed. 
That way all object local member function calls can be 
devirtualized and inlined. In D we have to use the init method 
you mention.


Re: Stroustrup is disappointed with D :(

2015-09-22 Thread Ola Fosheim Grøstad via Digitalmars-d
On Tuesday, 22 September 2015 at 23:21:20 UTC, Steven 
Schveighoffer wrote:

Yeah, but you can't do this in C++ though:

class D : B {
   this()
   {
  writeln("derived is only now complete");
  super();
   }
}

I find the ability to control the construction order far more 
important than virtual calls for base constructors.


You could do it in old C++ compilers, and some have a permissive 
switch that allows you to do it, but you should not do it. It 
leads to incorrect initialization and breaks encapsulation 
(unsound typing). Forcing construction order is a Good Thing.


In Beta, the successor to Simula, all execution follows this 
pattern:


this(){
   begin_prepare_stuff();
   subclass.this();
   end_prepare_stuff();
}

This way the superclass defines what you can override which is 
better for correctness.




Re: Stroustrup is disappointed with D :(

2015-09-23 Thread Mengu via Digitalmars-d
On Tuesday, 22 September 2015 at 19:52:48 UTC, Ola Fosheim 
Grøstad wrote:
On Tuesday, 22 September 2015 at 19:38:35 UTC, Ali Çehreli 
wrote:
C++'s approach is better from the point of view of corretness. 
However, it is slower because the object's vtbl pointer must 
be stamped several times during construction. (I am not aware 
of available compiler optimizations there.)


No dispatch needed if calls it's own functions, so no vtable 
needed for the constructor. But neither approach is good for 
correctness.


(OP: The guidelines have 30 committers or something, I somehow 
doubt Stroustrup wrote all that...)


we can always do a git blame :-D


Re: Stroustrup is disappointed with D :(

2015-09-23 Thread ponce via Digitalmars-d

On Tuesday, 22 September 2015 at 18:58:31 UTC, Tourist wrote:

"D disappointed me so much when it went the Java way".
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#to-do-unclassified-proto-rules

It's something about virtual calls, but I didn't understand 
what he means. What does he mean?


I fail to see how the multi-part C++ object initialization is any 
better than the one of D.
It just is very simple in D: first assign .init, then call the 
destructor, virtual calls allowed (of course!).


The weird rules of virtual functions in ctor/dtor in C++ just 
feel like one more special case. It doesn't even seem more 
efficient, quite the contrary. But it makes good interview 
questions I guess.




Re: Stroustrup is disappointed with D :(

2015-09-23 Thread ponce via Digitalmars-d

On Wednesday, 23 September 2015 at 08:27:43 UTC, ponce wrote:

On Tuesday, 22 September 2015 at 18:58:31 UTC, Tourist wrote:

"D disappointed me so much when it went the Java way".
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#to-do-unclassified-proto-rules
It just is very simple in D: first assign .init, then call the 
destructor, virtual calls allowed (of course!).




the call the *constructor*



Re: Stroustrup is disappointed with D :(

2015-09-23 Thread Ola Fosheim Grøstad via Digitalmars-d

On Wednesday, 23 September 2015 at 08:27:43 UTC, ponce wrote:
I fail to see how the multi-part C++ object initialization is 
any better than the one of D.
It just is very simple in D: first assign .init, then call the 
destructor, virtual calls allowed (of course!).


The combination of being able to override most member functions 
and them being called in super constructors makes for a brittle 
inheritance mechanism. If virtual was explicit and the superclass 
could make some parts of the virtual function non-overridable 
then it would be less problematic.


The weird rules of virtual functions in ctor/dtor in C++ just 
feel like one more special case. It doesn't even seem more 
efficient, quite the contrary.


Devirtualized inlining is trivially more efficient than virtual 
calls...


Re: Stroustrup is disappointed with D :(

2015-09-23 Thread Ola Fosheim Grøstad via Digitalmars-d
On Wednesday, 23 September 2015 at 06:06:42 UTC, Ola Fosheim 
Grøstad wrote:
In Beta, the successor to Simula, all execution follows this 
pattern:


this(){
   begin_prepare_stuff();
   subclass.this();
   end_prepare_stuff();
}


Actually, this was how Simula did it too. If you didn't provide 
the slot for the subclass constructor ("inner") it would inject 
it at the end. Unfortunately C++ didn't add the slot, and just 
mimics default construction in Simula...


But Beta is actually much more powerful than I suggested, more 
like this (Cish syntaxification):


B {
  int x,y,a,b,sum;

  virtual init1 {
int aa;
enter(aa,b);
b = b*2;
inner;
a = aa;
  }

  enter (a,b,x,y);
  enter (init1,(x,y));

  sum = 0;
  inner;
  sum  = sum + x + y + a + b;
}

D : B {
  int z;
  init1 : super.init1 {
 z = aa+b;
 inner;
  }
  sum = sum + z;
  inner;
}

"enter" is the parameter list, the compiler will pick the one 
that matches the tuple and execute it before it executes the body.


"inner" is where you inject code when specializing.

(Beta is a very minimal stackless language, it does not 
differentiate between construction and function call. Which bring 
some other problems.)




Re: Stroustrup is disappointed with D :(

2015-09-23 Thread Kagamin via Digitalmars-d
On Wednesday, 23 September 2015 at 09:09:53 UTC, Ola Fosheim 
Grøstad wrote:
The weird rules of virtual functions in ctor/dtor in C++ just 
feel like one more special case. It doesn't even seem more 
efficient, quite the contrary.


Devirtualized inlining is trivially more efficient than virtual 
calls...


Called methods call other virtual methods and you can't inline 
the entire call tree.


Re: Stroustrup is disappointed with D :(

2015-09-23 Thread Nemanja Boric via Digitalmars-d
On Tuesday, 22 September 2015 at 21:28:27 UTC, Ola Fosheim 
Grøstad wrote:


I tried to determine the actual author. It was not easy and I 
still don't know. :)


Me neither. I'm getting the impression that I am looking at a 
wall of guidelines-graffiti.


It was introduced in this commit:

https://github.com/isocpp/CppCoreGuidelines/commit/947cf3affcdfc392a316a32f73cdea7383ae55bd




Re: Stroustrup is disappointed with D :(

2015-09-23 Thread Steven Schveighoffer via Digitalmars-d

On 9/23/15 2:06 AM, Ola Fosheim Grøstad wrote:

On Tuesday, 22 September 2015 at 23:21:20 UTC, Steven Schveighoffer wrote:

Yeah, but you can't do this in C++ though:

class D : B {
   this()
   {
  writeln("derived is only now complete");
  super();
   }
}

I find the ability to control the construction order far more
important than virtual calls for base constructors.


You could do it in old C++ compilers, and some have a permissive switch
that allows you to do it, but you should not do it. It leads to
incorrect initialization and breaks encapsulation (unsound typing).
Forcing construction order is a Good Thing.


You can do it in C++ via initializers too, just not as useful. D still 
enforces sound construction.


-Steve


Re: Stroustrup is disappointed with D :(

2015-09-23 Thread Ola Fosheim Grøstad via Digitalmars-d
On Wednesday, 23 September 2015 at 13:14:54 UTC, Steven 
Schveighoffer wrote:
You can do it in C++ via initializers too, just not as useful. 
D still enforces sound construction.


The key quality for a good OO paradigm is that you can 
independently modify super-classes and sub-classes in an 
encapsulated way without knowing the concrete implementation of 
the other.


Like most languages C++ and D does not ensure sound object 
construction, but C++ is a bit better than D. When you allow 
super() to be called in arbitrary locations then modifications of 
ancestor classes are much more likely to cause issues for 
subclasses. So that approach does not scale.




Re: Stroustrup is disappointed with D :(

2015-09-23 Thread Steven Schveighoffer via Digitalmars-d

On 9/23/15 9:48 AM, Ola Fosheim Grøstad wrote:

On Wednesday, 23 September 2015 at 13:14:54 UTC, Steven Schveighoffer
wrote:

You can do it in C++ via initializers too, just not as useful. D still
enforces sound construction.


The key quality for a good OO paradigm is that you can independently
modify super-classes and sub-classes in an encapsulated way without
knowing the concrete implementation of the other.


Any usage of virtual functions by the base class ctor is bound to be 
something that is known by the derived class author. In fact, it's 
likely to be a feature.


If the base ctor doesn't call any virtual functions, when it's 
constructed doesn't really matter.



Like most languages C++ and D does not ensure sound object construction,
but C++ is a bit better than D. When you allow super() to be called in
arbitrary locations then modifications of ancestor classes are much more
likely to cause issues for subclasses. So that approach does not scale.


I don't see how you come to that conclusion. The derived class must 
control construction of the base class. All D does is allow you to write 
code that can build the parameters for the base class to use for 
construction, instead of forcing you to write it in one expression like C++.


It requires slightly more careful thought (and some rules from the 
compiler), but it scales just fine. We don't have to be purists for a 
paradigm to reap the benefits.


-Steve


Re: Stroustrup is disappointed with D :(

2015-09-23 Thread Ola Fosheim Grøstad via Digitalmars-d
On Wednesday, 23 September 2015 at 14:01:11 UTC, Steven 
Schveighoffer wrote:
If the base ctor doesn't call any virtual functions, when it's 
constructed doesn't really matter.


1. In D members are virtual by default, so the virtuality can be 
a mistake.


2. In D/C++ you can do full override of virtual members, that 
means that enforcing semantics are delegated to documentation and 
code review. This is a flaw inherited from Simula.


I don't see how you come to that conclusion. The derived class 
must control construction of the base class.


No, this is not how it is done in Simula/Beta. The construction 
is controlled from the base classes and follows the inheritance 
chain.


Doing construction in the opposite direction is a C++ flaw, 
probably related to C.


But neither C/C++ are good role models when it comes to typing.

It requires slightly more careful thought (and some rules from 
the compiler), but it scales just fine.


I don't think it scales "just fine". OO in C++ does not scale 
fine either. If you easily can break the super-class semantics in 
a sub-class then it does not scale. Alias this suffers from 
similar issues.




Re: Stroustrup is disappointed with D :(

2015-09-23 Thread Ali Çehreli via Digitalmars-d

On 09/23/2015 05:16 AM, Nemanja Boric wrote:

On Tuesday, 22 September 2015 at 21:28:27 UTC, Ola Fosheim Grøstad wrote:



I tried to determine the actual author. It was not easy and I still
don't know. :)


Me neither. I'm getting the impression that I am looking at a wall of
guidelines-graffiti.


It was introduced in this commit:

https://github.com/isocpp/CppCoreGuidelines/commit/947cf3affcdfc392a316a32f73cdea7383ae55bd



I had hit that one but the quoted phrase does not appear on that page. 
Is that diff abridged? Oh I see: It says "11,900 additions, 0 deletions 
not shown".


Ali



Re: Stroustrup is disappointed with D :(

2015-09-23 Thread Joakim via Digitalmars-d
On Wednesday, 23 September 2015 at 17:49:28 UTC, Ali Çehreli 
wrote:

On 09/23/2015 05:16 AM, Nemanja Boric wrote:
On Tuesday, 22 September 2015 at 21:28:27 UTC, Ola Fosheim 
Grøstad wrote:


I tried to determine the actual author. It was not easy and 
I still

don't know. :)


Me neither. I'm getting the impression that I am looking at a 
wall of

guidelines-graffiti.


It was introduced in this commit:

https://github.com/isocpp/CppCoreGuidelines/commit/947cf3affcdfc392a316a32f73cdea7383ae55bd



I had hit that one but the quoted phrase does not appear on 
that page. Is that diff abridged? Oh I see: It says "11,900 
additions, 0 deletions not shown".


That is the original commit, which was written and edited by a 
group, so git is no use.


The reddit discussion of the blog post announcing the guidelines 
has a fair amount of positive comments about D:


https://www.reddit.com/r/programming/comments/3ltwwf/bjarne_stroustrup_announces_c_core_guidelines/