October 04, 2014
On Saturday, 4 October 2014 at 10:38:32 UTC, ketmar via Digitalmars-d-learn wrote:
> On Sat, 04 Oct 2014 10:27:16 +0000
> John Colvin via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
> wrote:

> is there any possibility to declare *class* *method* in one

Yes, that too. Is even worse.
October 04, 2014
On Sat, 04 Oct 2014 10:37:39 +0000
eles via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote:

> No "extern" required?...
nope.


October 04, 2014
On Saturday, 4 October 2014 at 10:37:40 UTC, eles wrote:
> On Saturday, 4 October 2014 at 10:27:18 UTC, John Colvin wrote:
>> On Saturday, 4 October 2014 at 04:02:46 UTC, eles wrote:
>>> On Friday, 3 October 2014 at 15:47:33 UTC, John Colvin wrote:
>>>> On Friday, 3 October 2014 at 15:44:16 UTC, eles wrote:
>
>> So the compiler has no way of knowing whether you've forgotten to include a definition, or whether it's simply sitting in some other object file / library / whatever. The linker, however, can know, hence the linker error.
>
> No "extern" required?...

nope, no extern required. The extern you are referring to is the storage class http://dlang.org/declaration.html#extern and is for variables.

> This seem to allow an entire class of problems, by linking against long-time forgotten functions...

It's the core functionality that allows you to link to a function in a library without having the entire source available. You have a declaration, but the implementation is in another object file / library.

D is slightly tighter than C wrt all this. In C, you can just call functions without even having a declaration, the compiler will assume the argument types from what you passed in. A forgotten #include and compiling without warnings = horrific bugs in C. In D the declaration is required.
October 04, 2014
On Saturday, 4 October 2014 at 10:38:32 UTC, ketmar via Digitalmars-d-learn wrote:
> On Sat, 04 Oct 2014 10:27:16 +0000
> John Colvin via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
> wrote:
>
>> Sorry, but that's just not how it works. There is no requirement for the definition of a function to be found in the same compilation unit as it's declaration.
> is there any possibility to declare *class* *method* in one file and to
> implement it in another? O_O
>
> i doubt so.

Yes, you can. You just have to get the mangling right.

// methodLink.d
class A
{
    void foo();
}

void main()
{
    auto a = new A;
    a.foo();
}

// missingMethod.d
import methodLink;
import std.stdio;

pragma(mangle, A.foo.mangleof)
void foo() { writeln("Hello World"); }

$ dmd missingMethod.d -c
$ dmd methodLink.d missingMethod.o
$ ./methodLink
Hello World
October 04, 2014
On Saturday, 4 October 2014 at 11:01:30 UTC, John Colvin wrote:
> On Saturday, 4 October 2014 at 10:38:32 UTC, ketmar via Digitalmars-d-learn wrote:
>> On Sat, 04 Oct 2014 10:27:16 +0000
>> John Colvin via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
>> wrote:
>>
>>> Sorry, but that's just not how it works. There is no requirement for the definition of a function to be found in the same compilation unit as it's declaration.
>> is there any possibility to declare *class* *method* in one file and to
>> implement it in another? O_O
>>
>> i doubt so.
>
> Yes, you can. You just have to get the mangling right.
>
> // methodLink.d
> class A
> {
>     void foo();
> }
>
> void main()
> {
>     auto a = new A;
>     a.foo();
> }
>
> // missingMethod.d
> import methodLink;
> import std.stdio;
>
> pragma(mangle, A.foo.mangleof)
> void foo() { writeln("Hello World"); }
>
> $ dmd missingMethod.d -c
> $ dmd methodLink.d missingMethod.o
> $ ./methodLink
> Hello World

Inheritance works too:

//methodLink.d
import std.stdio;
class Base
{
    void foo() { writeln("From Base"); }
}

class A : Base
{
    override void foo();
}

void main()
{
    Base a = new A;
    a.foo();

    a.Base.foo();
}

$ dmd methodLink.d missingMethod.o
$ ./methodLink
Hello World
From Base
October 04, 2014
On Sat, 04 Oct 2014 11:01:28 +0000
John Colvin via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
wrote:

> On Saturday, 4 October 2014 at 10:38:32 UTC, ketmar via Digitalmars-d-learn wrote:
> > On Sat, 04 Oct 2014 10:27:16 +0000
> > John Colvin via Digitalmars-d-learn
> > <digitalmars-d-learn@puremagic.com>
> > wrote:
> >
> >> Sorry, but that's just not how it works. There is no requirement for the definition of a function to be found in the same compilation unit as it's declaration.
> > is there any possibility to declare *class* *method* in one
> > file and to
> > implement it in another? O_O
> >
> > i doubt so.
> 
> Yes, you can. You just have to get the mangling right.
and how about access to class fields? manual mangling is a half-working hack. alas. i really want to have some normal and non-hackish way to separate class definition and class implementation. besides, your trick is faulty, 'cause it misses hidden 'this' parameter. try that:

  // methodLink.d
  class A { void foo(int n); }
  void main () { auto a = new A; a.foo(42); }

  // missingMethod.d
  import methodLink;
  import std.stdio;

  pragma(mangle, A.foo.mangleof)
  void foo(int n) { writeln("n=", n); }

it writes gibberish and segfaults.


October 04, 2014
On Saturday, 4 October 2014 at 11:19:52 UTC, ketmar via Digitalmars-d-learn wrote:
> On Sat, 04 Oct 2014 11:01:28 +0000
> John Colvin via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
> wrote:
>
>> On Saturday, 4 October 2014 at 10:38:32 UTC, ketmar via Digitalmars-d-learn wrote:
>> > On Sat, 04 Oct 2014 10:27:16 +0000
>> > John Colvin via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
>> > wrote:
>> >
>> >> Sorry, but that's just not how it works. There is no requirement for the definition of a function to be found in the same compilation unit as it's declaration.
>> > is there any possibility to declare *class* *method* in one file and to
>> > implement it in another? O_O
>> >
>> > i doubt so.
>> 
>> Yes, you can. You just have to get the mangling right.
> and how about access to class fields? manual mangling is a half-working
> hack. alas. i really want to have some normal and non-hackish way to
> separate class definition and class implementation. besides, your trick
> is faulty, 'cause it misses hidden 'this' parameter. try that:
>
>   // methodLink.d
>   class A { void foo(int n); }
>   void main () { auto a = new A; a.foo(42); }
>
>   // missingMethod.d
>   import methodLink;
>   import std.stdio;
>
>   pragma(mangle, A.foo.mangleof)
>   void foo(int n) { writeln("n=", n); }
>
> it writes gibberish and segfaults.

good catch. This works for me, but it's probably not portable due to variations in where the hidden this is passed:

//methodLink
import std.stdio;
class Base
{
    int baseVal;
    void foo(int a) { writeln("baseVal + a: ", baseVal + a); }
}

class A : Base
{
    int aVal;
    this(int v) { aVal = v; baseVal = 2*v; }
    override void foo(int a);
}

void main()
{
    Base a = new A(42);
    a.foo(3);

    a.Base.foo(3);
}

// missingMethod.d
import methodLink;
import std.stdio;

pragma(mangle, A.foo.mangleof)
void foo(int a, A this_) { writeln("aVal + a: ", this_.aVal + a); }

$./methodLink
aVal + a: 45
baseVal + a: 87



I don't really see the point though.

class A
{
    void foo(int a) { Afoo(this, a); }
}

then declare and define Afoo however you like.
October 04, 2014
On Sat, 04 Oct 2014 15:29:55 +0000
John Colvin via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
wrote:

> I don't really see the point though.
> 
> class A
> {
>      void foo(int a) { Afoo(this, a); }
> }
> 
> then declare and define Afoo however you like.
it's noisy hackery and namespace pollution. sure i can do this and i'm using this trick when it's better to define some methods for class/struct in another module, but i don't like it. inheritance/interfaces is not the best solution sometimes.

sure, i can `import()` any text file, but this is not good for separate
compilation (and this is why i want this feature in the first place).

to make a long story short: i don't like such hacks. ;-) but i'm not yet familiar with compiler internals enough to write a patch.


October 04, 2014
On Saturday, 4 October 2014 at 15:54:26 UTC, ketmar via Digitalmars-d-learn wrote:
> On Sat, 04 Oct 2014 15:29:55 +0000
> John Colvin via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
> wrote:
>
>> I don't really see the point though.
>> 
>> class A
>> {
>>      void foo(int a) { Afoo(this, a); }
>> }
>> 
>> then declare and define Afoo however you like.
> it's noisy hackery and namespace pollution. sure i can do this and i'm
> using this trick when it's better to define some methods for
> class/struct in another module, but i don't like it.

It is a little noisy, but really very little. The only extra noise is the call to Afoo.

Namespace pollution? In what way would that cause a problem here?
October 05, 2014
On Sat, 04 Oct 2014 16:52:08 +0000
John Colvin via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
wrote:

> It is a little noisy, but really very little. The only extra noise is the call to Afoo.
it's "very little" turns to "alot" with alot of classes with alot of methods. and code readability suffers even from one such hack.

> Namespace pollution? In what way would that cause a problem here?
all this AFoo, BFoo, CFoo, XYZFoo are useless. all they do is polluting namespace, making debug info bigger and processing debug info slower. each unnecessary thing that computer must process is... well, unnecessary. ;-) i'm doing some tricks with debug info -- such as live code instrumentation, and i hate all that 'proxies'. ;-) i again must write code to deal with things that compiler should deal with.