C : Too much code
C++ : Too complex
C# : Too many classes
Perl : No compile time type checking
C++ : Too complex
C# : Too many classes
Perl : No compile time type checking
This. Plus very opinionated decisions in language design, like, "properties" are always bad, "operator overloading" is always bad, but hey, we certainly need "checked exceptions". No, thanks, no java for me...I pretend not to know Java. Concerns about the code it is typically used for.
#include <iostream>
class A {
public:
virtual void f() { std::cout << "A::f\n"; }
A() { f(); }
};
class B : public A {
public:
virtual void f() { std::cout << "B::f\n"; }
B() { f(); }
};
int main() {
B b;
return 0;
}
I would argue that this kind of code is illogical .As for me, the behavior of Java is illogical
In Java - yes, it's better not to write such code. But in C++ such code is quite normal (I think), and the behavior of such code in C++ is well defined (but I don't write such code).Also from the technical side, it's quickly obvious you should just avoid such code, because it's ill-defined. With the "Java model", you'll end up calling a method on an object that isn't (fully) initialized yet.
To the OP: I don't think your perpetual attempts "assessing" programming languages ever leads to something productive. Your "reasons" given here against specific languages are so ridiculously short, they'd be refuted in 1 or 2 sentences each. Instead, better get coding something real and useful, and focus on one language for some time. BTW, in my very personal opinion, C is also a very good choice for that (simple, requires/teaches discipline and some knowledge of how a machine works).
And that's why, in the "C++ model", virtual calls in constructors and destructors don't work.Technically, when a constructor is called, the first operation is to initialize the vptr, the class does not know if there are classes derived from it, and the vptr must refer to the virtual function table of that class. When returning to the constructor of a derived class, that constructor shifts the vptr to its virtual function table.With the "Java model", you'll end up calling a method on an object that isn't (fully) initialized yet.
Didn't you say the result is just calling the current class' version? Which would probably lead to a crash if it's unimplemented (null) in the current class, or do compilers catch that? Anyways, I don't like that kind of behavior, I think it's counter-intuitive. That doesn't mean I like Java's behavior either, because it creates an awesome opportunity to shoot your foot by working on uninitialized data (which you can of course avoid if you're aware, but still). IMHO, the only sane thing for a language (and compilers) to do would be to strictly disallow any call to virtual methods during construction (IOW, issue a compile-time diagnostic and refuse compilation). I'd argue code doing such a thing is a sign of a flawed, likely over-complicated, design, which you should fix.And that's why, in the "C++ model", virtual calls in constructors and destructors don't work.
My implementation in C is only slightly different, first thing done in every construction is indeed something similar (initialize a pointer to some "meta object", which contains a class name and the full vtable), but this starts at the most derived type (it was the most straight-forward thing to do in C). This little difference would in practice lead to Java's behavior. As C doesn't support OOP at the language level, I don't expect any compiler diagnostics here of course, I just don't write code doing virtual calls in the constructor.Technically, when a constructor is called, the first operation is to initialize the vptr, the class does not know if there are classes derived from it,
Yes, that's exactly what I said: first in post 10, then in posts 15 and 17. Simply virtual calls in constructors/destructors become non-virtual/non-polymorphic. Therefore, in C++ the code given in post 10 is quite normal. As for Java, I will still stick to my opinion, which I expressed in post 10.Didn't you say the result is just calling the current class' version?
sbcl & racket are nice.Golang: I only have room for one C/C++ replacement and that's Rust
Ruby: Python is right there
Anything vaguely related to LISP: There's too many, someone would have to pay me