Thread overview
how to implement a function in a different D source file
Nov 26
Omar
Nov 26
mipri
Nov 26
mipri
Nov 26
Elronnd
Nov 27
Omar
Nov 30
Omar
November 26
Hey, I'm very interested in this programming language, I already prefer it to C++ and if only i had adopted it years ago, but that's beside the point.

I read a bunch of tuts today and the only thing I'm really stuck on at the moment is how to actually implement a function in a different file.

the page here https://dlang.org/spec/function.html
suggests you can implement a function in a different file, and a different tutorial somewhere else (or maybe the same site or even same page idr) mentioned the endeavour of no-bodied-functions as a way of presenting a black-box type of interface.

But with the whole module namespace thing I'm a bit at a loss how to do this.
Say I have main.d ex.d and ex2.d and I want to import ex, and call a function it
declares, and implement the function in ex2.d and link the objects at the end so the linker is happy. I don't know how to do this and I can't find a straigh answer anywhere or any examples.

so ?
November 26
On Tuesday, 26 November 2019 at 03:06:52 UTC, Omar wrote:
> Hey, I'm very interested in this programming language, I already prefer it to C++ and if only i had adopted it years ago, but that's beside the point.
>
> I read a bunch of tuts today and the only thing I'm really stuck on at the moment is how to actually implement a function in a different file.
>
> the page here https://dlang.org/spec/function.html
> suggests you can implement a function in a different file, and a different tutorial somewhere else (or maybe the same site or even same page idr) mentioned the endeavour of no-bodied-functions as a way of presenting a black-box type of interface.
>
> But with the whole module namespace thing I'm a bit at a loss how to do this.
> Say I have main.d ex.d and ex2.d and I want to import ex, and call a function it
> declares, and implement the function in ex2.d and link the objects at the end so the linker is happy. I don't know how to do this and I can't find a straigh answer anywhere or any examples.
>
> so ?

First, here's exactly what you're asking for:

  $ cat ex1.d
  enum string admin = "Dave";

  $ cat ex2.d
  import ex1;

  string greeting() {
      return "Hello, " ~ admin;
  }

  $ cat main.d
  import ex2;

  void main() {
      import std.stdio: writeln;
      writeln(greeting);
  }

Three files that all import what they need, and can be
compiled separately and then linked.

  $ dmd -c ex1
  $ dmd -c ex2
  $ dmd -c main
  $ dmd -ofmain main.o ex2.o ex1.o
  $ ./main
  Hello, Dave

And dmd isn't cheating, as you can see by skipping the first
two compiles:

  $ rm *.o
  $ dmd -c main
  $ dmd -ofmain main.o
  /usr/bin/ld: main.o: in function `_Dmain':
  main.d:(.text._Dmain[_Dmain]+0x5): undefined reference to `_D3ex28greetingFZAya'
  collect2: error: ld returned 1 exit status
  Error: linker exited with status 1

But you could also just compile everything together:

  $ rm *.o
  $ dmd -ofmain *.d
  $ ./main
  Hello, Dave

If all of your code is in D, my received understanding is that
this is a completely reasonable option.

You could also use dub as your build system:

  Package recipe format (sdl/json) [json]:
  Name [main]:
  Description [A minimal D application.]:
  Author name [mipri]:
  License [proprietary]: MIT
  Copyright string [Copyright © 2019, mipri]:
  Add dependency (leave empty to skip) []:

This'll create a new directory named 'main', and you can build
and run a 'hello world' by running 'dub'.

After moving some files around...

  $ cat source/movie/references/names.d
  module movie.references.names;

  enum string admin = "Dave";

  $ cat source/movie/references/lines.d
  module movie.references.lines;

  string cantDoThat() {
      import movie.references.names: admin;
      return "I'm afraid I can't do that, " ~ admin;
  }

  $ cat source/app.d
  void main() {
      import movie.references.lines: cantDoThat;
      import std.stdio: writeln;
      writeln(cantDoThat);
  }

Building and running it:

  $ dub
  Performing "debug" build using dmd for x86_64.
  main ~master: building configuration "application"...
  Linking...
  Running ./main
  I'm afraid I can't do that, Dave


November 26
On Tuesday, 26 November 2019 at 03:06:52 UTC, Omar wrote:
> the page here https://dlang.org/spec/function.html
> suggests you can implement a function in a different file
...
> mentioned the endeavour of no-bodied-functions as a way of presenting a black-box type of interface.

oh, that's what you were asking.

Consider:

  $ cat interface/references.d
  module references;

  string greeting();

  $ cat implementation/references.d
  module references;

  string greeting() {
      return "Hello, Dave";
  }

  $ cat main.d
  import references;

  void main() {
      import std.stdio: writeln;
      writeln(greeting);
  }

And trying to build it:

  $ dmd -c implementation/references.d
  $ dmd -Iinterface -c main.d
  $ dmd main.o references.o
  $ ./main
  Hello, Dave

November 26
On Tuesday, 26 November 2019 at 03:55:24 UTC, mipri wrote:
> On Tuesday, 26 November 2019 at 03:06:52 UTC, Omar wrote:
>> the page here https://dlang.org/spec/function.html
>> suggests you can implement a function in a different file
> ...
>> mentioned the endeavour of no-bodied-functions as a way of presenting a black-box type of interface.
>
> oh, that's what you were asking.
>
> Consider:
>
>   $ cat interface/references.d
>   module references;
>
>   string greeting();
>
>   $ cat implementation/references.d
>   module references;
>
>   string greeting() {
>       return "Hello, Dave";
>   }
>
>   $ cat main.d
>   import references;
>
>   void main() {
>       import std.stdio: writeln;
>       writeln(greeting);
>   }
>
> And trying to build it:
>
>   $ dmd -c implementation/references.d
>   $ dmd -Iinterface -c main.d
>   $ dmd main.o references.o
>   $ ./main
>   Hello, Dave

The idiomatic way to do that is to put the interface in a "D interface" file (.di) and the implementation in a .d file:

foo/bar.di
foo/bar.d

Then, when importing foo.bar, the compiler will pick up the .di file automatically.

And you can actually have the compiler generate the interface file for you from a source file with the -H option.
November 26
On Tuesday, 26 November 2019 at 03:06:52 UTC, Omar wrote:
> the page here https://dlang.org/spec/function.html
> suggests you can implement a function in a different file, and a different tutorial somewhere else mentioned the endeavour of no-bodied-functions as a way of presenting a black-box type of interface.

This is not a common pattern in d; the only reason it's used in c and c++ is that those languages don't have a real module system.  However, the way it's done is with .di (d interface) files.  Consider:

test.di:
module test;

void print_stuff();

main.d:
import test;

void main() {
        print_stuff();
}


test.d:
module test;
void print_stuff() {
        import std.stdio;
        writeln("I'm stuff");
}


You can verify the compiler is reading from test.di by putting test.d in a different directory from main.d and test.di.
November 27
Oh I see, it seems like the answers I'm getting imply that you have the option of a pure interface or pure implementation but not
a mix. I see how I could elaborate more on what I was asking about.

As long as you only import the file but not try to compile the same module twice right ?
So just to be clear, in D you can't do something like.

/+ a.d +/
void func1 () { /+ do stuff +/ }
void func2 () { /+ do stuff +/ }
void func3 () ;

/+ b.d +/
void func_x1 () { /+ do stuff +/   }
void func3   () { /+ true stuff +/ }

this forks into a second question but I think still fits this thread as it could just be seen as another form of the same question.
Is there a way to define some functions in the body of a class definition, and define others outside of it in other places in the
source file ?
example

/+ top.d +/
import stuff = other_stuff ;

class system {
    int           a,b,c,d ;
    float         x,y,z   ;
    stuff.struct1 p,i,e   ;
    stuff.struct2 l,t,v   ;

    int           test           (int      CMD) { /+ do stuff +/ }
    int           maintenance    (stuff.struct) { /+ do stuff +/ }
    int           connect        ()                     ;
    stuff.struct3 eval           (stuff.op[] pipeline)  ;
    void          reset          (int node)             ;
    void          save           (stuff.struct_x state) ;
    void          exportFile     (string name)          ;
    void          loadFromStream ()                     ;
    void          loadFromFile   ()                     ;
}

/+ implement those 7 functions here or in other files +/

November 28
On Wednesday, 27 November 2019 at 23:32:34 UTC, Omar wrote:
> this forks into a second question but I think still fits this thread as it could just be seen as another form of the same question.
> Is there a way to define some functions in the body of a class definition, and define others outside of it in other places in the
> source file ?

No, there isn't. You have to define all of a class's methods in the class body.

However, you can define free functions that can be called with the same syntax as methods using UFCS [1]. For example:

import std.stdio;

class C {
    void foo() { writeln("foo"); }
}

void bar(C c) { writeln("bar"); }

void main() {
    C c;
    c.foo();
    c.bar();
}

The main limitation is that, because `bar` is really a free function and not a method, it will not be inherited by C's child classes, and therefore cannot be overridden.

[1] https://dlang.org/spec/function.html#pseudo-member
November 30
ok, thanks for the replies everyone !

I think i might try fiddling around with mixins and see how i like that.