digitalmars.D.learn - Private imports and Objects
- helxi (23/23) Nov 29 2017 1. Why are imports visible from outside the package when you do
- Jonathan M Davis (32/55) Nov 29 2017 If you use a version of dmd that's at least semi-recent, you should see ...
- helxi (10/42) Nov 30 2017 []
- Jonathan M Davis (28/74) Nov 30 2017 Virtual functions do have a cost but not a huge one, and to a point, the...
- Patrick Schluter (5/15) Nov 30 2017 And they come in very handy when one ports code from Java. As a
1. Why are imports visible from outside the package when you do selective imports? //mod.d module mod; import std.stdio : writeln; public void greet() { writeln("Hello"); } //app.d import mod; void main() { mod.greet(); writeln("You should not be seeing this."); } Compiles just fine and prints "You should not be seeing this." just fine with `$dub build`. Even if I use package imports the result stays the same. 2. Classes that do not inherit (base classes) actually inherit from 'Object`. For which, often times one converts the Object to its subclasses. What's the rationale behind this? Isn't this going to add overhead?
Nov 29 2017
On Thursday, November 30, 2017 06:29:43 helxi via Digitalmars-d-learn wrote:1. Why are imports visible from outside the package when you do selective imports? //mod.d module mod; import std.stdio : writeln; public void greet() { writeln("Hello"); } //app.d import mod; void main() { mod.greet(); writeln("You should not be seeing this."); } Compiles just fine and prints "You should not be seeing this." just fine with `$dub build`. Even if I use package imports the result stays the same.If you use a version of dmd that's at least semi-recent, you should see a deprecation message. It works due to a long standing bug that has been fixed, but when it was fixed, a number of aspects of imports were overhauled, and it was decided to phase in the new behavior to minimize code breakage, and as such, it should be printing a deprecation message at the moment, whereas in the future, it will become an error like it should be.2. Classes that do not inherit (base classes) actually inherit from 'Object`. For which, often times one converts the Object to its subclasses. What's the rationale behind this? Isn't this going to add overhead?I don't understand the question. You're asking whether casting from a base class to a derived class creates overhead? Or are you asking whether having a base class for all classes creates overhead? Or something else? Object exists primarily because D didn't originally have templates, and when you don't have templates, having a single base class is the only way to have a function accept any class, and for something like a container, you'd pretty much be forced to use void* without Object if you don't have templates. However, once templates were added to D, the benefits of Object were significantly reduced, and it's arguably not a particularly good idea to be writing code that operates on Object. However, it's far too late in the game to get rid of Object. At one point, it was decided to remove Object's member functions, because having them on Object needlessly locks in a particular set of attributes for those functions, and if we did that, then there really wouldn't be much reason to use Object directly, but that change has never happened, and it's not clear that it's going to happen, since there are a number of technical issues that make it a bit of a pain to do (particularly if we don't want to break a lot of code). One of the bigger issues is that the AA implementation in druntime needs to be templated so that it doesn't need to operate on Object, and that's proven to be a bit of a challenge. https://issues.dlang.org/show_bug.cgi?id=9769 https://issues.dlang.org/show_bug.cgi?id=9770 https://issues.dlang.org/show_bug.cgi?id=9771 https://issues.dlang.org/show_bug.cgi?id=9772 - Jonathan M Davis
Nov 29 2017
On Thursday, 30 November 2017 at 06:44:43 UTC, Jonathan M Davis wrote:On Thursday, November 30, 2017 06:29:43 helxi via Digitalmars-d-learn wrote:[]I don't understand the question. You're asking whether casting from a base class to a derived class creates overhead? Or are you asking whether having a base class for all classes creates overhead? Or something else? Object exists primarily because D didn't originally have templates, and when you don't have templates, having a single base class is the only way to have a function accept any class, and for something like a container, you'd pretty much be forced to use void* without Object if you don't have templates. However, once templates were added to D, the benefits of Object were significantly reduced, and it's arguably not a particularly good idea to be writing code that operates on Object. However, it's far too late in the game to get rid of Object. At one point, it was decided to remove Object's member functions, because having them on Object needlessly locks in a particular set of attributes for those functions, and if we did that, then there really wouldn't be much reason to use Object directly, but that change has never happened, and it's not clear that it's going to happen, since there are a number of technical issues that make it a bit of a pain to do (particularly if we don't want to break a lot of code). One of the bigger issues is that the AA implementation in druntime needs to be templated so that it doesn't need to operate on Object, and that's proven to be a bit of a challenge. https://issues.dlang.org/show_bug.cgi?id=9769 https://issues.dlang.org/show_bug.cgi?id=9770 https://issues.dlang.org/show_bug.cgi?id=9771 https://issues.dlang.org/show_bug.cgi?id=9772 - Jonathan M DavisI was actually referring to both. Override functions such as opCmp, opEquals, toString, toHash etc --wouldn't they be inherently expensive? I thought they are virtual functions. Also, with regards to casting, wouldn't this be an extra legwork? Both of these seem to be a performance handicap to me. But I'm no expert on this matter. Maybe the compiler optimises it away since normally you'd cast to a constant subclass.
Nov 30 2017
On Thursday, November 30, 2017 10:54:44 helxi via Digitalmars-d-learn wrote:On Thursday, 30 November 2017 at 06:44:43 UTC, Jonathan M Davis wrote:Virtual functions do have a cost but not a huge one, and to a point, they're kind of the whole point of classes. If you don't need inheritance, then use a struct. D separates structs and classes so that classes have inheritance and are always reference types (like in Java), whereas structs don't have inheritance. Classes in D cost about what they would cost in C++ or Java. Unlike C++, they do have an invisible monitor member to enable synchronized to work, and public member functions are virtual by default, but in general, calling a function on a class in D costs what it would to call a virtual function in C++ - and if you don't need virtual functions, then why use a class? You can mark individual member functions as final to devirtualize them (assuming that they're not overriding a base class member), but if you don't need any virtual functions, then you don't need inheritance, and you don't need a class. As for casting, I don't know what the concern is. You typically construct a class object and then either reference it through a class reference of its actual type or through a class reference of a base type, just like you would implicit casting is only going to happen if you assign the object to another reference of a base type of the current reference. Casting class objects shouldn't be any more expensive in D than it is in other languages. Having Object exist doesn't really affect much of any of this. It just provides a common base class. The functions that are on it don't need to be there, and if we were doing things from scratch, they certainly wouldn't be, but it doesn't make functions or casting more expensive. Any extra cost that's there is inherent to inheritance in general, and that's the whole reason that classes exist. - Jonathan M DavisOn Thursday, November 30, 2017 06:29:43 helxi viaDigitalmars-d-learn wrote:[]I don't understand the question. You're asking whether casting from a base class to a derived class creates overhead? Or are you asking whether having a base class for all classes creates overhead? Or something else? Object exists primarily because D didn't originally have templates, and when you don't have templates, having a single base class is the only way to have a function accept any class, and for something like a container, you'd pretty much be forced to use void* without Object if you don't have templates. However, once templates were added to D, the benefits of Object were significantly reduced, and it's arguably not a particularly good idea to be writing code that operates on Object. However, it's far too late in the game to get rid of Object. At one point, it was decided to remove Object's member functions, because having them on Object needlessly locks in a particular set of attributes for those functions, and if we did that, then there really wouldn't be much reason to use Object directly, but that change has never happened, and it's not clear that it's going to happen, since there are a number of technical issues that make it a bit of a pain to do (particularly if we don't want to break a lot of code). One of the bigger issues is that the AA implementation in druntime needs to be templated so that it doesn't need to operate on Object, and that's proven to be a bit of a challenge. https://issues.dlang.org/show_bug.cgi?id=9769 https://issues.dlang.org/show_bug.cgi?id=9770 https://issues.dlang.org/show_bug.cgi?id=9771 https://issues.dlang.org/show_bug.cgi?id=9772 - Jonathan M DavisI was actually referring to both. Override functions such as opCmp, opEquals, toString, toHash etc --wouldn't they be inherently expensive? I thought they are virtual functions. Also, with regards to casting, wouldn't this be an extra legwork? Both of these seem to be a performance handicap to me. But I'm no expert on this matter. Maybe the compiler optimises it away since normally you'd cast to a constant subclass.
Nov 30 2017
On Thursday, 30 November 2017 at 06:44:43 UTC, Jonathan M Davis wrote:Object exists primarily because D didn't originally have templates, and when you don't have templates, having a single base class is the only way to have a function accept any class, and for something like a container, you'd pretty much be forced to use void* without Object if you don't have templates. However, once templates were added to D, the benefits of Object were significantly reduced, and it's arguably not a particularly good idea to be writing code that operates on Object. However, it's far too late in the game to get rid of Object.And they come in very handy when one ports code from Java. As a first approach a simple 1 to 1 adaptation of the code makes the porting so much easier. Templates and D magic can come afterwards.
Nov 30 2017