digitalmars.D.learn - Why the compiler dosen't enforce correct module declarations?
- Ary Manzana (43/43) May 12 2007 I can have three files:
- Manfred Nowak (6/8) May 12 2007 | The ModuleDeclaration sets the name of the module and what package
- Ary Manzana (3/13) May 12 2007 So what's the point of settings a package and module name different than...
- Chris Nicholson-Sauls (14/27) May 12 2007 Its useful as an alternative means of doing platform-versioning. (At le...
- Ary Manzana (9/25) May 12 2007 Why use an alternative of the built-in version system?
- Manfred Nowak (3/4) May 12 2007 The version system is not equivalent to the module naming system.
- Ary Manzana (6/11) May 12 2007 Ok. My point is that it is totaly unnecessary to have the module
- Daniel Keep (26/38) May 12 2007 I plan to use this while DDL is out of commission.
- Bruno Medeiros (19/44) May 18 2007 Let me see if I got this correct, because I also do not understand how
- Daniel Keep (19/42) May 18 2007 Because the plan is to eventually move to DDL. Once I do that, I have
- Bruno Medeiros (6/44) May 22 2007 I still don't see (as in, I dont' see) why one would need multiple
- Manfred Nowak (11/13) May 12 2007 Can you prove this statement correct?
- Derek Parnell (8/22) May 13 2007 The only reason I can see as the purpose of the module statement is to
- Ary Manzana (3/15) May 13 2007 Thanks for all your answers.
- Bruno Medeiros (9/17) May 18 2007 That particular usage of the module system is equivalent to using the
- Sean Kelly (8/12) May 22 2007 I've decided that this is actually a good thing. It allows large
- Bruno Medeiros (13/28) May 26 2007 But:
- gareis (37/62) May 26 2007 The first part is mostly naming convention. Though if you can't possibly...
- Bruno Medeiros (35/102) Jun 01 2007 Yes, the object module example is a valid use case for this behavior.
I can have three files: main.d: --- module one; import two; import lala.la; void main() { foo(); bar(); } --- other.d --- module two; import std.stdio; void foo() { writefln("Hello!"); } --- dir/some_other.d --- module lala.la; import std.stdio; void bar() { writefln("Hello!!"); } --- and compile them with no problem: dmd main.d other.d dir/some_other.d Shouldn't the compiler say "Wait, you are saying that module one is in file main.d, module two is in other.d and module lala.la is in dir/some_other.d, this isn't quite well"? In http://www.digitalmars.com/d/module.html it states: "The packages correspond to directory names in the source file path." "The module name is the file name with the path and extension stripped off." Why this isn't honored by the compiler? My worry is, if this is valid, then in an IDE you can't just assume directories are packages, and filenames (path and extension stripped off) are modules, since this is not mandatory. Then it's a lot harder to do. Further, it complicates things since probably nobody wants to name a module with a name and path that dosen't match the underlying filesystem's name and path. So enforcing this in a compiler eliminates "bugs".
May 12 2007
Ary Manzana wroteIn http://www.digitalmars.com/d/module.html it states:| The ModuleDeclaration sets the name of the module and what package | it belongs to. If absent, the module name is taken to be the same | name (stripped of path and extension) of the source file name. Please read carefully. -manfred
May 12 2007
Manfred Nowak escribió:Ary Manzana wroteSo what's the point of settings a package and module name different than what's in the filesystem?In http://www.digitalmars.com/d/module.html it states:| The ModuleDeclaration sets the name of the module and what package | it belongs to. If absent, the module name is taken to be the same | name (stripped of path and extension) of the source file name. Please read carefully.
May 12 2007
Ary Manzana wrote:Manfred Nowak escribió:Its useful as an alternative means of doing platform-versioning. (At least I remember this working... I might just be crazy.) For example: Given project: main.d - module main; util_win32.d - module util; util_linux.d - module util; You may now simply `import util;` in main, and on the command line pass the appropriate util module. I'm sure there might be another use as well, but I admit that even this one has limited value -- aside from avoiding having a redundant version(){}else{} block at the beginning of all modules importing util, but we have two different ways of avoiding that: a go-between module with a version'd public import of util, or a mixin. (Possibly even a mixin(import()).) -- Chris Nicholson-SaulsAry Manzana wroteSo what's the point of settings a package and module name different than what's in the filesystem?In http://www.digitalmars.com/d/module.html it states:| The ModuleDeclaration sets the name of the module and what package | it belongs to. If absent, the module name is taken to be the same | name (stripped of path and extension) of the source file name. Please read carefully.
May 12 2007
Chris Nicholson-Sauls escribió:Ary Manzana wrote:Why use an alternative of the built-in version system? Also, if you have many versioned modules (a1_win32.d, a1_linux.d, b1_win32.d, b1_linux.d, etc.) you need to change the command line for each of the modules, instead of just changing the version passed. You also have to tell the other developers: remember not to use the version flag, but to change the suffix of the filenames according to the version... Maybe doing the suffix thing is valid for C or C++, but I think D tries to solve that using versions, and not using them seems awkward to me.Manfred Nowak escribió:Its useful as an alternative means of doing platform-versioning.Ary Manzana wroteSo what's the point of settings a package and module name different than what's in the filesystem?In http://www.digitalmars.com/d/module.html it states:| The ModuleDeclaration sets the name of the module and what package | it belongs to. If absent, the module name is taken to be the same | name (stripped of path and extension) of the source file name. Please read carefully.
May 12 2007
Ary Manzana wroteWhy use an alternative of the built-in version system?The version system is not equivalent to the module naming system. -manfred
May 12 2007
Manfred Nowak escribió:Ary Manzana wroteOk. My point is that it is totaly unnecessary to have the module declaration say something different than it's location relative to the include source path. This is like things work in Java, for example: you get an error if the package declaration and the filesystem dosen't match. Why not apply the same in D?Why use an alternative of the built-in version system?The version system is not equivalent to the module naming system.
May 12 2007
Ary Manzana wrote:Manfred Nowak escribió:I plan to use this while DDL is out of commission. For instance: I have a class engine.gx.camera.Camera, which is just the interface declaration (no actual contents). I then have two different implementations: one for GL and one for D3D; they both need to have the same module name, but they exist in totally different places on the physical filesystem. And don't say "just use version()s" since I really don't want to have to go around putting in version flags in every place this switch happens. I just want to do it once at compile time and be done with it. Hell, once DDL is working again, they won't even be linked together at all. The whole point of this is to allow someone to swap out which implementation to use at run time; version()s won't let you do that :) Besides, I don't see that this is a huge problem. IDEs can just assume the "normal" behaviour holds, and if they find it doesn't they can either ignore it, or flag the modules in question for having odd names. -- Daniel -- int getRandomNumber() { return 4; // chosen by fair dice roll. // guaranteed to be random. } http://xkcd.com/ v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/Ary Manzana wroteOk. My point is that it is totaly unnecessary to have the module declaration say something different than it's location relative to the include source path. This is like things work in Java, for example: you get an error if the package declaration and the filesystem dosen't match. Why not apply the same in D?Why use an alternative of the built-in version system?The version system is not equivalent to the module naming system.
May 12 2007
Daniel Keep wrote:Ary Manzana wrote:Let me see if I got this correct, because I also do not understand how this could not be done just as good with versioning. You said you don't want to put "version flags in every place this switch happens". Did you mean every place that uses/imports the Camera module? Why not just have the Camera module change implementations according to the version (like Chris mentioned) ? Something like: ---- engine/gx/camera/Camera.d ---- module engine.gx.camera.Camera version(OGL) { // OGL implementation } else version(D3D) { // D3D implementation } ---- ---- -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#DManfred Nowak escribió:I plan to use this while DDL is out of commission. For instance: I have a class engine.gx.camera.Camera, which is just the interface declaration (no actual contents). I then have two different implementations: one for GL and one for D3D; they both need to have the same module name, but they exist in totally different places on the physical filesystem. And don't say "just use version()s" since I really don't want to have to go around putting in version flags in every place this switch happens. I just want to do it once at compile time and be done with it.Ary Manzana wroteOk. My point is that it is totaly unnecessary to have the module declaration say something different than it's location relative to the include source path. This is like things work in Java, for example: you get an error if the package declaration and the filesystem dosen't match. Why not apply the same in D?Why use an alternative of the built-in version system?The version system is not equivalent to the module naming system.
May 18 2007
Bruno Medeiros wrote:Daniel Keep wrote:Because the plan is to eventually move to DDL. Once I do that, I have to go back and remove all of the version statements (that I didn't need to put there in the first place), since linking will then be done at runtime. For now, I'm just using dmd to do DDL's job at compile time. Also, I'm a damn stubborn bastard about these things: I've found a way that works for me and I'll be damned if we lets anyone take it away from usss, my precioussss! :P -- Daniel -- int getRandomNumber() { return 4; // chosen by fair dice roll. // guaranteed to be random. } http://xkcd.com/ v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/And don't say "just use version()s" since I really don't want to have to go around putting in version flags in every place this switch happens. I just want to do it once at compile time and be done with it.Let me see if I got this correct, because I also do not understand how this could not be done just as good with versioning. You said you don't want to put "version flags in every place this switch happens". Did you mean every place that uses/imports the Camera module? Why not just have the Camera module change implementations according to the version (like Chris mentioned) ? Something like: ---- engine/gx/camera/Camera.d ---- module engine.gx.camera.Camera version(OGL) { // OGL implementation } else version(D3D) { // D3D implementation } ---- ----
May 18 2007
Daniel Keep wrote:Bruno Medeiros wrote:I still don't see (as in, I dont' see) why one would need multiple version statements for your case. -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#DDaniel Keep wrote:Because the plan is to eventually move to DDL. Once I do that, I have to go back and remove all of the version statements (that I didn't need to put there in the first place), since linking will then be done at runtime. For now, I'm just using dmd to do DDL's job at compile time. Also, I'm a damn stubborn bastard about these things: I've found a way that works for me and I'll be damned if we lets anyone take it away from usss, my precioussss! :P -- DanielAnd don't say "just use version()s" since I really don't want to have to go around putting in version flags in every place this switch happens. I just want to do it once at compile time and be done with it.Let me see if I got this correct, because I also do not understand how this could not be done just as good with versioning. You said you don't want to put "version flags in every place this switch happens". Did you mean every place that uses/imports the Camera module? Why not just have the Camera module change implementations according to the version (like Chris mentioned) ? Something like: ---- engine/gx/camera/Camera.d ---- module engine.gx.camera.Camera version(OGL) { // OGL implementation } else version(D3D) { // D3D implementation } ---- ----
May 22 2007
Ary Manzana wrotetotaly unnecessary to have the module declaration say something differentCan you prove this statement correct? Why then have module declarations at all? What is the redundany good for? In general: any proof that some form of existing freedom is not usable is a counter argument for the wish to delete that freedom. For a freedom that is usable a declaration of unnecessity is insufficient; a retraction has to be grounded by greater wealth (in terms of money) of the set of possible users---unless it is a "political" decision. -manfred
May 12 2007
On Sun, 13 May 2007 05:22:15 +0000 (UTC), Manfred Nowak wrote:Ary Manzana wroteThe only reason I can see as the purpose of the module statement is to ensure that one has named the file as one intended it to be named. -- Derek Parnell Melbourne, Australia "Justice for David Hicks!" skype: derek.j.parnelltotaly unnecessary to have the module declaration say something differentCan you prove this statement correct? Why then have module declarations at all? What is the redundany good for? In general: any proof that some form of existing freedom is not usable is a counter argument for the wish to delete that freedom. For a freedom that is usable a declaration of unnecessity is insufficient; a retraction has to be grounded by greater wealth (in terms of money) of the set of possible users---unless it is a "political" decision.
May 13 2007
Thanks for all your answers. I'll follow Daniel's advice. Ary Manzana escribió:Manfred Nowak escribió:Ary Manzana wroteOk. My point is that it is totaly unnecessary to have the module declaration say something different than it's location relative to the include source path. This is like things work in Java, for example: you get an error if the package declaration and the filesystem dosen't match. Why not apply the same in D?Why use an alternative of the built-in version system?The version system is not equivalent to the module naming system.
May 13 2007
Manfred Nowak wrote:Ary Manzana wroteThat particular usage of the module system is equivalent to using the versioning system. Equivalent in the sense that they're both trying to do conditional compilation. However the version system was specifically designed to do that, whereas that module system usage is an ugly hack. (also see my reply to Daniel Keep) -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#DWhy use an alternative of the built-in version system?The version system is not equivalent to the module naming system. -manfred
May 18 2007
Ary Manzana wrote:Shouldn't the compiler say "Wait, you are saying that module one is in file main.d, module two is in other.d and module lala.la is in dir/some_other.d, this isn't quite well"?I've decided that this is actually a good thing. It allows large modules to be split across multiple files and for different implementation files to be chosen at compile time when using the header/source model. It's also the only way I've found to compile the implementation of "object.d" for Tango. Actually naming it "object.d" caused all sorts of problems. Sean
May 22 2007
Sean Kelly wrote:Ary Manzana wrote:But: A) "It allows large modules to be split across multiple files" What do you mean? Splitting a large module into multiple files implies putting each new file in a different module. What does that have to do with allowing module-file name mismatches? B) "and for different implementation files to be chosen at compile time when using the header/source model." And why is that a good thing? If I use conditional compilation and define conditional properties at compile time I achieve the same effect. -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#DShouldn't the compiler say "Wait, you are saying that module one is in file main.d, module two is in other.d and module lala.la is in dir/some_other.d, this isn't quite well"?I've decided that this is actually a good thing. It allows large modules to be split across multiple files and for different implementation files to be chosen at compile time when using the header/source model. It's also the only way I've found to compile the implementation of "object.d" for Tango. Actually naming it "object.d" caused all sorts of problems. Sean
May 26 2007
== Quote from Bruno Medeiros (brunodomedeiros+spam com.gmail)'s articleSean Kelly wrote:The first part is mostly naming convention. Though if you can't possibly imagine using one file without having the exact source of another file, they should be one module. You could combine the files, but that tends to work poorly after a while. Still, I'd use imports most of the time, if it were possible. For the second part, Mr. Kelly gave an example: his object module couldn't appear in object.d without causing issues.Ary Manzana wrote:But: A) "It allows large modules to be split across multiple files" What do you mean? Splitting a large module into multiple files implies putting each new file in a different module. What does that have to do with allowing module-file name mismatches?Shouldn't the compiler say "Wait, you are saying that module one is in file main.d, module two is in other.d and module lala.la is in dir/some_other.d, this isn't quite well"?I've decided that this is actually a good thing. It allows large modules to be split across multiple files and for different implementation files to be chosen at compile time when using the header/source model. It's also the only way I've found to compile the implementation of "object.d" for Tango. Actually naming it "object.d" caused all sorts of problems. SeanB) "and for different implementation files to be chosen at compile time when using the header/source model." And why is that a good thing? If I use conditional compilation and define conditional properties at compile time I achieve the same effect.You can wrap your entire file in version statements, but then it's difficult to work with. If you have multiple people working on the functions for different versions, you might get conflicts with cvs / subversion / what-have-you (especially with coding style and editor issues). And IDEs might barf on entire functions wrapped in version statements and appearing multiple times. You could wrap all the import statements in version statements, but that's ugly and doesn't scale that well. Modules that aren't platform-specific or feature-specific will end up having to pay attention to platforms and features. You could have a module that just has a bunch of statements like: --- version (Windows) import foo.windows; version (Linux) { version (Bigendian) { import foo.linux_bigendian; } else { import foo.linux_little_endian; } version (UsingSSL) import foo.linux_ssl; } --- That's also annoying. And contrived. Still, if you're using makefiles and autotools, conditional compilation of files is the easiest way to go. You can compile each file into a separate object file for faster recompilation in the face of changes, and you don't have any issues with, for instance, foo.windows panicking because it can't use Windows functions on Linux. I'm not sure whether dsss allows for this sort of thing -- a source file that will not be used on one system and will not compile on it, but will be used on another system and compile on it.
May 26 2007
Sorry for the long delay in this posts. gareis wrote:== Quote from Bruno Medeiros (brunodomedeiros+spam com.gmail)'s articleYes, the object module example is a valid use case for this behavior. But it is a very special case (hell, it's *unique*), which doesn't by itself justify module-file name mismatches.Sean Kelly wrote:The first part is mostly naming convention. Though if you can't possibly imagine using one file without having the exact source of another file, they should be one module. You could combine the files, but that tends to work poorly after a while. Still, I'd use imports most of the time, if it were possible. For the second part, Mr. Kelly gave an example: his object module couldn't appear in object.d without causing issues.Ary Manzana wrote:But: A) "It allows large modules to be split across multiple files" What do you mean? Splitting a large module into multiple files implies putting each new file in a different module. What does that have to do with allowing module-file name mismatches?Shouldn't the compiler say "Wait, you are saying that module one is in file main.d, module two is in other.d and module lala.la is in dir/some_other.d, this isn't quite well"?I've decided that this is actually a good thing. It allows large modules to be split across multiple files and for different implementation files to be chosen at compile time when using the header/source model. It's also the only way I've found to compile the implementation of "object.d" for Tango. Actually naming it "object.d" caused all sorts of problems. SeanYes, that is not a good solution.B) "and for different implementation files to be chosen at compile time when using the header/source model." And why is that a good thing? If I use conditional compilation and define conditional properties at compile time I achieve the same effect.You can wrap your entire file in version statements, but then it's difficult to work with. If you have multiple people working on the functions for different versions, you might get conflicts with cvs / subversion / what-have-you (especially with coding style and editor issues). And IDEs might barf on entire functions wrapped in version statements and appearing multiple times.You could wrap all the import statements in version statements, but that's ugly and doesn't scale that well. Modules that aren't platform-specific or feature-specific will end up having to pay attention to platforms and features.Yes, that is not a good solution either.You could have a module that just has a bunch of statements like: --- version (Windows) import foo.windows; version (Linux) { version (Bigendian) { import foo.linux_bigendian; } else { import foo.linux_little_endian; } version (UsingSSL) import foo.linux_ssl; } --- That's also annoying. And contrived.Like I said before, that is the alternative that I was thinking, and I don't see what's bad with it. Why is it annoying and contrived? The only issue I see is the one you mention below:Still, if you're using makefiles and autotools, conditional compilation of files is the easiest way to go. You can compile each file into a separate object file for faster recompilation in the face of changes, and you don't have any issues with, for instance, foo.windows panicking because it can't use Windows functions on Linux.Indeed, you would need to specify to the build tool (or IDE) that certain modules (like the windows one on linux) are not to be compiled. But you have to the same thing with makefiles and autotools, so you're not any worse. In fact, a smart IDE (or build tool with semantic knowledge) might understand the version statements and automatically know which modules to compile or not. But if you're still not convinced, there is perhaps another alternative. Use different files for different implementations, but put each file on a different source folder, thus allowing each file to correctly match the pack+module names to the directory+file structure: --- src-linux/foo/bar.d --- module foo.bar; ... --- src-windows/foo/bar.d --- module foo.bar; ... ---- This is how it's done on Java programs with platform specific code(like SWT), and should work fine for D *and* be IDE-friendly. This should be adequate for big conditional variants, like platform, but no so much for small optional features, but you can always use a combination of methods for the cases where its not adequate. -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Jun 01 2007