September 28, 2008
Sergey Gromov:

> There is no main module in D.  The main() function can be in any module.

This true for Python too. What I have named conventionally "main module" is the module you call bud (or a saner D compiler able to find the necessary modules by itself) with. If you call bud with another name, then the "main module" becomes magically the new one.


> There are no specific privileges for the first module on the command line except sometimes compiler derives an output name from it.

I think that's bad.


> Why don't you want to use versions instead?  For the module builders for
> instance it could be:
> do unittests:
> bud builders -unittest -version=builders
> benchmark:
> bud builders -version=builders -version=benchmark

Don't you see something bad in what you have written? You have expressed the name 'builders' two times in your command line.
So why can't the compiler, given the line:
dmd builders
define a compile variable that's true inside builders.d and false for all the other modules.
While when you compile for example:
dmd foo
is true inside foo and false for all the other modules, including builders?

Bye,
bearophile
September 28, 2008
Sun, 28 Sep 2008 19:34:25 -0400,
bearophile wrote:
> Sergey Gromov:
> 
> > There is no main module in D.  The main() function can be in any module.
> 
> This true for Python too. What I have named conventionally "main module" is the module you call bud (or a saner D compiler able to find the necessary modules by itself) with. If you call bud with another name, then the "main module" becomes magically the new one.
> 
> > There are no specific privileges for the first module on the command line except sometimes compiler derives an output name from it.
> 
> I think that's bad.

What if a makefile builds all modules by "dmd -c module.d" and then links object files together?  That's how bud works.  Which module is "main" then?

I'll tell you, it's not the compiler's task.  Compiler is not a build system.  Recursive building is a special case for simple tools, and in a large project you do want an incremental build.

But a build system can definitely do that.  Bud could do that.  Bud could define a -version=builders, or define -version=mainmodule when compiling the first module in the chain.

> > Why don't you want to use versions instead?  For the module builders for
> > instance it could be:
> > do unittests:
> > bud builders -unittest -version=builders
> > benchmark:
> > bud builders -version=builders -version=benchmark
> 
> Don't you see something bad in what you have written? You have expressed the name 'builders' two times in your command line.

I'd definitely better specify a module name twice than modify module source every time I want to benchmark.
September 29, 2008
Sergey Gromov:

> Recursive building is a special case for simple tools, and in a large project you do want an incremental build.

This is true, but for small programs it seems bud (and another similar tool) is enough (my experience with DMD shows that 'small' means up to more than 80000 lines of code). And putting that basic functionality into the compiler, that already parses code, can probably bump that limit up a little higher.
So why not offer a handy feature for all the small cases, plus the capability of using complex incremental builds for large programs?
Giving the programmer sensible "defaults" for simple very common cases (such very common cases have to be found experimentally) sometimes makes the difference between a handy computer language (or a handy technological system) and a language that isn't nice at all (this is often one little secret of scripting languages).
If D wants to be used for smaller programs too (see the other thread here about people using D for scripting-like purposes of text processing) sensible defaults and a handy building becomes important.
Do you know why DMD has the -run compilation flag, plus it accepts the shebang syntax that you often find at the top of scripts like Perl/Python ones? It may be of little use if you have to compile a large project, but for smaller quicker things they are useful.


> But a build system can definitely do that.  Bud could do that.  Bud could define a -version=builders, or define -version=mainmodule when compiling the first module in the chain.

I see :-) Well, this solution of yours is better than nothing. I don't know if bud is updated still.
But the name of the constant you have to use into the code is is different for each module, it's not a standard one like I have suggested. So your solution is worse still.

Bye,
bearophile
September 29, 2008
Sun, 28 Sep 2008 20:40:53 -0400,
bearophile wrote:
> Sergey Gromov:
> 
> > Recursive building is a special case for simple tools, and in a large project you do want an incremental build.
> 
> So why not offer a handy feature for all the small cases, plus the capability of using complex incremental builds for large programs?

Well, the "give me all source on the command line" thing is a C legacy where compiler simply couldn't deduce the files required to build the project.  In D it's possible and there probably should be an -auto option in DMD.  Maybe -version=auto could be defined for the first module then.  I'm not sure.

> > But a build system can definitely do that.  Bud could do that.  Bud could define a -version=builders, or define -version=mainmodule when compiling the first module in the chain.
> 
> I see :-) Well, this solution of yours is better than nothing. I don't know if bud is updated still.

Bud supports D2.  This means it's being maintained.

> But the name of the constant you have to use into the code is is different for each module, it's not a standard one like I have suggested. So your solution is worse still.

Please read again:

> > or define -version=mainmodule when compiling the first module in the chain.

It's completely up to the build system which way to go, it has all the flexibility.
September 29, 2008
"Sergey Gromov" <snake.scaly@gmail.com> wrote in message news:MPG.234a6d462c08ea3198971e@news.digitalmars.com...
>> > or define -version=mainmodule when compiling the first module in the chain.
>
> It's completely up to the build system which way to go, it has all the flexibility.

Flexibility can be nice, but for something like what's being discussed here I think I'd prefer a language-wide standard.


September 29, 2008
Sergey Gromov:

> Please read again:
> > > or define -version=mainmodule when compiling the first module in the chain.

You are right, I am sorry for missing that.

-----------

Nick Sabalausky:

>Flexibility can be nice, but for something like what's being discussed here I think I'd prefer a language-wide standard.<

I agree.

Bye and thanks for the interesting discussion,
bearophile
September 29, 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)
October 09, 2008
On Thu, 25 Sep 2008 22:33:54 +0200, Johan Granberg wrote:

> bearophile wrote:
> 
>> Mosfet:
>>> Is there any performance loss from compared to D language ?
>> 
>> No, it's just D1 resyntaxed. That is, it generally improves on the old-school syntax of D ;-)
>> 
>> Bye,
>> bearophile
> 
> 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 :)

It's now based on D2. The main problem was that Tango's D2 branch doesn't work with GDC, so I had to switch to Phobos instead.

Pretty much all D syntax has a direct equivalent in Delight. The main missing things are:

- labels (and therefore goto). They might come back later (with a new
  syntax, since colon is used for indented blocks).

- anonymous functions are limited to expressions (as in Python).

In addition, these things are only available to modules in the dlt.* namespace:

- module level variables
- static variables
- extern

This is to encourage external libraries to be wrapped, since they generally don't fit in with the style the language is experimenting with.

> Looks good overall thou I'm particularly curious about how the dependency injection will turn out. It feels slightly similar to pure in an object oriented way :)
October 09, 2008
On Thu, Oct 9, 2008 at 8:06 PM, Thomas Leonard <talex5+d@gmail.com> wrote:
> - labels (and therefore goto). They might come back later (with a new
>  syntax, since colon is used for indented blocks).

Is there any syntactic requirement for colons on blocks as in Python? At least when I've used Python I've done nothing but curse and swear profusely when I forget a colon where it's completely obvious what my intent is.  Couldn't they be eliminated?
October 10, 2008
On Thu, 09 Oct 2008 20:40:57 +0200, Jarrett Billingsley wrote:

> On Thu, Oct 9, 2008 at 8:06 PM, Thomas Leonard <talex5+d@gmail.com> wrote:
>> - labels (and therefore goto). They might come back later (with a new
>>  syntax, since colon is used for indented blocks).
> 
> Is there any syntactic requirement for colons on blocks as in Python? At least when I've used Python I've done nothing but curse and swear profusely when I forget a colon where it's completely obvious what my intent is.  Couldn't they be eliminated?

I don't think so. For example:

  if a .b .c

could mean

  if a: .b.c

or

  if a.b: .c

Probably removing the : would require () around the condition.