namespace (for export)
Jonathan M Davis
jmdavisProg at gmx.com
Thu Nov 25 15:42:33 PST 2010
On Thursday 25 November 2010 09:55:44 spir wrote:
> On Thu, 25 Nov 2010 03:03:24 -0800
>
> Jonathan M Davis <jmdavisProg at gmx.com> wrote:
> > I really don't get what you're trying to do, since previous posts on this
> > topic
>
> that you've made indicate that you're trying to put statements at the
> module level, which makes no sense at all. All statements must be in a
> function and thus have an execution path.
>
> In the general case, defining symbols requires kinds of statement (but I
> don't see what you mean by "statement" as for me an assignemnt is the
> archetype of a statement, so how can you define anything?). Anyway, if I
> put definitions in a func, as you propose, then how can I have the symbols
> available for export? The answer seems to be: declare them first as
> globals. Right, but then we get this double definition issue (not that
> serious, just annoying); it's just a useless hack. What I don't understand
> is why the language refuses the same exact definition at the toplevel that
> it accepts in a func. You seems to take it for granted that I cannot
> write:
> auto myExportedSymbol = new T();
> ...
> myExportedSymbol.i = 1;
> but for me there is no obvious reason why D refuses that, and accepts
> T myExportedSymbol;
> static this () {
> auto myExportedSymbol = new T();
> ...
> myExportedSymbol.i = 1;
> }
> It's the same thing, from my point of view: when I import the module, I get
> the symbol correctly defined. I don't get why a module needs a
> constructor: why else has it a top-level?
>
> > All a module constructor is for is initializing global variables at
> > runtime.
>
> Precising runtime to import time, that's exactly what I'm looking for. How
> can one do it without static this?
1. All declarations other than non-static locals are done at compile time.
Conceptually, they can run in any order. Unlike in a function, there is no
execution path for them to be run on. So, if you have
int i = 7;
float g = 2.1;
there's nothing that says that i must be initialized before g. Such declarations
are purely declarative in nature such as you'd expect from declarative
programming.
2. static this blocks - be they module constructors or static class or static
struct constructors - are essentially special functions which are run in lexical
order in each module prior to main (and prior to the unittest blocks if -
unittest is used). They're completely at runtime and provide an execution path
statements so that you can initialize globals and static class/struct variables
with stuff that can only be done at runtime or uses other globals or statics as
part of the initialization. Modules which circularly import each other cannot
have module constructors precisely because that creates problems with knowing
the proper order to run the module constructors to avoid interdependencies and
thus avoid trying to use a variable before it has actually been initialized.
3. imports import the symbols table. The code may or may not have been fully
compiled before an import is processed. If modules are interdependent, then it
can't have been. importing a module also cannot affect the module being imported,
or the order of imports and the order of the compilation of modules matters, and
whether you import a particular module could affect other modules. Modules are
independent, can be compiled in any order - barring interdependencies - and are
only compiled once. So, having a module affected by a module importing it does
not work at all. And because symbols can at least be partially - if not fully -
compiled independently, having a global variable affected by whether it was
imported or not doesn't work at all - especially when it could be a third party
which imports it. If your module were in a compiled library (be it shared or
static), and someone using that library imports it, your code has already been
compiled and all compile-time initialization done, so it there's no way that you
could have modules be affected by who imports them or even know whether any
modules actually do import them.
It is true that some languages do not make symbols as independent of each other
as D does - C and C++ are particularly bad with how #include works - and for a
number of languages, global variables are initialized at runtime in
lexigraphical order (C++ and Java both do that), but that creates
interdependencies and bugs which only pop up at runtime when variables were
declared in a particular order. It's very messy, although if you're careful or
don't do much with globals or static variables, it's not generally a problem. D
doesn't do things that way. It made it so that all global and static variables
must be initialized at compile-time (avoiding all of the ordering and
interdependcy problems except for those posed by module constructors). This not
only avoids bugs, but it makes it possible for the compiler to parallelize their
compilation on a _much_ greater level than would be possible in a language like
C++ or Java. And while, languages like C++ and Java do do global initializations
at runtime and in do it lexographical order, they're still conceptually doing
declarative programming, so it really doesn't make sense for them to put
statements directly in the module either (though in their case, the
implementation doesn't quite match the concept). Java added static constructors
to help fix the problem, and D took it a step further by making global
initializations have to be done at compile time or in a static constructor.
So, what you're trying to do just doesn't work with D's compilation model, or
really the compilation model of any C-based language, I don't believe. In D,
modules are essentially independent, and all compilation is made as independent
as possible. Obviously, there is a dependence on order in functions (be they
static constructors or normal functions), but that's pretty much the only place
that order matters. So, I really don't think that you're going to be able to do
what you're trying to do like you've been trying to do it.
- Jonathan M Davis
More information about the Digitalmars-d-learn
mailing list