Delight

Yigal Chripun yigal100 at gmail.com
Sun Sep 28 22:13:06 PDT 2008


bearophile wrote:
> Sorry for my answering delay, I was busy.
> 
> Yigal Chripun:
> 
>> Java is similar with this since it has dynamic class-loading - i.e.
>> all your classes can define a main function and you specify to the
>> JVM which class to load. this has other problems in java but the
>> general idea (not the specific java implementation) is a good
>> thing. if you try a similar thing in D - compile two D files which
>> both define main - you'll get an error.<
> 
> I see. In Python this problem is solved with this not nice syntax:
> 
> code if __name__ == "__main__": more_code
> 
> The 'code' is run when you import that module. But the more_code is
> run only when you run that module as main module. So every module can
> have that if __name__==... part, so every module can be run both
> stand alone (for example to run a little demo of its purpose, or to
> run just its own tests), or imported like a normal module.
> 
> Time ago in one of my lists of improvements I have asked to have
> something similar (with a different syntax, a better syntax too) in
> D.
> 
> At the moment lot of the D modules I write have a structure like
> this:
> 
> 
> const bool do_benchmarks = false;
> 
> void foo() { ... }
> 
> unittest { // unittest of function foo ... }
> 
> void bar() { ... }
> 
> unittest { // unittest of function bar }
> 
> static if (do_benchmarks) { import d.time: clock;
> 
> void benchmark1() { ... }
> 
> void benchmark2() { ... } }
> 
> unittest { printf(__FILE__ " unittest performed.\n"); }
> 
> static if (0) { void main() { static if (do_benchmarks) { 
> putr("\nSome benchmarks:"); benchmark1(); benchmark2(); } } }
> 
> So when I want to test it I replace the 0 with a 1 at the end and I
> add -unittest to the command line of the 'bud' tool. When I want to
> test the performance I also set do_benchmarks to true.
> 
> With a syntax to denote if a module is run as main the code can
> become simpler, for example:
> 
> mainmodule { void main() { static if (do_benchmarks) { putr("\nSome
> benchmarks:"); benchmark1(); benchmark2(); } } }
> 
> Or even adding just a compile-time constant to D (that is true only
> for the main module) may suffice:
> 
> static if (mainmodule) { void main() { static if (do_benchmarks) { 
> putr("\nSome benchmarks:"); benchmark1(); benchmark2(); } } }
> 
> Do you like?
> 
> ------------------------------
> 
> Johan Granberg:
> 
>> How complet is the page? From wath I read there was several good
>> features missing from D1 and if it's just a resyntax thats a shame
>> :)<
> 
> I think the language is just born, so more things will be added in
> the future. Probably the purpose is to support all D.
> 
> Bye, bearophile

In a perfect world, I'd want a different solution:
the _linker_ needs to have a command line flag that tells it what
compilation unit contains the main function. (i.e. what's the "main"
module).
the compiler can safely compile the main function in each module so all
object files can contain main functions, but at link time the linker
will use only the main function in the specified module.
No need for anything in the code such as a a version block or an if
statement.

this solution does require to change the linker though, and mark "main"
functions with a marker of some sort to be recognized by the linker.

I know that Walter is unlikely to make any changes to the liker though :(

build tools like rebuild do parse the code so maybe they can implement
the above instead of the linker. another possibility is to have an
_implicit_ version block with the name of the module defined for each
module.

your code is:

module A;
...code...
void main() {..code..}

the compiler treats it as:

module A;
...code...
version A {
    void main() {..code..}
}

on the command-line you'd use it as:
dmd source_files -version=A
(or maybe define a different name like --main=A)


More information about the Digitalmars-d-announce mailing list