www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - modules

reply Gabe <Gabe_member pathlink.com> writes:
I don't quite understand the module declaration at the top of source files.
From the D website, I see that 'Modules have a one-to-one correspondence with
source files. The module name is the file name with the path and extension
stripped off.' So, I guess my question is: why bother?  If the name of the file
and the name of the module are the same thing, why are you (in essence) stating
it twice? (It strikes me as a tad 'header.h'y) Wouldn't it make more sense to
have implicit module declarations, as in Java, where 'module std' would
represent one directory named 'std' and the name of the file simply IS the name
of the module?  Naming the file and then naming the module the same thing inside
the file seems a tad, well, redundant.  Also, isn't this why there's the
somewhat (from my perspective) hacky 'all.d' declarations in some external
packages?  Wouldn't 'module std' and 'import std.*' be more effective solutions,
simply relying on the compiler and PATH variables to sort out the rest?  

But then again, I could totally be missing something here.
-Gabe
Apr 30 2006
next sibling parent "Derek Parnell" <derek psych.ward> writes:
On Sun, 30 Apr 2006 17:49:32 +1000, Gabe <Gabe_member pathlink.com> wrote:

 I don't quite understand the module declaration at the top of source  
 files.
 From the D website, I see that 'Modules have a one-to-one correspondence  
 with
 source files

...
 Naming the file and then naming the module the same thing inside
 the file seems a tad, well, redundant.

In once sense it is redundant. The module name is always the file name so what purpose does the 'module' statement serve? The only thing I can come up with is that is forces a naming convention on coders wanting to use your module. If you didn't have the module statement it means that you can rename the file or move it another package, but that would cause linker problems with libraries that were expecting specific file and package names. By having the module statement explicitly encoded, you are helping to keep references to your module consistent. I'm not saying this is a good or bad thing, I'm just pointing out my persepective on trying read Walter's mind. -- Derek Parnell Melbourne, Australia
Apr 30 2006
prev sibling next sibling parent Lars Ivar Igesund <larsivar igesund.net> writes:
Gabe wrote:

 I don't quite understand the module declaration at the top of source
 files. From the D website, I see that 'Modules have a one-to-one
 correspondence with source files. The module name is the file name with
 the path and extension
 stripped off.' So, I guess my question is: why bother?  If the name of the
 file and the name of the module are the same thing, why are you (in
 essence) stating it twice? (It strikes me as a tad 'header.h'y) Wouldn't
 it make more sense to have implicit module declarations, as in Java, where
 'module std' would represent one directory named 'std' and the name of the
 file simply IS the name
 of the module?  Naming the file and then naming the module the same thing
 inside
 the file seems a tad, well, redundant.  Also, isn't this why there's the
 somewhat (from my perspective) hacky 'all.d' declarations in some external
 packages?  Wouldn't 'module std' and 'import std.*' be more effective
 solutions, simply relying on the compiler and PATH variables to sort out
 the rest?
 
 But then again, I could totally be missing something here.
 -Gabe

If you for foo.d only sets module foo; then it would be redundant, but by using a form like module bar.baz.foo; you have stated that the file foo is part of the bar package and baz subpackage and the import root for all files in that package are placed in the directory where you find bar. Also, the module names functions as your namespace. If you have equally named functions in two modules, and you need to use them both from one file, you would have to call them as bar.baz.foo.func(); and bar.baz.boodle.func(); -- Lars Ivar Igesund blog at http://larsivi.net DSource & #D: larsivi
Apr 30 2006
prev sibling next sibling parent FunkyM <FunkyM_member pathlink.com> writes:
In article <e31q6c$im8$1 digitaldaemon.com>, Gabe says...
I don't quite understand the module declaration at the top of source files.
From the D website, I see that 'Modules have a one-to-one correspondence with
source files. The module name is the file name with the path and extension
stripped off.' So, I guess my question is: why bother? If the name of the file
and the name of the module are the same thing, why are you (in essence) stating
it twice? (It strikes me as a tad 'header.h'y)

It is easier for the compiler to read the qualified module name from the statement instead of constructing it from the current "directories". This might especially turn complicated for the compiler has to deal with multiple include directories and figuring out the base path.
 Wouldn't it make more sense to have implicit module declarations, as in Java,
where 'module std' would represent one directory named 'std' and the name of
the file simply IS the name of the module?

You define the fully qualified name in Java indirectly with the import statements. (Which results in the interpreter acting similar to the way I described the D compiler works in, just that it has to construct its "module" names beforehand and resolve things, which is more complicated work than the D compiler has to do with the module approach) One defined rule is that writing compilers for D should be easy which is one reason of avoiding stuff which requires the compiler to do a lot of "resolving work". Instead it defines a language construct which avoides having to do extra work.
 Naming the file and then naming the module the same thing inside the file
seems a tad, well, redundant.

Partly agree. There is a reason for defining the fully qualified name in the file. Otherwise how would you define the "root" of your class directory? Adding a new directory below all others would also implicitly introduce a new package namespace and thus draw all code using fully qualified names to resolve the correct module go wrong.
 Also, isn't this why there's the somewhat (from my perspective) hacky 'all.d'
declarations in some external
 packages? 

Thats not the reaseon. The reason of the hack "all.d", which I recently had to learn myself, is that D limits you when it comes to define a modular structure for your sources and prevents unlimited package levels. As soon as you target to have more than one package level, which (almost!) no project in D does use yet, you get a problem. D defines that a package can not have the same name as a module. This results in you not being to do this with D: kernel.cpu kernel.cpu.arm // kernel.cpu already a module, prevents you from writing a good structure .. Instead people tend to do things like this (which seriously can be cried about): kernel.cpu kernel.armcpu .. The D community solution is to use the "all.d" approach which turns this into: kernel.cpu.all kernel.cpu.arm // once you introduce sub-packages to arm, you will have to add arm.all etc.. .. It re-enables you to do unlimited levels why not conflicting with the D language definitions. Mind that this introduces additional duplicated (unrequired) package levels: kernel.cpu.arm.Arm // Arm is a class extending a Cpu class for instance You can notice that in many of the current D based libraries you find ambigious stuff like: std.c.windows.windows gtk.Window.Window .. I would say that this behaviour is conflicting with the defined goals of the D language as it requires a "hack/cheat" instead of offering a proper self-explained solution delivering an "expected-by-the-coder" behaviour.
 Wouldn't 'module std' and 'import std.*' be more effective solutions,
simply relying on the compiler and PATH variables to sort out the rest?  

Unfortunately its not that easy. Main reason being that the compiler will get more complicated if multiple source paths are used (Has to have a resolver. It could be though of if it really adds THAT much overhead vs. the simplification it introduces from the developer-view). --- Overall looking at your message, I agree that the module statement is the only one that gives back an impression that it requires some rethinking if a different approach might not be better (I vote for it and from the responses I got from the community a lot of people actually agree). You should READ the forum thread you posted on dsource.org and it's replies ("FunkyM"): http://www.dsource.org/forums/viewtopic.php?t=1447&start=0&postdays=0&postorder=asc&highlight= In the end, it's not a discussion about D language semantics, it's a discussion about the source organisation architecture of the D compiler and the rule modulename!=packagename. The D language semantics would work even with different appraoches (like using namespaces which removes the need for any file/languageelement mapping need). For my part, after evaluating the language for use in various commercial projects it is the only left questionable/weak part of D, in contrast to the remaining geniously designed semantics which are just so logical that it feels great. I am preparing a rather detailed post on the main D newsgroup about this "issue". However, I first try to prepare a possible solution, otherwise the request will probably get unnoticed by Walter or die in "you just want C#/Java but D is not that" (stupid argument) kind of responses. I undertand most people as of now are ok with the way it is now, but this is MAINLY as there is no really big library or project yet in D. Most people are ok with having C like flat-small libraries and organising their few classes in stuff like "some.module". More ambitious future goals like .NET-like massive frameworks would fail with the current module mapping architecture (or need the hacky "all.d" approach and introduce lots of superficient extra package levels and avoid a nice API design). A cross-platform GUI library, as Walter wants to have, should have a clear API design and this is a thing that prevents me from contributing yet in that section although I would directly like to. It turns out to be really complicated to find a new approach/solution to D's source file handling while maintaining the goals set by the language definitions. --- BTW: Gabe, you should visit IRC #D on freenode.net as a couple of people want to get in contact with you including myself.
Apr 30 2006
prev sibling parent reply James Pelcis <jpelcis gmail.com> writes:
As I understand it, the documentation is referring to the default module 
name.  If you felt like it, you could do something like the following:

test1.d
	module blah;

	private import std.stdio;

	void print (char[] data) {
		writefln(data);
	}

test2.d
	import blah;

	void main () {
		print("This was successful.");
	}

This can confuse build though, I think.

Gabe wrote:
 I don't quite understand the module declaration at the top of source files.
 From the D website, I see that 'Modules have a one-to-one correspondence with
 source files. The module name is the file name with the path and extension
 stripped off.' So, I guess my question is: why bother?  If the name of the file
 and the name of the module are the same thing, why are you (in essence) stating
 it twice? (It strikes me as a tad 'header.h'y) Wouldn't it make more sense to
 have implicit module declarations, as in Java, where 'module std' would
 represent one directory named 'std' and the name of the file simply IS the name
 of the module?  Naming the file and then naming the module the same thing
inside
 the file seems a tad, well, redundant.  Also, isn't this why there's the
 somewhat (from my perspective) hacky 'all.d' declarations in some external
 packages?  Wouldn't 'module std' and 'import std.*' be more effective
solutions,
 simply relying on the compiler and PATH variables to sort out the rest?  
 
 But then again, I could totally be missing something here.
 -Gabe
 
 

Apr 30 2006
next sibling parent reply "Derek Parnell" <derek psych.ward> writes:
On Mon, 01 May 2006 00:59:01 +1000, James Pelcis <jpelcis gmail.com> wrote:

 As I understand it, the documentation is referring to the default module  
 name.  If you felt like it, you could do something like the following:

 test1.d
 	module blah;

 	private import std.stdio;

 	void print (char[] data) {
 		writefln(data);
 	}

 test2.d
 	import blah;

 	void main () {
 		print("This was successful.");
 	}

 This can confuse build though, I think.

I stand corrected. Thanks James. I thought that this would not compile. You have given me a new issue to 'fix' in Build, damn it! -- Derek Parnell Melbourne, Australia
Apr 30 2006
parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
Derek Parnell wrote:
 On Mon, 01 May 2006 00:59:01 +1000, James Pelcis <jpelcis gmail.com> wrote:
 
 As I understand it, the documentation is referring to the default 
 module  name.  If you felt like it, you could do something like the 
 following:

 test1.d
     module blah;

     private import std.stdio;

     void print (char[] data) {
         writefln(data);
     }

 test2.d
     import blah;

     void main () {
         print("This was successful.");
     }

 This can confuse build though, I think.

I stand corrected. Thanks James. I thought that this would not compile. You have given me a new issue to 'fix' in Build, damn it!

Heheh, I thought that was a design decision on your part! This is not really an issue, though. It's not build's fault, and there really isn't any effecient way to always figure out the filename if it doesn't match the module name.
May 01 2006
parent reply "Derek Parnell" <derek psych.ward> writes:
On Mon, 01 May 2006 19:08:28 +1000, Hasan Aljudy <hasan.aljudy gmail.com>  
wrote:


 It's not build's fault, and there really isn't any effecient way to  
 always figure out the filename if it doesn't match the module name.

Yes I know that, so what I'm considering is allowing a .mfm (module-file-mapping) file to be placed on the command line to help Build resolve import names. This might replace the all.d hack too. -- Derek Parnell Melbourne, Australia
May 01 2006
parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
Derek Parnell wrote:
 On Mon, 01 May 2006 19:08:28 +1000, Hasan Aljudy 
 <hasan.aljudy gmail.com>  wrote:
 
 
 It's not build's fault, and there really isn't any effecient way to  
 always figure out the filename if it doesn't match the module name.

Yes I know that, so what I'm considering is allowing a .mfm (module-file-mapping) file to be placed on the command line to help Build resolve import names. This might replace the all.d hack too.

but that defeats the point of using build.
May 01 2006
parent Derek Parnell <derek psych.ward> writes:
On Mon, 01 May 2006 23:15:17 -0600, Hasan Aljudy wrote:

 Derek Parnell wrote:
 On Mon, 01 May 2006 19:08:28 +1000, Hasan Aljudy 
 <hasan.aljudy gmail.com>  wrote:
 
 It's not build's fault, and there really isn't any effecient way to  
 always figure out the filename if it doesn't match the module name.

Yes I know that, so what I'm considering is allowing a .mfm (module-file-mapping) file to be placed on the command line to help Build resolve import names. This might replace the all.d hack too.

but that defeats the point of using build.

I know ;-) but if people are going to use module references that don't follow the (implied) standards then they might appreciate the help. Plus I'm thinking that the .mfm file could be a way of implementing the "import package.*" idea that Java people like so much. I'll think on it a bit more ... -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocracy!" 2/05/2006 3:17:45 PM
May 01 2006
prev sibling parent Bruno Medeiros <brunodomedeirosATgmail SPAM.com> writes:
James Pelcis wrote:
 As I understand it, the documentation is referring to the default module 
 name.  If you felt like it, you could do something like the following:
 
 test1.d
     module blah;
 
     private import std.stdio;
 
     void print (char[] data) {
         writefln(data);
     }
 
 test2.d
     import blah;
 
     void main () {
         print("This was successful.");
     }
 
 This can confuse build though, I think.
 

Whoa! I for long explicitly thought this wasn't possible, and I guess I wasn't the only one. Still, it seems like a borderline (perhaps even non-recommendable?) idiom. (To do separate compilation with this one needs to manually use header files). -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
May 01 2006