www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Private imports and Objects

reply helxi <brucewayneshit gmail.com> writes:
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
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
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
next sibling parent reply helxi <brucewayneshit gmail.com> writes:
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 Davis
I 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
parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
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:
 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 Davis
I 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.
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 in C++, Java, C#, etc. You don't typically need explicit casting, and 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 Davis
Nov 30
prev sibling parent Patrick Schluter <Patrick.Schluter bbox.fr> writes:
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