Allegro.cc - Online Community

Allegro.cc Forums » Off-Topic Ordeals » the D programming language

This thread is locked; no one can reply to it. rss feed Print
the D programming language
Thomas Fjellstrom
Member #476
June 2000
avatar

Quote:

I need an adult! I need an adult! :'(

Don't worry, he is one. And quite good at what he does too. 8-)

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Rampage
Member #3,035
December 2002
avatar

Man, this threads are fun.

Quote:

Exactly! :) and D dumbs down the linking interface so circular dependencies are harder to solve.

If D's linking is truly like Java's, there are no problems with circular dependencies like in C/C++. You just have to compile the two interdependent files at the same time. 8-)

-R

Lars Ivar Igesund
Member #8,746
June 2007

D handles circular dependencies pretty well, but one should still avoid it as it seldom is a sign of good design. There are some situations in D where you need to be aware of it, and that is if you use module constructors or static ctors, as these will be called in dependency sequence. Thus two mutually dependent modules can't both have such constructors.

As the coverage functionality in DMD depends on module ctors, it won't work if you have cycles in your module dependency graph.

torhu
Member #2,727
September 2002
avatar

Quote:

If D's linking is truly like Java's, there are no problems with circular dependencies like in C/C++. You just have to compile the two interdependent files at the same time. 8-)

Unfortunately, that doesn't help. The circular dependencies issues that you sometimes get when there's a lot of files (I've run into the problem once or twice with DAllegro, which is around 50 files), can only be solved by moving things around, or sometimes change the order of the import statements. The last time I got it, I moved the definitions that caused the problem into a file of its own.

D is not suppposed to have this problem, it's just one of the things that its creator (which also is the sole developer of the DMD compiler) hasn't gotten around to fixing yet. Even though he seems to be a a one-man army of coders, he can't do it all at once.

Someone mentioned that the D documentation sucks, and I agree. The most useful page not on the digitalmars.com site is probably this one:

http://www.prowiki.org/wiki4d/wiki.cgi?LanguageSpecification/KeywordIndex

It links to documentation for different uses of all the D keywords, and helped me a lot when I was learning D. Very handy if you already know C++ or Java, and just want to know how D does things differently.

Kitty Cat
Member #2,815
October 2002
avatar

Quote:

Someone mentioned that the D documentation sucks, and I agree.

What I said was that having no documentation is better than bad/incorrect documentation. I couldn't tell you how good D's documentation is, as I've never read it. I just mean to say that having a documentation parser in the compiler is nothing I'd tout as a "feature" because it'll just encourage lazy (bad/incorrect) documentation.

I've yet to see any documentation generator that uses source code comments to produce documentation, make good documentation and leave the source code readable.

Unless you're not talking about what I said. :P

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

Lars Ivar Igesund
Member #8,746
June 2007

When torhu talks about circular dependency problems, I believe he actually talks about forward referencing bugs. This is a problem with the compiler, but are "only" bugs, not something inherent in the language itself. They tend to crop up when porting headers/wrapping API's of other libraries, probably because you get structures that you wouldn't otherwise have used when just coding in D, and if the library is large enough, they become hard to track down. It's been a couple of years since I came across a forward reference problem myself.

The cases where the language prevents circular dependencies are those mentioned in my previous post, and these are well defined and documented.

torhu
Member #2,727
September 2002
avatar

Quote:

What I said was that having no documentation is better than bad/incorrect documentation. I couldn't tell you how good D's documentation is, as I've never read it. I just mean to say that having a documentation parser in the compiler is nothing I'd tout as a "feature" because it'll just encourage lazy (bad/incorrect) documentation.

I've yet to see any documentation generator that uses source code comments to produce documentation, make good documentation and leave the source code readable.

DDoc is cleaner than javadoc or doxygen. Most or all of digitalmars.com/d is created using DDoc. I encourage you to download the dmd compiler and read the library source in the source/phobos dir. DDoc is somewhere in between NaturalDocs and javadoc when it comes to how nice it looks in the source code.

/**
 * Do what it takes, and do it good.
 *
 * Params:
 *       x = that's the first one.
 *       y = that's the second one.
 *
 * Returns: The answer to everything.
 *
 * Note: I was pretty drunk when writing this :p
 */
int doStuff(int x, int y) { */ stuff here */ }

Compile that with 'dmd -c -D dostuff.d'. :)

bamccaig
Member #7,536
July 2006
avatar

torhu said:

Someone mentioned that the D documentation sucks, and I agree. The most useful page not on the digitalmars.com site is probably this one:http://www.prowiki.org/wiki4d/wiki.cgi?LanguageSpecification/KeywordIndex

It links to documentation for different uses of all the D keywords, and helped me a lot when I was learning D. Very handy if you already know C++ or Java, and just want to know how D does things differently.

Thanks. ;D

Kitty Cat said:

What I said was that having no documentation is better than bad/incorrect documentation. I couldn't tell you how good D's documentation is, as I've never read it. I just mean to say that having a documentation parser in the compiler is nothing I'd tout as a "feature" because it'll just encourage lazy (bad/incorrect) documentation.

I've yet to see any documentation generator that uses source code comments to produce documentation, make good documentation and leave the source code readable.

Unless you're not talking about what I said. :P

I don't know who he was referring to, but I did specifically say that...

bamccaig said:

In the time I've spent trying to learn how D does things I've learned that D's documentation sucks.

torhu said:

Most or all of digitalmars.com/d is created using DDoc.

Then I just lost faith in DDoc... :'( I'm not really talking about the appearance, but of the content... Just trying to find a page specific to the import statement and packages and how they work is impossible... WTF!?

Archon
Member #4,195
January 2004
avatar

Quote:

It sounds silly to have two classes each with a member of each other.

Nope. If they both have pointers to each other, then it's perfectly fine for them to reference each other - so they can interact. How else is is objectB going to send messages to objectA? Events?

Thomas Fjellstrom
Member #476
June 2000
avatar

Quote:

I'm not really talking about the appearance, but of the content... Just trying to find a page specific to the import statement and packages and how they work is impossible... WTF!?

Click "Language" in the first menu block, then "Modules" the second item in the second menu block.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

23yrold3yrold
Member #1,134
March 2001
avatar

Quote:

Nope. If they both have pointers to each other, then it's perfectly fine for them to reference each other

They're not talking pointers though, at least I don't think they are. Otherwise what's the big deal?

--
Software Development == Church Development
Step 1. Build it.
Step 2. Pray.

Bob
Free Market Evangelist
September 2000
avatar

Does D even have stack allocated objects? If not, then the point of it handling circular dependencies is moot: there are no circular dependencies, and that's how that problem is "solved".

Finally, please behave. No personal insults. You know who you are.

--
- Bob
[ -- All my signature links are 404 -- ]

bamccaig
Member #7,536
July 2006
avatar

The following seems relevant to the recent discussion on circular dependencies...

Modules - D Programming Language - Digital Mars said:

Cycles (circular dependencies) in the import declarations are allowed as long as not both of the modules contain static constructors or static destructors. Violation of this rule will result in a runtime exception.

- Source

Thomas Fjellstrom said:

Click "Language" in the first menu block, then "Modules" the second item in the second menu block.

Thanks... IMO, it should be Reference or Language Reference. Everything in the /d directory is about the language... :-/ I'm not a fan of that site's design. That article on Modules never did explain where files/directories need to be or how you associate them with a build... :-/ They did say that packages are I think equivalent to filesystem directories and modules are equivalent to a single source file... :-/

I'm also not a fan of D's Module Scope Operator... :-/

int x;

int foo(int x)
{
    if (y)
  return x;    // returns foo.x, not global x
    else
  return .x;    // returns global x
}

I think a global or module keyword would make it more clean... :-/ There must be a better option than using the dot operator... :-/

int x;

int foo(int x)
{
    if (y)
  return x;    // returns foo.x, not global x
    else
        return module.x;  // returns global x
// -- OR --
        return module_name.x;  // returns global x
}

VBScript uses a preceding dot operator inside it's With statement to access the With's object... :-/ I'm sort of used to that... I prefer that to JavaScript where you just directly access the properties/methods... Apparently D's with statement has syntax similar to JavaScript... :-/

// VBScript
With objObject
    .Property = intValue;
    .Method()
End With

// D | JavaScript
with(objObject)
{
    property = intValue;
    method();
}

Lars Ivar Igesund
Member #8,746
June 2007

Quote:

Does D even have stack allocated objects?

Yes.

Dustin Dettmer
Member #3,935
October 2003
avatar

Lars Ivar Igesund said:

The cases where the language prevents circular dependencies are those mentioned in my previous post, and these are well defined and documented.

I'm having a hard time understanding... could you translate this code into D for me?

// header.h
class Bar;

class Foo {
  void foo();
  void bar();
  Bar *b;
};

class Bar {
  void foo();
  void bar();
  Foo *f;
};

1// source.cpp
2void Foo::foo()
3{
4 cout << "Foo\n";
5}
6 
7void Foo::bar()
8{
9 b->bar();
10}
11 
12void Bar::foo()
13{
14 f->foo();
15}
16 
17void Bar::bar()
18{
19 cout << "Bar\n";
20}

Matthew Leverton
Supreme Loser
January 1999
avatar

In one file:

1module ref;
2 
3import std.stdio : writefln;
4 
5class Foo
6{
7 public Bar b;
8
9 public void foo()
10 {
11 writefln("Foo");
12 }
13 
14 public void bar()
15 {
16 b.bar();
17 }
18}
19 
20class Bar
21{
22 public Foo f;
23 
24 public void foo()
25 {
26 f.foo();
27 }
28 
29 public void bar()
30 {
31 writefln("Bar");
32 }
33}
34 
35int main()
36{
37 Foo f = new Foo();
38 Bar b = new Bar();
39 
40 f.b = b;
41 b.f = f;
42 
43 f.foo();
44 f.bar();
45 b.foo();
46 b.bar();
47 
48 return 0;
49}

Compile with: dmd ref.d -ofref.exe

Or in multiple files:

foo.d

1module foo;
2 
3import std.stdio : writefln;
4 
5import bar;
6 
7class Foo
8{
9 public Bar b;
10
11 public void foo()
12 {
13 writefln("Foo");
14 }
15 
16 public void bar()
17 {
18 b.bar();
19 }
20}

bar.d

1module bar;
2 
3import std.stdio : writefln;
4 
5import foo;
6 
7class Bar
8{
9 public Foo f;
10 
11 public void foo()
12 {
13 f.foo();
14 }
15 
16 public void bar()
17 {
18 writefln("Bar");
19 }
20}

ref.d

1module ref;
2 
3import foo, bar;
4 
5int main()
6{
7 Foo f = new Foo();
8 Bar b = new Bar();
9 
10 f.b = b;
11 b.f = f;
12 
13 f.foo();
14 f.bar();
15 b.foo();
16 b.bar();
17 
18 return 0;
19}

Compile with: dmd ref.d foo.d bar.d -ofref.exe. Or:

dmd -c ref.d
dmd -c foo.d
dmd -c bar.d
dmd ref.obj foo.obj bar.obj -ofref.exe

Dustin Dettmer
Member #3,935
October 2003
avatar

Ah ok, so theres a sort of 'late-binding'. I suppose I'm just too "C++ trained" to think of this sort of solution.

HoHo
Member #4,534
April 2004
avatar

Quote:

I think a global or module keyword would make it more clean... :-/ There must be a better option than using the dot operator... :-/

IIRC, in C++ you replace .x with ::x to get the global variable. Much better, isn't it?
:P

__________
In theory, there is no difference between theory and practice. But, in practice, there is - Jan L.A. van de Snepscheut
MMORPG's...Many Men Online Role Playing Girls - Radagar
"Is Java REALLY slower? Does STL really bloat your exes? Find out with your friendly host, HoHo, and his benchmarking machine!" - Jakub Wasilewski

bamccaig
Member #7,536
July 2006
avatar

HoHo said:

IIRC, in C++ you replace .x with ::x to get the global variable. Much better, isn't it?
:P

:-/ That's ugly too... WTF!? >:( It wouldn't really be an issue for my code because I prefix all global variable identifiers with a 'g'.

int gintGlobalInteger = 0;
char[] gstrGlobalString = "";
Object gobjGlobalObject = new Object();

Jonny Cook
Member #4,055
November 2003

Ewwwwww. Hungarian notation is icky.

The face of a child can say it all, especially the mouth part of the face.

Thomas Fjellstrom
Member #476
June 2000
avatar

Quote:

It wouldn't really be an issue for my code because I prefix all global variable identifiers with a 'g'.

Uhghghg. ewwww. Next you'll be telling me you also like: "wzpstrSomeStupidString".

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

bamccaig
Member #7,536
July 2006
avatar

bamccaig said:

Ewwwwww. Hungarian notation is icky.

I find that it can be useful.
[quote ]Uhghghg. ewwww. Next you'll be telling me you also like: "wzpstrSomeStupidString".
</quote>
Nah, I try to keep it simple. If it's not a common type (int, short, long, float, double, char, string) then it's usually grouped in the object category (prefix obj).

It's not perfect, but I find that it's useful anyway. I'd prefer a better way, but just plain variable identifiers seem even less organized to me. Especially when they have no underscores or case changes...

int numberofrecords; // Ugly.
int NumberOfRecords; // Acceptable.
int intNumberOfRecords; // ;D

My only problem with 'Hungarian notation' is that I haven't figured out a clean way to prefix arrays or pointers... :-/

int *p_intNumberOfRecords;  // Recently I've been experimenting with a p_
                            // prefix for pointers...

int *p_gintNumberOfRecords; // The problem is when it's a global pointer...
//         -- OR --
int *gp_intNumberOfRecords; // It gets a little bit more messy... :'(

int intPlayerIDs[10]; // Don't know what to do for arrays aside from using a plural 
                      // identifier...
//       -- OR --
int intPlayerIDArray[10]; // Or you can add an 'Array' postfix.

:-/

I find it's extra useful in OOP because your private members get prefixes and your public accessors don't.

1#include <iostream>
2 
3class Example
4{
5private:
6 int mintMember; // m=module-level scope, int=integer
7public:
8 int Member(void)
9 {
10 return mintMember;
11 }
12 
13 void Member(int intMember)
14 {
15 mintMember = intMember;
16 }
17};
18 
19int main(int argc, char* argv[])
20{
21 Example *objExample = new Example();
22 
23 cout << "Member: " << objExample->Member(); << endl; // Garbage.
24 objExample->Member(32);
25 cout << "Member: " << objExample->Member(); << endl; // 32.
26 
27 delete objExample;
28 
29 return 0;
30}

Jonny Cook
Member #4,055
November 2003

There is no clean form of Hungarian notation. It's just plain icky.

The face of a child can say it all, especially the mouth part of the face.

Thomas Fjellstrom
Member #476
June 2000
avatar

Quote:

int numberofrecords; // Ugly.
int NumberOfRecords; // Acceptable.
int intNumberOfRecords; // ;D

I prefer record_count.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

bamccaig
Member #7,536
July 2006
avatar

Thomas Fjellstrom said:

I prefer record_count.

I don't really mind that. If it was just recordcount then I'd say it could use something to make it more clean. I picked up Hungarian notation from the VB.NET classes in college whose textbook used it. It was new to me then and I kind of liked it so I started using it regularly. :-/:)

int RecordCount;    // Normally I would use RecordCount as the identifier, but
//     -- OR --     // I was just making up a quick example.
int intRecordCount;



Go to: