November 16, 2012
On Fri, 16 Nov 2012 03:55:53 +0100
"Stugol" <stugol@gmx.com> wrote:

> On Friday, 16 November 2012 at 02:22:32 UTC, Adam D. Ruppe wrote:
> > On Friday, 16 November 2012 at 02:00:05 UTC, Stugol wrote:
> >> Hmm, that makes a bit more sense now I guess. Funny, I don't remember seeing that rule when I read the documentation.
> >
> > It might not be clear, but it is there:
> >
> > http://dlang.org/module.html
> > "The ModuleDeclaration sets the name of the module and what
> > package it belongs to. If absent, the module name is taken to
> > be the same name (stripped of path and extension) of the source
> > file name."
> >
> > The parenthesis is important in this case - once the name is stripped of path, it only leaves a simple name, no more package info.
> 
> I'm not quite sure what purpose the MODULE keyword serves in any case. I have a file "Include.D\Infinity\Standard\Mixins\Event.d", but if I give it a module name of "infinity.standard.event" it doesn't work. I have to include the ".mixins" part. So what's the point?
> 

It sounds like you're using something that does automatic dependency tracking, like RDMD (maybe VisualD uses RDMD behind the scenes?) The only way those *can* work is of the filename/path matches (othewrwise, if it needs to find a module named "foo.bar.bat", it has no way to know where to find it if it's not in something named "foo/bar/bat.d").

In order to have module/package names that differ from the file/path names, the only way for that to work is if you pass those files in explicitly. Otherwise the compiler or build system would have to read every file on your computer hoping to find one that included the text "module foo.bar.bat;". Naturally, that wouldn't be a good idea ;)

Since it can be a pain to track all of your files manually, most people just follow the "module/package name == file/path name" convention so they can use an auto-dependency tool like RDMD.


> Also, I'm having difficulty specifying a default specialisation for a template class:
> 
>     class Event(TEventArgs : EventArgs = EventArgs) {
>     }

That would probably normally be:

    class Event(TEventArgs = EventArgs) {
    }

Unless you really are requiring that TEventArgs must be either EventArgs or something derived from EventArgs. (Maybe you are?)

> 
> Usage:
> 
>     Event!() e1;     // Works
>     Event e2;        // Won't compile
> 
> How can I have "Event" be an alias for "Event!EventArgs"?

I think function templates are the only kind that can be instantiated without the "!()" part. So "Event" just refers to the template itself, not the class inside it.

You may be able to do this:

    alias Event!() Event;

But I don't know if that would result in a naming conflict.

November 16, 2012
On Friday, 16 November 2012 at 02:55:54 UTC, Stugol wrote:
> I'm not quite sure what purpose the MODULE keyword serves in any case. I have a file "Include.D\Infinity\Standard\Mixins\Event.d", but if I give it a module name of "infinity.standard.event" it doesn't work. I have to include the ".mixins" part. So what's the point?

I haven't used VisualD but I suspect it is assuming filenames based on import declarations.

You don't have to do it this way though. If all the modules are passed on the one command, with a manual listing, the filename doesn't matter. It only uses the module line then. That's useful for times when your folder structure doesn't exactly match.


Let me give you an example. For one of my work projects, we compile it differently for different clients. What I do is have a bunch of different configuration/customization files:

custom_acme.d
custom_bugs.d
custom_daffy.d

Each of these has the same module line:

module myproduct.configuration;
/* then various config variables and little customizations are next */


Then the main app never knows about the different clients. It just does

import myproduct.configuration;

and it all just works. Now, if I want to build the one for Acme, I do: dmd myapp.d custom_acme.d, and it is good.

If I want to make the one for Bugs, I just do: dmd myapp.d custom_bugs.d and have their version.

If they buy a source license, I can send just their file without changing anything else and without exposing any of the other client's custom code.



It's something you might never need, but is really nice to have when it does come up.

> Also, I'm having difficulty specifying a default specialisation for a template class:

Yea... even with default args, you still have to use the !() to tell it that you actually want the template instantiated.

One option would be to do something like this:

class EventBase(int a = 0) {
}

alias EventBase!(0) Event;

void main() {
        EventBase!() e1;
        Event e2;
}


The alias line can include template arguments and then will work. But it needs to have a different name than the class itself so the names don't conflict.


I don't think there's any other way... either has to be Event!() like you had, or use the alias like I did here.
November 16, 2012
On Friday, 16 November 2012 at 02:55:54 UTC, Stugol wrote:

> Also, I'm having difficulty specifying a default specialisation for a template class:
>
>    class Event(TEventArgs : EventArgs = EventArgs) {
>    }
>
> Usage:
>
>    Event!() e1;     // Works
>    Event e2;        // Won't compile
>
> How can I have "Event" be an alias for "Event!EventArgs"?

I encountered this same "wtf???" today. Apparently, even with a default type specified, you still have to put in a !(). I don't know what the reasoning was behind making this seeming redundancy a requirement, and it partially defeats the purpose of the default. IN my case I wanted the default type to be selected when left unspecified, but also to get rid of the !() requirement for a more natural appearance. I was planning on asking about this in the forums later.

In any case, a simple work-a-round solution is to create an alias, for example:

alias Event!() Event_t;
// you may substitute "Event_t" with whatever type name you want

Event_t e2;        // Will compile!

BTW, I come from a C++ background, and I found that certain parts of D were more difficult to learn perhaps because of my C++ background. I think this may be because I expected things like modules to work like .h files, but they don't, or I expected copy and move semantics to work the same way in D but they don't, or I expected structs and classes to be similar to what C++ provides, but they are in fact very different in terms of how they operate. The GC is another matter to get used to. The worse of it is a lack of detailed documentation. The very best thing you can do, is get a copy of "The D Programming Language", there's also an on-line tutorial e-book, translated from Turkish into English over here http://ddili.org/ders/d.en/index.html but it is not yet fully translated.

Good luck, and have some patience, you'll need it.

--rt


November 16, 2012
On Friday, 16 November 2012 at 02:55:54 UTC, Stugol wrote:

> Also, I'm having difficulty specifying a default specialisation for a template class:
>
>    class Event(TEventArgs : EventArgs = EventArgs) {
>    }
>
> Usage:
>
>    Event!() e1;     // Works
>    Event e2;        // Won't compile
>
> How can I have "Event" be an alias for "Event!EventArgs"?

I encountered this same "wtf???" today. Apparently, even with a default type specified, you still have to put in a !(). I don't know what the reasoning was behind making this seeming redundancy a requirement, and it partially defeats the purpose of the default. IN my case I wanted the default type to be selected when left unspecified, but also to get rid of the !() requirement for a more natural appearance. I was planning on asking about this in the forums later.

In any case, a simple work-a-round solution is to create an alias, for example:

alias Event!() Event_t;
// you may substitute "Event_t" with whatever type name you want

Event_t e2;        // Will compile!

BTW, I come from a C++ background, and I found that certain parts of D were more difficult to learn perhaps because of my C++ background. I think this may be because I expected things like modules to work like .h files, but they don't, or I expected copy and move semantics to work the same way in D but they don't, or I expected structs and classes to be similar to what C++ provides, but they are in fact very different in terms of how they operate. The GC is another matter to get used to. The worse of it is a lack of detailed documentation. The very best thing you can do, is get a copy of "The D Programming Language", there's also an on-line tutorial e-book, translated from Turkish into English over here http://ddili.org/ders/d.en/index.html but it is not yet fully translated.

Good luck, and have some patience, you'll need it.

--rt


November 16, 2012
On Friday, 16 November 2012 at 03:24:28 UTC, Nick Sabalausky wrote:
>
> Unless you really are requiring that TEventArgs must be either
> EventArgs or something derived from EventArgs. (Maybe you are?)

I am.

> You may be able to do this:
>
>     alias Event!() Event;
>
> But I don't know if that would result in a naming conflict.

It does.
November 16, 2012
On Friday, 16 November 2012 at 03:32:06 UTC, Rob T wrote:
>
> I encountered this same "wtf???" today. Apparently, even with a default type specified, you still have to put in a !(). I don't know what the reasoning was behind making this seeming redundancy a requirement, and it partially defeats the purpose of the default. IN my case I wanted the default type to be selected when left unspecified, but also to get rid of the !() requirement for a more natural appearance. I was planning on asking about this in the forums later.

I agree.

> In any case, a simple work-a-round solution is to create an alias, for example:
>
> alias Event!() Event_t;
> // you may substitute "Event_t" with whatever type name you want
>
> Event_t e2;        // Will compile!

Yeah but that kinda blows, doesn't it?

> best thing you can do, is get a copy of "The D Programming Language"
>
> Good luck, and have some patience, you'll need it.

Already got it somewhere, I think. And thanks.
November 16, 2012
On Friday, 16 November 2012 at 00:55:36 UTC, Stugol wrote:
> On Friday, 16 November 2012 at 00:20:00 UTC, Adam D. Ruppe wrote:
>> On Friday, 16 November 2012 at 00:11:19 UTC, Stugol wrote:
>>> As to the module bug, I refer you to this error I just received after trying to use D again after a long absence:
>>>
>>> "Error 42: Symbol Undefined _D8infinity8standard3api7windows12__ModuleInfoZ	d:\Documents\Programming\WindowsApp1\WindowsApp1\"
>>
>> That means the your custom module wasn't given on the final command line.
>
> I'm using VisualD. I don't have a final command line.

So I'm going to have to claim this isn't a bug. And I know very little about how to address this issue with VisualD. For this reason I can't just give you an answer and instead I'll have to explain what you are being told so that you can find the missing piece. And as I don't know your experience it may sound as though I'm talking down to you.

While this may seem a nitpick it is an important distinction. This is not a compiler error, it is from the linker. This means your program has has compiled successfully.

The role of the linker is to find the machine code that can execute function calls you have made.

From your link I see that your are using DFL, This is generally built into a library and then the linker is told to grab it. And I believe you'll need to tell it to build a windows executable: /exet:nt/su:windows:4.0

http://wiki.dprogramming.com/Dfl/SetupInstructions

Onto the optional module statement. It is optional, but the name is derived from the directory and file structure at the place of compilation. So if VisualD does some incremental compilation from within a folder then the module will not be named what you are looking it up as. If this is the case then maybe the VisualD project has a bug here. I'm more incline to believe that you've attempted a combination of parts and just don't know how they fit together.

The only way to improve on this situation is to write a tutorial on how to fit x, y and z together and make a whole. Generally this would come from the one trying to fit these pieces together as everyone has their own desired combinations. You may convince someone to give it a try, but you'll make it much more likely with a reduced case that demonstrates the problem, Run is not an entry into a program. I have had my share of difficult/impossible reductions, but I can't imagine you're very far with having run into this problem.
November 16, 2012
On Friday, 16 November 2012 at 03:41:45 UTC, Stugol wrote:
>> Event_t e2;        // Will compile!
>
> Yeah but that kinda blows, doesn't it?
>

I found it surprising or unintuitive that the !() is required, and I do want to know what is the reasoning behind it, but it's not that big of a deal because the power that "alias" gives you is amazing, and makes a problem like this go away once you start using it correctly. Also don't loose sight of the fact that D has a whole lot more that is good than is bad. I find the better a language is I actually get more picky about things that I don't like. A garbage language is, well garbage, so I tend to care much less if it sucks. So to see me complain, is actually a good thing, it means I like it and want to see if get better.

--rt


November 16, 2012
> I found it surprising or unintuitive that the !() is required, and I do want to know what is the reasoning behind it

I don't know whether the language could be changed to support code like:

struct Foo(){}
Foo foo;

but doing that certainly would introduce some ambiguities. For example, consider this line:

alias Foo Bar;

Should Bar be a template or an instance of a template here?
November 16, 2012
On Friday, 16 November 2012 at 04:26:31 UTC, jerro wrote:
>> I found it surprising or unintuitive that the !() is required, and I do want to know what is the reasoning behind it
>
> I don't know whether the language could be changed to support code like:
>
> struct Foo(){}
> Foo foo;
>
> but doing that certainly would introduce some ambiguities. For example, consider this line:
>
> alias Foo Bar;
>
> Should Bar be a template or an instance of a template here?

OK, now it makes sense, I figured there had to be a reason for the !(). Thanks for letting me know.

--rt