Thread overview
defining in a module symbols for export
Nov 22, 2010
spir
Nov 22, 2010
bearophile
Nov 22, 2010
spir
Nov 22, 2010
Pelle Månsson
Nov 23, 2010
spir
Nov 22, 2010
Jesse Phillips
Nov 23, 2010
spir
November 22, 2010
Hello,

Let us say I have a parsing library. Now, I want to define parsers in stand-alone modules -- for code structuration and reusability. Then, import them from apps that need them.
Is there another way than defining the parser (== list of patterns) at the module's top-level. I have nothing against this, since the module is dedicated to this anyway -- but dmd refuses.
More generally, I find myself unable to define structured objects at a modules's top level. for instancz:

=== mod.d ==
import std.stdio;

struct S {
    int i;
    void speak() {writeln("i: ",this.i);}
}
=== __trials__.d ===
import mod;

auto s = S();
s.speak();
s.i = 1;
writeln(s.i);

void main () {
}

=== compilation ===
__trials__.d(19): no identifier for declarator s.speak
__trials__.d(20): no identifier for declarator s.i
__trials__.d(21): found '.' when expecting ')'
__trials__.d(21): semicolon expected, not 'i'
__trials__.d(21): no identifier for declarator i
__trials__.d(21): semicolon expected, not ')'
__trials__.d(21): Declaration expected, not ')'

Why does dmd refuse? If I put the code in a function, I can compile, link, and run it. But this does not match my use case: I need to export symbols (patterns) defined there; so, i guess, they must be defined at the top of the module. Is there another solution?

I take the opportunity to ask whether it is possible to define which symbols are to be _ex_ported.


Denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com

November 22, 2010
spir:

> More generally, I find myself unable to define structured objects at a modules's top level. for instancz:

I suggest to declare global variables and then initialize them in a "static this() {...}". But generally I suggest you to minimize the number of global variables.

Bye,
bearophile
November 22, 2010
On 11/22/2010 08:18 PM, spir wrote:
> Hello,
>
> Let us say I have a parsing library. Now, I want to define parsers in stand-alone modules -- for code structuration and reusability. Then, import them from apps that need them.
> Is there another way than defining the parser (== list of patterns) at the module's top-level. I have nothing against this, since the module is dedicated to this anyway -- but dmd refuses.
> More generally, I find myself unable to define structured objects at a modules's top level. for instancz:
>
> === mod.d ==
> import std.stdio;
>
> struct S {
>      int i;
>      void speak() {writeln("i: ",this.i);}
> }
> === __trials__.d ===
> import mod;
>
> auto s = S();
> s.speak();
> s.i = 1;
> writeln(s.i);
>
> void main () {
> }
>
> === compilation ===
> __trials__.d(19): no identifier for declarator s.speak
> __trials__.d(20): no identifier for declarator s.i
> __trials__.d(21): found '.' when expecting ')'
> __trials__.d(21): semicolon expected, not 'i'
> __trials__.d(21): no identifier for declarator i
> __trials__.d(21): semicolon expected, not ')'
> __trials__.d(21): Declaration expected, not ')'
>
> Why does dmd refuse? If I put the code in a function, I can compile, link, and run it. But this does not match my use case: I need to export symbols (patterns) defined there; so, i guess, they must be defined at the top of the module. Is there another solution?
>
> I take the opportunity to ask whether it is possible to define which symbols are to be _ex_ported.
>
>
> Denis
> -- -- -- -- -- -- --
> vit esse estrany ☣
>
> spir.wikidot.com
>

To initialize at runtime:

    S s;
    static this() {
        s.i = 1;
    }

to initialize at compile time:

    S getS() { S s; s.i = 1; return s; }
    S s = getS();

Use public/private to control which symbols are availible. Unfortunately, this doesn't really work at the moment :-)
November 22, 2010
On Mon, 22 Nov 2010 15:11:29 -0500
bearophile <bearophileHUGS@lycos.com> wrote:

> spir:
> 
> > More generally, I find myself unable to define structured objects at a modules's top level. for instancz:
> 
> I suggest to declare global variables and then initialize them in a "static this() {...}". But generally I suggest you to minimize the number of global variables.
> 
> Bye,
> bearophile

Yes, I would generally agree (I normally have about nothing at module toplevel), but then how can they be exported? A parser module is precisely here to define symbols for export... How do you guys write that?


denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com

November 22, 2010
spir Wrote:


> === mod.d ==
> import std.stdio;
> 
> struct S {
>     int i;
>     void speak() {writeln("i: ",this.i);}
> }
> === __trials__.d ===
> import mod;
> 
> auto s = S();
> s.speak();
> s.i = 1;
> writeln(s.i);
> 
> void main () {
> }

Others have answered how to initialize variables, but haven't explained the compilation error. A simple example of what you are doing wrong is:

import std.stdio;

writeln("foo");

void main () {
}

How are you to execute writeln()? You probably wouldn't try this under normal conditions, but is what you are trying to do. You can place it in a static this constructor:

import std.stdio;

static this() { writeln("foo"); }

void main () {
}

Note you can move the calls into main and it compiles fine:

void main () {
s.speak();
s.i = 1;
writeln(s.i);
}

November 23, 2010
On Mon, 22 Nov 2010 22:17:46 +0100
Pelle Månsson <pelle.mansson@gmail.com> wrote:

> On 11/22/2010 08:18 PM, spir wrote:
> > Hello,
> >
> > Let us say I have a parsing library. Now, I want to define parsers in stand-alone modules -- for code structuration and reusability. Then, import them from apps that need them.
> > Is there another way than defining the parser (== list of patterns) at the module's top-level. I have nothing against this, since the module is dedicated to this anyway -- but dmd refuses.
> > More generally, I find myself unable to define structured objects at a modules's top level. for instancz:
> >
> > === mod.d ==
> > import std.stdio;
> >
> > struct S {
> >      int i;
> >      void speak() {writeln("i: ",this.i);}
> > }
> > === __trials__.d ===
> > import mod;
> >
> > auto s = S();
> > s.speak();
> > s.i = 1;
> > writeln(s.i);
> >
> > void main () {
> > }
> >
> > === compilation ===
> > __trials__.d(19): no identifier for declarator s.speak
> > __trials__.d(20): no identifier for declarator s.i
> > __trials__.d(21): found '.' when expecting ')'
> > __trials__.d(21): semicolon expected, not 'i'
> > __trials__.d(21): no identifier for declarator i
> > __trials__.d(21): semicolon expected, not ')'
> > __trials__.d(21): Declaration expected, not ')'
> >
> > Why does dmd refuse? If I put the code in a function, I can compile, link, and run it. But this does not match my use case: I need to export symbols (patterns) defined there; so, i guess, they must be defined at the top of the module. Is there another solution?
> >
> > I take the opportunity to ask whether it is possible to define which symbols are to be _ex_ported.
> >
> >
> > Denis
> > -- -- -- -- -- -- --
> > vit esse estrany ☣
> >
> > spir.wikidot.com
> >
> 
> To initialize at runtime:
> 
>      S s;
>      static this() {
>          s.i = 1;
>      }
> 
> to initialize at compile time:
> 
>      S getS() { S s; s.i = 1; return s; }
>      S s = getS();
> 
> Use public/private to control which symbols are availible. Unfortunately, this doesn't really work at the moment :-)

Thank you very much!
Unfortunately, a parser is typically a bunch a definitions. I cannot expect the user (first, myself) to write a func for every little setting needed.
I could write setters on classes that require the user to set attributes, but as shown in the example, method calls are also refused.
Where is the issue, actually?


Denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com

November 23, 2010
On Mon, 22 Nov 2010 16:20:07 -0500
Jesse Phillips <jessekphillips+D@gmail.com> wrote:

> spir Wrote:
> 
> 
> > === mod.d ==
> > import std.stdio;
> > 
> > struct S {
> >     int i;
> >     void speak() {writeln("i: ",this.i);}
> > }
> > === __trials__.d ===
> > import mod;
> > 
> > auto s = S();
> > s.speak();
> > s.i = 1;
> > writeln(s.i);
> > 
> > void main () {
> > }
> 
> Others have answered how to initialize variables, but haven't explained the compilation error. A simple example of what you are doing wrong is:
> 
> import std.stdio;
> 
> writeln("foo");
> 
> void main () {
> }
> 
> How are you to execute writeln()? You probably wouldn't try this under normal conditions, but is what you are trying to do. You can place it in a static this constructor:
> 
> import std.stdio;
> 
> static this() { writeln("foo"); }
> 
> void main () {
> }
> 
> Note you can move the calls into main and it compiles fine:
> 
> void main () {
> s.speak();
> s.i = 1;
> writeln(s.i);
> }
> 

Right. Seems I may put the whole parser definition into static this(). I'll try it. Will work if symbols defined in there are available for export.


Denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com