March 19, 2012 Re: Why not finally allow bracket-less top-level keywords? | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix | deadalnix wrote: > As all functionnality of a Ship are final, you basically ends up with a mother ship that is a ship and then have some other function that are de facto separated and unreachable from ship. Yes, because Ship is designed to be the common denominator among Ship types. This is not a problem, it's simply the far right side of access-limitation. There's no need to abstract the type (as you suggest below) simply because the base class went one function "to tight". > Separation of concerns tells us that this should be 2 different objects. MotherShip is still concerned with being a Ship. It's intended as a Ship, and should be classified as such. Removing the ability to express this only forces coders into needlessly wrapping functions: class Ship { final void fire() {} } class Bomber : Ship { void bomb() {} } void main() { auto b = new Bomber(); b.fire(); // can fire() like other Ships automatically } vs: class Bomber { Ship ship; void fire() { ship.fire(); } // have to wrap this } This would be very annoying if you had many functions in the base class and would probably lead the authors writing a single unused virtual function into the base, just so they could derive types from it. > As teha ddition of MotherShip to Ship are orthogonal, I would argue that mothership functionality is better suited for its own class/struct/whatever, and agregated with a ship. A Ship wrapper is not conceptually a Ship. Nor could you cast a Ship pointer to it. All you're doing by aggregating types is complicating the structure for no-gain and loosing expression in the process. |
March 23, 2012 Re: virtual-by-default rant | ||||
---|---|---|---|---|
| ||||
Posted in reply to F i L | Am Sun, 18 Mar 2012 04:49:12 +0100
schrieb "F i L" <witte2008@gmail.com>:
> On Sunday, 18 March 2012 at 03:27:40 UTC, bearophile wrote:
> > F i L:
> >
> >> I'm a bit confused. Reading through the virtual function's docs (http://dlang.org/function.html#virtual-functions) it says:
> >>
> >> "All non-static non-private non-template member functions are virtual. This may sound inefficient, but since the D compiler knows all of the class hierarchy when generating code, all functions that are not overridden can be optimized to be non-virtual."
> >
> > This is so much theoretical that I think this should be removed from the D docs. And to be put back when one DMD compiler is able to do this. Otherwise it's just false advertising :-)
> >
> > Bye,
> > bearophile
>
> Dammit, I was afraid someone would say something like that. Well at least it's a good goal. It is a bit of false advertising though, honestly it should just be marked "implementation in progress" or something like that.
>
"the D compiler knows all of the class hierarchy when generating code"
This is just wrong, and if that was the base for deciding on virtual as default, I believe it is natural to think about it again.
Otherwise it should read "if you deal with non exported classes and don't use incremental compilation as well as refrain from compiling your code into static libraries, a D compiler can optimize methods to be non-virtual. As of the time of writing [...] no such compiler exists."
Now I feel better :)
-- Marco
|
March 23, 2012 Re: virtual-by-default rant | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marco Leise | Marco Leise wrote:
> "the D compiler knows all of the class hierarchy when generating code"
> This is just wrong, and if that was the base for deciding on virtual as default, I believe it is natural to think about it again.
Yes, further reading has led me to believe that Manu is right in his request for a virtual keyword (at least). Final by default is a great concept on paper, but unless it's possible across Lib boundaries (which I'm not sure it is) then to me it does seem a bit backwards given that efficiency is a key feature of D and most programmers are already used to fixed by default anyways.
|
March 23, 2012 Re: virtual-by-default rant | ||||
---|---|---|---|---|
| ||||
Posted in reply to F i L | On 03/23/2012 02:47 PM, F i L wrote:
> ... and most programmers are already used
> to fixed by default anyways.
>
This assertion is unjustified.
|
March 23, 2012 Re: virtual-by-default rant | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Friday, 23 March 2012 at 13:58:00 UTC, Timon Gehr wrote:
> On 03/23/2012 02:47 PM, F i L wrote:
>> ... and most programmers are already used
>> to fixed by default anyways.
>>
>
> This assertion is unjustified.
Given that the four most popular languages today (Java, C, C++, and C#) all function this way, I'd say it's fairly accurate. But I also didn't to say Final by default should be default in D (though I wouldn't really disagree with that direction either), I do think D should have a virtual keyword.
|
March 23, 2012 Re: virtual-by-default rant | ||||
---|---|---|---|---|
| ||||
Posted in reply to F i L | > Given that the four most popular languages today (Java, C, C++, and C#) all function this way, I'd say it's fairly accurate. But I also didn't to say Final by default should be default in D (though I wouldn't really disagree with that direction either), I do think D should have a virtual keyword.
Whoops, that's wrong. Java is virtual by default. So I guess you're right, my statements aren't really justified.
|
March 23, 2012 Re: virtual-by-default rant | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | On 3/18/12 9:23 AM, Manu wrote:
> The virtual model broken. I've complained about it lots, and people
> always say "stfu, use 'final:' at the top of your class".
>
> That sounds tolerable in theory, except there's no 'virtual' keyword to
> keep the virtual-ness of those 1-2 virtual functions I have... so it's
> no good (unless I rearrange my class, breaking the logical grouping of
> stuff in it).
> So I try that, and when I do, it complains: "Error: variable
> demu.memmap.MemMap.machine final cannot be applied to variable",
> allegedly a D1 remnant.
> So what do I do? Another workaround? Tag everything as final individually?
>
> My minimum recommendation: D needs an explicit 'virtual' keyword, and to
> fix that D1 bug, so putting final: at the top of your class works, and
> everything from there works as it should.
Is virtual-ness your performance bottleneck?
|
March 23, 2012 Re: virtual-by-default rant | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ary Manzana Attachments:
| On 23 March 2012 17:24, Ary Manzana <ary@esperanto.org.ar> wrote:
> On 3/18/12 9:23 AM, Manu wrote:
>
>> The virtual model broken. I've complained about it lots, and people always say "stfu, use 'final:' at the top of your class".
>>
>> That sounds tolerable in theory, except there's no 'virtual' keyword to
>> keep the virtual-ness of those 1-2 virtual functions I have... so it's
>> no good (unless I rearrange my class, breaking the logical grouping of
>> stuff in it).
>> So I try that, and when I do, it complains: "Error: variable
>> demu.memmap.MemMap.machine final cannot be applied to variable",
>> allegedly a D1 remnant.
>> So what do I do? Another workaround? Tag everything as final individually?
>>
>> My minimum recommendation: D needs an explicit 'virtual' keyword, and to fix that D1 bug, so putting final: at the top of your class works, and everything from there works as it should.
>>
>
> Is virtual-ness your performance bottleneck?
>
Frequently. It's often the most expensive 'trivial' operation many
processors can be asked to do. Senior programmers (who have much better
things to waste their time on considering their pay bracket) frequently
have to spend late nights mitigating this even in C++ where virtual isn't
default. In D, I'm genuinely concerned by this prospect. Now I can't just
grep for virtual and fight them off, which is time consuming alone, I will
need to take every single method, one by one, prove it is never overloaded
anywhere (hard to do), before I can even begin the normal process of
de-virtualising it like you do in C++.
The problem is elevated by the fact that many programmers are taught in
university that virtual functions are okay. They come to the company, write
code how they were taught in university, and then we're left to fix it up
on build night when we can't hold our frame rate. virtual functions and
scattered/redundant memory access are usually the first thing you go
hunting for. Fixing virtuals is annoying when the system was designed to
exploit them, it often requires some extensive refactoring, much harder to
fix than a bad memory access pattern, which might be as simple as
rearranging a struct.
|
March 23, 2012 Re: virtual-by-default rant | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | Something that *might* help is to do unit tests. Yeah, that's kinda ass, but it would catch a stray virtual early. Do a unit test that does a traits check for virtuals: http://dlang.org/traits.html#getVirtualFunctions if the name isn't on a list of approved virtuals, static assert fail. You'd then maintain the list of approved virtuals in the unit test, where it is easier to check over. idk though, I've never worked on a project like this. |
March 24, 2012 Re: virtual-by-default rant | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe Attachments:
| On 23 March 2012 21:11, Adam D. Ruppe <destructionator@gmail.com> wrote: > Something that *might* help is to do unit tests. Yeah, that's kinda ass, but it would catch a stray virtual early. > They're not necessarily 'stray' virtuals, they're inappropriate ones There's a time and place for virtuals, but there's many more times and places they shouldn't be :) It's nice to be able to skim a class and see 'virtual' written clearly all over it to gather some basic performance/usage information about the class. The visual cue is important, and the ability to grep for them. Rememer that virtuals are Do a unit test that does a traits check for virtuals: > > http://dlang.org/traits.html#**getVirtualFunctions<http://dlang.org/traits.html#getVirtualFunctions> > > if the name isn't on a list of approved virtuals, > static assert fail. > I've said this all before, but I'll repeat my general reasoning on the issue. My objection to virtual-by-default, but, acknowledging that can't be changed, insistence on a virtual keyword is this. (uh oh, manu-rant alert) :P The top most compelling reason for switching from an extremely mature, efficient, reliable, commercially accepted language like C/C++ to something still relatively experimental (D) is to simplify code and maintenance long term. The goal is to do the same work we already do with less lines of code. They should also be cleaner, tidier, less confusing, more informative lines of code. Adding a system like you describe to validate virtuals is not a complexity I'm interested in implementing, it is just one clear reason to sick with C++. Imagine presenting that to a building full of programmers who are sceptical about changing from C++ in the first place? What will they make of such a crude requirement when they already have a perfectly good virtual keyword in C++? D offers some amazing steps forwards in terms of powerful meta-programming. Many typical C/C++ systems that require maintaining (and synchronising) ugly tables of data, enums, stupid little functions and macros to do trivial stuff; these can largely be removed in D. It is possible to invent systems that take code and comprehend it implicitly, generating the desired functionality, without having to pollute the classes themselves with extra rubbish used by such a generator (see: user attributes thread). Removing this sort of crap is something everyone can appreciate. But if we have to revert to this behaviour to work around a different set of problems, then we haven't really gained anything. Code that remains tidy and maintainable for 10+ years (common in gamedev, game engines live ~2 console generations on average, often longer), but is still very fluid and dynamic (how gamedev code differs from other enterprise code, it changes frequently), and doesn't degrade in performance due to added complexity over years, is, fundamentally, SIMPLE code. It is also *LESS* code, the fewer lines, the more maintainable as a rule. And most certainly, code WITHOUT explicit tables of codegen related data; these are always the first things to rot and fall out of sync. There are often weird ancillary systems grown around these things to try and auto-magically maintain them, which themselves are just redundant noise, and contributes to further complexity and eventual bitrot. I've seen it time and time again. This is C++'s biggest shortcoming; the language only goes 90% of the way, and untold complexity is added to achieve the final 10%. These such sorts of tables are why I fear an enum based serialisation system, or an enum based virtual function verification system. Who maintains these tables? It's only a matter of time before some clever bugger comes along and writes some fancy system to auto-magically manage these tables, and then every other programmer comes along, has no idea what to make of it anymore, and wonders what said clever bugger was smoking. This is just how it works out in practise. Then said clever bugger quits... >_< This is one of the key pains I hope to eliminate by using D, but I can't trade performance for it. The bar is high, competition is staunch, games consoles are fixed hardware. All the performance tuning mechanisms available in C/C++ must also be available in D (and generally are, plus more waiting to be taken advantage of). I shouldn't need to add complex workarounds for something so trivial as the missing virtual keyword :) Side note.. I'm a language nerd, and I get excited by D, but I'm trying to think critically about transplanting it realistically into the commercial environment. I know what happens there, and it can only be adopted if a significant numer of C++'s shortcoings are overcome, AND no new shortcomings are added in the process. Most people aren't interested in D, they may be sceptical and apprehensive to abandon something with 40 years of maturity and a whole industry of support. They will not take the risk to their business for a small number of improvements, especially if they lose ANYTHING in the process. It is in my interest to prove to those people undeniably that D is a step forward in every regard. I believe that is what it will take to allow it to be adopted widely in the commercial software world. D is a competitor to C++. I know there are a lot that might disagree with me, maybe it explores some other avenues too, but in terms of direct competition to C++ (still the only real choice for realtime programming on limited systems), there is NOTHING ELSE. I think D needs to embrace what it is; a native systems language (finally) introducing modern concepts, and by extension, needs to take performance very seriously. SIMD support is a great start, I really appreciate that one appearing out of nowhere almost overnight! :) |
Copyright © 1999-2021 by the D Language Foundation