www.digitalmars.com         C & C++   DMDScript  

D - request for module initializer

reply "Sean L. Palmer" <seanpalmer directvinternet.com> writes:
Burton Radons made a new D GUI interface that looks pretty cool. But in the
initialization of the WinMain in the usage sample, he requires:

      digInit ();
         (new Program ()).showModal (); // Run our program.
      digTerm ();

For one thing, in D you are not guaranteed that the temporary Program class
there will be destructed before the call to digTerm().  Not without calling
delete on it.  With an raii (auto) class Program you could do that maybe.

This is such a typical pattern (starting and stopping a global module) that
I feel it deserves special language support.

In Pascal, this was dealt with using Units.  A Unit is like a D module
except it had startup and shutdown code that was run automatically, and it
also separated the interface of the module from the implementation.  This is
roughly akin to a C .h header and .c file, or to public and private sections
of a D module.  The compiler would automatically initialize all the units by
calling a special function (if provided) for each unit starting with the one
with no other dependencies (actually I think system was before this, as
everything depended on that).  Then main was run and then the units were
shut down in reverse order.

I miss Pascal sometimes.

Anyway, you rarely needed any Init or Term function in Pascal that was
visible to the outside world.  And the mechanism for doing so was
standardized and completely automated from the client's point of view;  all
they had to do was "uses themodule;" and make sure the lib (if the
implementation wasn't around) was visible to the compiler.  No muss, no
fuss.

This works great so long as the module dependencies were clear.  What didn't
work so well was if unit A and unit B were mutually interdependent.

I wonder what kind of construct would be good for that?

Let's look at:  http://www.digitalmars.com/d/module.html under "Static
Construction and Destruction"

Well I notice a couple problems immediately.  One, it says a DeclDef can be
either a Constructor or a Destructor.  I doubt that you really want that, as
modules should be entirely static and thus can have at most one instance.
Constructor has the connotation that it can initialize any of multiple
objects.  Plus it conflicts with:

StaticConstructor and StaticDestructor:  the DeclDef section mentions them
but I can't find any explanation.  I assume it's similar to the Class static
constructor and static destructor, but for the module.  If so, this is
exactly what we need.

I looked at the section on Static Constructors under Classes section and
found this excerpt:
"A current weakness of the static constructors is that the order in which
they are called is not defined. Hence, for the time being, write the static
constructors to be order independent. This problem needs to be addressed in
future versions."

I guess maybe now might be a good time?

Well for one thing, it might make sense not to have any sort of module level
static constructor or destructor, and let that be done purely through the
static constructors and destructors for the classes within the module.  if
so, I recommend removing all four Constructor, Destructor, Static
Constructor, and Static Destructor from the Module section in D
documentation, and instead providing some explanation for the mechanism by
which the compiler decides which static constructors go before which others.
I recommend that through global flow analysis (what uses what) it
initializes the used ones before the users.

One more thing:  the module declaration;  If you have one module spread over
several files (all with first line "module mymodule;", does importing the
module import all the files' declarations?  If so, how does the compiler
know which files to look in to find the declarations the module consists of?

What if we extend "import ModuleNameList;" to "import ModuleNameList [ from
"D:\DcodeSample\Osfile.d" ];" ?  At least having a standard for something
like that may obviate much of the need for makefiles or other linker config.
If omitted, some other way (compiler specific) must be used to communicate
the location to find the module(s).

Anyway it appears that D has three different kinds of "classes":

classes
structs
modules

A module is just almost exactly like a class or struct except:

    It pretty much takes up at least one whole file.
    It is entirely static; one instance only.
    It can contain other classes and structs.
    It doesn't use the curly brace block syntax which is the essence of
C/C++.

With that in mind, how much of the job of a module could be done by a class
instead?  Or should it remain its own thing?  An extra keyword that makes an
ordinary class into a module (such as "static class") might be good enough.

In some languages, every distinct type or logical group of data is a class.
That sure keeps things simple in the language spec.

Sean
Oct 23 2002
parent "Mike Wynn" <mike.wynn l8night.co.uk> writes:
modules do have
static this() { ... }

but it would be nice to have initialisation params to modules

--- module code ---
static this( int val ) { ... }

--- program code ---
import mymodule;

uses mymodule( 3 );

I don't miss pascal, but do miss the Delph virtual constructors and class
types.
templated modules would be nice
so you could have the following;

--- module code ---
template(class T) package mymodule
T theapp
static this() {
    init_this_module();
theapp = new T()
    theapp.run();
cleanup_this_module();
}

--- program code ---
import mymodule( MyClass );
or
import mymodule;
uses mymodule( MyClass );

I'd also like the see templatable parameter lists
template myt( paramlist T ) { class X { int func( T ){ .. } }
instance myt( int, float, int ) ifi;
ifi foo = new ifi.X();
foo.func( 1, 2.0, 3 );
( or have function params treated as a struct )
would make code like http://sigslot.sourceforge.net
much easier to code/use. (and be very handy for crossplatfrom support).

"Sean L. Palmer" <seanpalmer directvinternet.com> wrote in message
news:ap8476$15nu$1 digitaldaemon.com...
 Burton Radons made a new D GUI interface that looks pretty cool. But in
the
 initialization of the WinMain in the usage sample, he requires:

       digInit ();
          (new Program ()).showModal (); // Run our program.
       digTerm ();

 For one thing, in D you are not guaranteed that the temporary Program
class
 there will be destructed before the call to digTerm().  Not without
calling
 delete on it.  With an raii (auto) class Program you could do that maybe.

 This is such a typical pattern (starting and stopping a global module)
that
 I feel it deserves special language support.

 In Pascal, this was dealt with using Units.  A Unit is like a D module
 except it had startup and shutdown code that was run automatically, and it
 also separated the interface of the module from the implementation.  This
is
 roughly akin to a C .h header and .c file, or to public and private
sections
 of a D module.  The compiler would automatically initialize all the units
by
 calling a special function (if provided) for each unit starting with the
one
 with no other dependencies (actually I think system was before this, as
 everything depended on that).  Then main was run and then the units were
 shut down in reverse order.

 I miss Pascal sometimes.

 Anyway, you rarely needed any Init or Term function in Pascal that was
 visible to the outside world.  And the mechanism for doing so was
 standardized and completely automated from the client's point of view;
all
 they had to do was "uses themodule;" and make sure the lib (if the
 implementation wasn't around) was visible to the compiler.  No muss, no
 fuss.

 This works great so long as the module dependencies were clear.  What
didn't
 work so well was if unit A and unit B were mutually interdependent.

 I wonder what kind of construct would be good for that?

 Let's look at:  http://www.digitalmars.com/d/module.html under "Static
 Construction and Destruction"

 Well I notice a couple problems immediately.  One, it says a DeclDef can
be
 either a Constructor or a Destructor.  I doubt that you really want that,
as
 modules should be entirely static and thus can have at most one instance.
 Constructor has the connotation that it can initialize any of multiple
 objects.  Plus it conflicts with:

 StaticConstructor and StaticDestructor:  the DeclDef section mentions them
 but I can't find any explanation.  I assume it's similar to the Class
static
 constructor and static destructor, but for the module.  If so, this is
 exactly what we need.

 I looked at the section on Static Constructors under Classes section and
 found this excerpt:
 "A current weakness of the static constructors is that the order in which
 they are called is not defined. Hence, for the time being, write the
static
 constructors to be order independent. This problem needs to be addressed
in
 future versions."

 I guess maybe now might be a good time?

 Well for one thing, it might make sense not to have any sort of module
level
 static constructor or destructor, and let that be done purely through the
 static constructors and destructors for the classes within the module.  if
 so, I recommend removing all four Constructor, Destructor, Static
 Constructor, and Static Destructor from the Module section in D
 documentation, and instead providing some explanation for the mechanism by
 which the compiler decides which static constructors go before which
others.
 I recommend that through global flow analysis (what uses what) it
 initializes the used ones before the users.

 One more thing:  the module declaration;  If you have one module spread
over
 several files (all with first line "module mymodule;", does importing the
 module import all the files' declarations?  If so, how does the compiler
 know which files to look in to find the declarations the module consists
of?
 What if we extend "import ModuleNameList;" to "import ModuleNameList [
from
 "D:\DcodeSample\Osfile.d" ];" ?  At least having a standard for something
 like that may obviate much of the need for makefiles or other linker
config.
 If omitted, some other way (compiler specific) must be used to communicate
 the location to find the module(s).

 Anyway it appears that D has three different kinds of "classes":

 classes
 structs
 modules

 A module is just almost exactly like a class or struct except:

     It pretty much takes up at least one whole file.
     It is entirely static; one instance only.
     It can contain other classes and structs.
     It doesn't use the curly brace block syntax which is the essence of
 C/C++.

 With that in mind, how much of the job of a module could be done by a
class
 instead?  Or should it remain its own thing?  An extra keyword that makes
an
 ordinary class into a module (such as "static class") might be good
enough.
 In some languages, every distinct type or logical group of data is a
class.
 That sure keeps things simple in the language spec.

 Sean
Oct 24 2002