www.digitalmars.com         C & C++   DMDScript  

D - DMD 0.58 release

reply "Walter" <walter digitalmars.com> writes:
Maintenance.

www.digitalmars.com/d/changelog.html
Mar 03 2003
next sibling parent reply Patrick Down <Patrick_member pathlink.com> writes:
In article <b3vdgg$1f8t$1 digitaldaemon.com>, Walter says...
Maintenance.

www.digitalmars.com/d/changelog.html

<quote> Added covariant function return types </quote> Have you documented this anywhere?
Mar 03 2003
parent "Walter" <walter digitalmars.com> writes:
"Patrick Down" <Patrick_member pathlink.com> wrote in message
news:b404ce$1tff$1 digitaldaemon.com...
 <quote>
 Added covariant function return types
 </quote>

 Have you documented this anywhere?

Documentation? Huh? <g> www.digitalmars.com/d/function.html
Mar 03 2003
prev sibling next sibling parent reply "Sean L. Palmer" <seanpalmer directvinternet.com> writes:
Yeah, what is a covariant function return type?

Sean

"Walter" <walter digitalmars.com> wrote in message
news:b3vdgg$1f8t$1 digitaldaemon.com...
 Maintenance.

 www.digitalmars.com/d/changelog.html

Mar 03 2003
parent "Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> writes:
"Sean L. Palmer" <seanpalmer directvinternet.com> escreveu na mensagem
news:b40568$1tur$1 digitaldaemon.com...
 Yeah, what is a covariant function return type?

 Sean

 "Walter" <walter digitalmars.com> wrote in message
 news:b3vdgg$1f8t$1 digitaldaemon.com...
 Maintenance.

 www.digitalmars.com/d/changelog.html


You can redefine the return type to be "more specific". That means a subclass can override a inherited method and change the return type to a subtype of the original method. class A { A self() { return this; } } class B : A { B self() { // covariant return type return this; } } http://sern.ucalgary.ca/courses/SENG/609.03/W98/Abadi/AbadiCh2.html#2.6 --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.459 / Virus Database: 258 - Release Date: 25/2/2003
Mar 03 2003
prev sibling next sibling parent reply Dan Liebgold <Dan_member pathlink.com> writes:
In article <b3vdgg$1f8t$1 digitaldaemon.com>, Walter says...
Maintenance.

www.digitalmars.com/d/changelog.html

" Added covariant function return types." Very cool! Yet another thing that is just plain broken in C++, fixed in D. Dan
Mar 03 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Dan Liebgold" <Dan_member pathlink.com> wrote in message
news:b40b5v$21pv$1 digitaldaemon.com...
 " Added covariant function return types."

 Very cool!  Yet another thing that is just plain broken in C++, fixed in

But C++ supports covariant function return types. Or is something broken about it that I'm missing? Oddly, C# does not support it, nor does Java. I'd intended to make this work in D for a while, I just was buried in other things. I've been looking at adding 'virtual types', too.
Mar 03 2003
next sibling parent reply Dan Liebgold <Dan_member pathlink.com> writes:
In article <b40d29$23a9$1 digitaldaemon.com>, Walter says...
But C++ supports covariant function return types. Or is something broken
about it that I'm missing? Oddly, C# does not support it, nor does Java. I'd
intended to make this work in D for a while, I just was buried in other
things. I've been looking at adding 'virtual types', too.

Hmmm, I guess they slipped that in to the C++ design when I wasn't looking. Do you know when it was added? It seems to have been discussed as recently as a few years ago. Dan
Mar 03 2003
parent "Walter" <walter digitalmars.com> writes:
"Dan Liebgold" <Dan_member pathlink.com> wrote in message
news:b40jlg$27to$1 digitaldaemon.com...
 In article <b40d29$23a9$1 digitaldaemon.com>, Walter says...
But C++ supports covariant function return types. Or is something broken
about it that I'm missing? Oddly, C# does not support it, nor does Java.


intended to make this work in D for a while, I just was buried in other
things. I've been looking at adding 'virtual types', too.


 you know when it was added?  It seems to have been discussed as recently

 few years ago.

I don't know when it was added, but it's in the C++98 spec.
Mar 03 2003
prev sibling next sibling parent reply Garen <garen_nospam_ wsu.edu> writes:
Walter wrote:

 But C++ supports covariant function return types. Or is something broken
 about it that I'm missing? Oddly, C# does not support it, nor does Java. I'd
 intended to make this work in D for a while, I just was buried in other
 things. I've been looking at adding 'virtual types', too.
 

Both C# and Java plan to have 'em in future releases. How would virtual types fit in with templates?
Mar 03 2003
parent "Walter" <walter digitalmars.com> writes:
"Garen" <garen_nospam_ wsu.edu> wrote in message
news:b40jpp$280e$1 digitaldaemon.com...
 Walter wrote:
 But C++ supports covariant function return types. Or is something broken
 about it that I'm missing? Oddly, C# does not support it, nor does Java.


 intended to make this work in D for a while, I just was buried in other
 things. I've been looking at adding 'virtual types', too.


I'll update www.digitalmars.com/d/comparsion.html whenver they do. D has it now.
 How would virtual types fit in with templates?

VT's are more a feature of classes, not templates.
Mar 03 2003
prev sibling next sibling parent reply "Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> writes:
"Walter" <walter digitalmars.com> escreveu na mensagem
news:b40d29$23a9$1 digitaldaemon.com...
 "Dan Liebgold" <Dan_member pathlink.com> wrote in message
 news:b40b5v$21pv$1 digitaldaemon.com...
 " Added covariant function return types."

 Very cool!  Yet another thing that is just plain broken in C++, fixed in

But C++ supports covariant function return types. Or is something broken about it that I'm missing? Oddly, C# does not support it, nor does Java.

 intended to make this work in D for a while, I just was buried in other
 things. I've been looking at adding 'virtual types', too.

http://www.mjolner.com/mjolner-system/documentation/beta-intro/ --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.459 / Virus Database: 258 - Release Date: 25/2/2003
Mar 03 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> wrote in message
news:b40pqk$2c3e$1 digitaldaemon.com...
 "Walter" <walter digitalmars.com> escreveu na mensagem
 I've been looking at adding 'virtual types', too.

http://www.mjolner.com/mjolner-system/documentation/beta-intro/

I don't understand Beta at all.
Mar 03 2003
parent reply "Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> writes:
"Walter" <walter digitalmars.com> escreveu na mensagem
news:b411ej$2gpo$1 digitaldaemon.com...
 "Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> wrote in message
 news:b40pqk$2c3e$1 digitaldaemon.com...
 "Walter" <walter digitalmars.com> escreveu na mensagem
 I've been looking at adding 'virtual types', too.

http://www.mjolner.com/mjolner-system/documentation/beta-intro/

I don't understand Beta at all.

There's a good paper about virtual types and genericity in Beta: http://citeseer.nj.nec.com/thorup99unifying.html What'll be virtual types in D? --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.459 / Virus Database: 258 - Release Date: 26/2/2003
Mar 03 2003
next sibling parent "Walter" <walter digitalmars.com> writes:
"Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> wrote in message
news:b415t0$2j23$1 digitaldaemon.com...
 There's a good paper about virtual types and genericity in Beta:

 http://citeseer.nj.nec.com/thorup99unifying.html

 What'll be virtual types in D?

That's a good paper. I'll have to study it first.
Mar 03 2003
prev sibling next sibling parent reply Bill Cox <bill viasic.com> writes:
Daniel Yokomiso wrote:
 "Walter" <walter digitalmars.com> escreveu na mensagem
 news:b411ej$2gpo$1 digitaldaemon.com...
 
"Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> wrote in message
news:b40pqk$2c3e$1 digitaldaemon.com...

"Walter" <walter digitalmars.com> escreveu na mensagem

I've been looking at adding 'virtual types', too.

By virtual types do you mean Beta like virtual classes? http://www.mjolner.com/mjolner-system/documentation/beta-intro/

I don't understand Beta at all.

There's a good paper about virtual types and genericity in Beta: http://citeseer.nj.nec.com/thorup99unifying.html What'll be virtual types in D? --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.459 / Virus Database: 258 - Release Date: 26/2/2003

Hi, Daniel. I read most of the paper you listed. Yep. Those are virtual types, and they provide a powerful programming capability. One major problem I have with the version of virtual types described in the paper is that I will probably fail in getting my team to use them. Look at how long and hard to understand the paper is. It's not the author's fault, it's simply a difficult subject. The other major issue I have with them is they look really hard to implement. An even more powerfull capability can be found in Sather, although it doesn't have the static type checking capability. It's called "include" in that language. The "include" construct seems easy to understand and use, and it is very easy to implement. Here's a URL to the manual page on the "include" construct. http://www.icsi.berkeley.edu/~sather/Documentation/LanguageDescription/webmaker/DescriptionX2Erem-chapters-1.html#HEADING1-2 I think the lack of static type checking makes it more powerful, not less. For example, with the include construct, I can apply a module's functionality to all kinds of other modules, even though they don't in any way inherit from anything that the original module knows about. That's the way it should be. You can also apply a module's functionality multiple times to other modules, without any multiple-inheritance kinds of crud in the compiler or generated code. Another nice advantage of the "include" construct is that it allows us to reuse any code, not just template code. You don't have to rely on a programmer having 20/20 foresight and providing exactly correct template wrappers in order for you to reuse his code. Everything is a template. Perl has some difficult to understand features. However, I've never seen a single one get used, and I've read a lot of Perl code. It also has very very many simple features that get used all the time (too often in my opinion). I think that's a major part of Perl's success. I'm putting in a vote for the simple version of virtual types (Sather's "include" construct). The KISS rule is rarely wrong. Bill
Mar 04 2003
parent "Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> writes:
Hi,

    Comments embedded.

"Bill Cox" <bill viasic.com> escreveu na mensagem
news:3E64B6C0.9040903 viasic.com...
[snip]
 Hi, Daniel.

 I read most of the paper you listed.  Yep.  Those are virtual types, and
 they provide a powerful programming capability.  One major problem I
 have with the version of virtual types described in the paper is that I
 will probably fail in getting my team to use them.  Look at how long and
 hard to understand the paper is.  It's not the author's fault, it's
 simply a difficult subject.  The other major issue I have with them is
 they look really hard to implement.

Every level of abstraction requires more models and less "reality" than the earlier level. Most programmers don't need to understand the details of a sufficiently advanced type system, but it should be easy enough for them to use without much problems. Something like: "Hey Bob, here's what you'll do. Inherit from this generic class Alice wrote using such and such parameters and everything will be alright". If the library hides all the complexity from the programmer and the usage syntax is simple, nothing will go wrong. Perhaps I'm too opmistic, but I don't think that Beta-like virtual types should be that hard to implement. AFAICS they're just another level of indirection.
 An even more powerfull capability can be found in Sather, although it
 doesn't have the static type checking capability.  It's called "include"
 in that language.  The "include" construct seems easy to understand and
 use, and it is very easy to implement.

 Here's a URL to the manual page on the "include" construct.

ker/DescriptionX2Erem-chapters-1.html#HEADING1-2
 I think the lack of static type checking makes it more powerful, not
 less.  For example, with the include construct, I can apply a module's
 functionality to all kinds of other modules, even though they don't in
 any way inherit from anything that the original module knows about.
 That's the way it should be.  You can also apply a module's
 functionality multiple times to other modules, without any
 multiple-inheritance kinds of crud in the compiler or generated code.

 Another nice advantage of the "include" construct is that it allows us
 to reuse any code, not just template code.  You don't have to rely on a
 programmer having 20/20 foresight and providing exactly correct template
 wrappers in order for you to reuse his code.  Everything is a template.

Hmmm, code inclusion is a form of inheritance. However there's no subtyping relationship. If we keep these two concepts separated, subclassing and subtyping, we have more coherence in the type system (i.e. no more non-conforming subtypes). Inheritance is a mechanism that many languages use to achieve subtyping but it's not its only use. AFAIK there are no problems regaring static type checking of included partial classes. Could you elaborate more on that? Eiffel is planning to include a code inclusion form of inheritance, called "non-conforming inheritance" in the next version (ETL 3). I don't know about other statically typed languages using this mechanism, but I think it's checked by the compiler. About the last remark, include mechanisms are based on inheritance. Templates are based on composition (i.e. template parameters). One can be used to emulate the other, it's just a matter of taste. IMHO there's no way to create a generic module that'll satisfy everyone, as time passes we'll always refactor base modules to improve extensibility or genericity. Mixin are easier to extend, but templates are easier to use, you don't need to subclass them and write hook functions.
 Perl has some difficult to understand features.  However, I've never
 seen a single one get used, and I've read a lot of Perl code.  It also
 has very very many simple features that get used all the time (too often
 in my opinion).  I think that's a major part of Perl's success.

 I'm putting in a vote for the simple version of virtual types (Sather's
 "include" construct).  The KISS rule is rarely wrong.

 Bill

IMO we should first start using D and see what are really the deficiencies in current mechanisms (e.g. templates, classes, delegates). If these tools fails us then we should implement alternatives. Putting features without real need it's always a bad decision. Best regards, Daniel Yokomiso. "Physics is like sex: sure, it may give some practical results, but that's not why we do it." - Richard Feynman --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.459 / Virus Database: 258 - Release Date: 25/2/2003
Mar 04 2003
prev sibling parent reply Bill Cox <bill viasic.com> writes:
Daniel Yokomiso wrote:
 "Walter" <walter digitalmars.com> escreveu na mensagem
 news:b411ej$2gpo$1 digitaldaemon.com...
 
"Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> wrote in message
news:b40pqk$2c3e$1 digitaldaemon.com...

"Walter" <walter digitalmars.com> escreveu na mensagem

I've been looking at adding 'virtual types', too.

By virtual types do you mean Beta like virtual classes? http://www.mjolner.com/mjolner-system/documentation/beta-intro/

I don't understand Beta at all.

There's a good paper about virtual types and genericity in Beta: http://citeseer.nj.nec.com/thorup99unifying.html What'll be virtual types in D? --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.459 / Virus Database: 258 - Release Date: 26/2/2003

Just two more facts supporting the need for "virtual class" functionallity. I just counted 5 places in an IC router I'm working on that would benifit from inheriting graph functionality. Virtual classes allow this to happen in a way that's natural. There have been no entries in "The Great D Pizza Contest" so far. No one on this group has yet succeeded in writing a reusable graph package in D of any kind (although Patric Down made a good start). I'm still offering 30 bucks worth of pizza for it. Here's an interesting idea... Walter, can I bribe you with 30 bucks worth of pizza to add vitual classes or Sather's "include" constructs? If so, I see a lot of pizza in your future. Bill
Mar 04 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Bill Cox" <bill viasic.com> wrote in message
news:3E64B884.9060901 viasic.com...
 I just counted 5 places in an IC router I'm working on that would
 benifit from inheriting graph functionality.  Virtual classes allow this
 to happen in a way that's natural.

What I was thinking is to allow: class C { } class D : C { } class A { C c; } class B : A { D c; } where A.c shares its storage with B.c, instead of B.c creating a new, distinct member. It will work just like virtual functions (but no vtable is required). With my reading of virtual types, this mechanism looks like it should cover the territory. What do you think?
 There have been no entries in "The Great D Pizza Contest" so far.  No
 one on this group has yet succeeded in writing a reusable graph package
 in D of any kind (although Patric Down made a good start).  I'm still
 offering 30 bucks worth of pizza for it.

I was thinking of running some sort of contest too, with a Digital Mars t-shirt as the prize, but I don't know what the challenge should be.
 Here's an interesting idea... Walter, can I bribe you with 30 bucks
 worth of pizza to add vitual classes or Sather's "include" constructs?
 If so, I see a lot of pizza in your future.

I'm pretty burned out on pizza <g>. If you want to help out Digital Mars financially, the best way is to buy the CD from www.digitalmars.com/shop.html, buy a nerd shirt from www.digitalmars.com/gift/index.html, or when you buy anything from amazon, reach amazon through one of the links at www.digitalmars.com/bibliography.html.
Mar 04 2003
next sibling parent reply "Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> writes:
"Walter" <walter digitalmars.com> escreveu na mensagem
news:b42l2l$beu$1 digitaldaemon.com...
 "Bill Cox" <bill viasic.com> wrote in message
 news:3E64B884.9060901 viasic.com...
 I just counted 5 places in an IC router I'm working on that would
 benifit from inheriting graph functionality.  Virtual classes allow this
 to happen in a way that's natural.

What I was thinking is to allow: class C { } class D : C { } class A { C c; } class B : A { D c; } where A.c shares its storage with B.c, instead of B.c creating a new, distinct member. It will work just like virtual functions (but no vtable

 required). With my reading of virtual types, this mechanism looks like it
 should cover the territory. What do you think?

Won't this break lots of code? All places that assign to c will need revision. Also with interface semantics subtle bugs can appear (this is a issue with covariant return types too): interface I { int foo(); } class C : I { int foo() { return 1; } } class D : C, I { int foo() { return 2; } } class A { C c; } class B : A { D d; } A a = new B(); I i = cast(I) a.c; i.foo(); // what will it return? there's any implicit casts to C here? --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.459 / Virus Database: 258 - Release Date: 25/2/2003
Mar 04 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> wrote in message
news:b42m76$c9c$1 digitaldaemon.com...
 "Walter" <walter digitalmars.com> escreveu na mensagem
 news:b42l2l$beu$1 digitaldaemon.com...
 "Bill Cox" <bill viasic.com> wrote in message
 news:3E64B884.9060901 viasic.com...
 I just counted 5 places in an IC router I'm working on that would
 benifit from inheriting graph functionality.  Virtual classes allow



 to happen in a way that's natural.

What I was thinking is to allow: class C { } class D : C { } class A { C c; } class B : A { D c; } where A.c shares its storage with B.c, instead of B.c creating a new, distinct member. It will work just like virtual functions (but no vtable

 required). With my reading of virtual types, this mechanism looks like


 should cover the territory. What do you think?

Won't this break lots of code? All places that assign to c will need revision. Also with interface semantics subtle bugs can appear (this is a issue with covariant return types too): interface I { int foo(); } class C : I { int foo() { return 1; } } class D : C, I { int foo() { return 2; } } class A { C c; } class B : A { D d;

I assume you meant D c; here.
 }

 A a = new B();

 I i = cast(I) a.c;
 i.foo(); // what will it return? there's any implicit casts to C here?

It will work, in this case, exactly as if (in the current implementation): A a = new B(); a.c = new D(); I i = cast(I) a.c; i.foo();
Mar 04 2003
parent reply "Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> writes:
"Walter" <walter digitalmars.com> escreveu na mensagem
news:b42pbd$edm$1 digitaldaemon.com...
 "Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> wrote in message
 news:b42m76$c9c$1 digitaldaemon.com...
 "Walter" <walter digitalmars.com> escreveu na mensagem
 news:b42l2l$beu$1 digitaldaemon.com...
 "Bill Cox" <bill viasic.com> wrote in message
 news:3E64B884.9060901 viasic.com...
 I just counted 5 places in an IC router I'm working on that would
 benifit from inheriting graph functionality.  Virtual classes allow



 to happen in a way that's natural.

What I was thinking is to allow: class C { } class D : C { } class A { C c; } class B : A { D c; } where A.c shares its storage with B.c, instead of B.c creating a new, distinct member. It will work just like virtual functions (but no



 is
 required). With my reading of virtual types, this mechanism looks like


 should cover the territory. What do you think?

Won't this break lots of code? All places that assign to c will need revision. Also with interface semantics subtle bugs can appear (this is


 issue with covariant return types too):

 interface I {
     int foo();
 }

 class C : I {
     int foo() {
         return 1;
     }
 }
 class D : C, I {
     int foo() {
         return 2;
     }
 }
 class A {
     C c;
 }
 class B : A {
     D d;

I assume you meant D c; here.

yes, my mistake.
 }

 A a = new B();

 I i = cast(I) a.c;
 i.foo(); // what will it return? there's any implicit casts to C here?

It will work, in this case, exactly as if (in the current implementation): A a = new B(); a.c = new D(); I i = cast(I) a.c; i.foo();

Hmmm, so it'll return 1. This return 2, I suppose: B b = new B(); I i = cast(I) b.c; i.foo(); Will this code be valid? A a = new B(); a.c = new C(); Or you'll add rules disallowing such classes (i.e. B) to covariantly redefine some of its attributes types? BTW the quick cheat sheet of variance is: "in" parameters must be contravariant, "out" and return type must be covariant and inout must be invariant. The same rules could be applied to D's type system, and everything would be type-safe. Or we could follow the Eiffel road and allow CAT calls (i.e. type mismatches due to type anchors, similar to virtual types). --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.459 / Virus Database: 258 - Release Date: 25/2/2003
Mar 04 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> wrote in message
news:b42qvl$fft$1 digitaldaemon.com...
     Hmmm, so it'll return 1. This return 2, I suppose:
 B b = new B();
 I i = cast(I) b.c;
 i.foo();

Yes.
     Will this code be valid?
 A a = new B();
 a.c = new C();

No. But I don't know how to detect such cases. A big hole.
     Or you'll add rules disallowing such classes (i.e. B) to covariantly
 redefine some of its attributes types? BTW the quick cheat sheet of

 is: "in" parameters must be contravariant, "out" and return type must be
 covariant and inout must be invariant.

I never figured out what contravariant is <g>.
 The same rules could be applied to
 D's type system, and everything would be type-safe. Or we could follow the
 Eiffel road and allow CAT calls (i.e. type mismatches due to type anchors,
 similar to virtual types).

Mar 04 2003
parent reply "Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> writes:
"Walter" <walter digitalmars.com> escreveu na mensagem
news:b42t3p$h4f$1 digitaldaemon.com...
 "Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> wrote in message
 news:b42qvl$fft$1 digitaldaemon.com...
     Hmmm, so it'll return 1. This return 2, I suppose:
 B b = new B();
 I i = cast(I) b.c;
 i.foo();

Yes.
     Will this code be valid?
 A a = new B();
 a.c = new C();

No. But I don't know how to detect such cases. A big hole.

It's only possible with global world analysis. Eiffel has such holes, and they are trying to close them now, at least some, in the ECMA standard. I vote against such feature in D. It'll be very easy to produce correct code for it if there's no restriction. OTOH you can just disallow subclass covariance of attributes if in the superclass the attribute is either externally writable (semantics should change) or assigned inside a final method. All methods allowing assignment of such field should then be overriden by the subclass, or a compiler error should be raised. Also issues regarding interface inherited by the superclass and the subclass (leading to two implementations) should be reviewed. interface J { void setC(C c); C getC(); } class E : J { C c; void setC(C newC) { this.c = newC; } C getC() { return this.c; } } class F : E, J { D c; void setC(C newC) { this.c = cast(D) newC; } D getC() { return this.c; } } E e = new F(); J j = cast(J) e; j.setC(new C()); // safety hole here j = cast(J) new F(); j.setC(new C()); // everything fine here Of course if we changed "F.setC(C)" (interface implementation) to "F.setC(D)" (overloading) things could get weirder. BTW I think the interface semantics are officially counter-intuitive right now. Shouldn't this be reviewed?
     Or you'll add rules disallowing such classes (i.e. B) to covariantly
 redefine some of its attributes types? BTW the quick cheat sheet of

 is: "in" parameters must be contravariant, "out" and return type must be
 covariant and inout must be invariant.

I never figured out what contravariant is <g>.

Here is a good and short link on that: http://sern.ucalgary.ca/courses/SENG/609.03/W98/Abadi/AbadiCh2.html#2.6
 The same rules could be applied to
 D's type system, and everything would be type-safe. Or we could follow


 Eiffel road and allow CAT calls (i.e. type mismatches due to type


 similar to virtual types).


--- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.459 / Virus Database: 258 - Release Date: 25/2/2003
Mar 04 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> wrote in message
news:b432o0$krg$1 digitaldaemon.com...
     It's only possible with global world analysis. Eiffel has such holes,
 and they are trying to close them now, at least some, in the ECMA

 I vote against such feature in D. It'll be very easy to produce correct

 for it if there's no restriction.

Hmm, you mean you are against the virtual type feature because you think it will be too easy to produce incorrect code?
Mar 04 2003
parent reply Daniel Yokomiso <Daniel_member pathlink.com> writes:
In article <b43dg1$rq7$1 digitaldaemon.com>, Walter says...
"Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> wrote in message
news:b432o0$krg$1 digitaldaemon.com...
     It's only possible with global world analysis. Eiffel has such holes,
 and they are trying to close them now, at least some, in the ECMA

 I vote against such feature in D. It'll be very easy to produce correct


code
 for it if there's no restriction.

Hmm, you mean you are against the virtual type feature because you think it will be too easy to produce incorrect code?

Errr, yes. My mistake. With such feature (without the restrictions) it'll be easy to forget about covariant attribute type changes when using frameworks or other functions. I believe that's better safe than sorry.
Mar 06 2003
parent "Walter" <walter digitalmars.com> writes:
"Daniel Yokomiso" <Daniel_member pathlink.com> wrote in message
news:b47sc8$ch3$1 digitaldaemon.com...
 In article <b43dg1$rq7$1 digitaldaemon.com>, Walter says...
"Daniel Yokomiso" <daniel_yokomiso yahoo.com.br> wrote in message
news:b432o0$krg$1 digitaldaemon.com...
     It's only possible with global world analysis. Eiffel has such



 and they are trying to close them now, at least some, in the ECMA

 I vote against such feature in D. It'll be very easy to produce correct


code
 for it if there's no restriction.



will be too easy to produce incorrect code?


 easy to forget about covariant attribute type changes when using

 other functions. I believe that's better safe than sorry.

I'm just going to set aside the virtual type thing for the time being, as it clearly needs a lot more thought before it's workable.
Mar 06 2003
prev sibling next sibling parent Bill Cox <bill viasic.com> writes:
Hi, Walter.

 What I was thinking is to allow:
 
 class C { }
 class D : C { }
 
 class A
 {
     C c;
 }
 
 class B : A
 {
     D c;
 }
 
 where A.c shares its storage with B.c, instead of B.c creating a new,
 distinct member. It will work just like virtual functions (but no vtable is
 required). With my reading of virtual types, this mechanism looks like it
 should cover the territory. What do you think?

This looks close. However, I get into some trouble in that the classes I want to add graph functionality to may already inherit from another class. In D, we'd have to make Graph an interface, or we'd be into multiple inheritance teritory. Interfaces aren't quite what I want, since I'd like some members from Graph, Node, and Edge added to my classes so that the Graph methods could run. The "include" feature from Sather doesn't seem to suffer from this problem. Of course, you could add multiple inheritance as a feature, but I'd be against it.
There have been no entries in "The Great D Pizza Contest" so far.  No
one on this group has yet succeeded in writing a reusable graph package
in D of any kind (although Patric Down made a good start).  I'm still
offering 30 bucks worth of pizza for it.

I was thinking of running some sort of contest too, with a Digital Mars t-shirt as the prize, but I don't know what the challenge should be.
Here's an interesting idea... Walter, can I bribe you with 30 bucks
worth of pizza to add vitual classes or Sather's "include" constructs?
If so, I see a lot of pizza in your future.

I'm pretty burned out on pizza <g>. If you want to help out Digital Mars financially, the best way is to buy the CD from www.digitalmars.com/shop.html, buy a nerd shirt from www.digitalmars.com/gift/index.html, or when you buy anything from amazon, reach amazon through one of the links at www.digitalmars.com/bibliography.html.

Ok. -- Bill
Mar 04 2003
prev sibling next sibling parent reply "Mike Wynn" <mike.wynn l8night.co.uk> writes:
 What I was thinking is to allow:

 class C { }
 class D : C { }

 class A
 {
     C c;
 }

 class B : A
 {
     D c;
 }

 where A.c shares its storage with B.c, instead of B.c creating a new,
 distinct member. It will work just like virtual functions (but no vtable

 required). With my reading of virtual types, this mechanism looks like it
 should cover the territory. What do you think?

to code); dynamic array, list or tree classes would benift from a good syntax to allow this type of construct. why not ; class A( T : C ) // must define the base class { T c; } class B : A(D) { } I think the syntax is O.K. int func( A(D) a ) { .... } int other() { return func( new B() ); } arrays/new arrays might cause parsing problems as the types A and D may not be known at the time the line is parsed A(D)[] ar = new A(D)[4]; forcing an alias first would solve any problems there, no bigger issue than having to instatiate templates first. alias A(D) AD; or use the asme syntax as real templates.
Mar 04 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Mike Wynn" <mike.wynn l8night.co.uk> wrote in message
news:b42nk1$dad$1 digitaldaemon.com...
 What I was thinking is to allow:

 class C { }
 class D : C { }

 class A
 {
     C c;
 }

 class B : A
 {
     D c;
 }

 where A.c shares its storage with B.c, instead of B.c creating a new,
 distinct member. It will work just like virtual functions (but no vtable

 required). With my reading of virtual types, this mechanism looks like


 should cover the territory. What do you think?


 to code); dynamic array, list or tree classes would benift from a good
 syntax to allow this type of construct.

 why not ;

 class A( T : C ) // must define the base class
 {
      T c;
 }

 class B : A(D)
 {
 }

 I think the syntax is O.K.

It leads to similar ambiguity problems that C++ suffers from with A<D>
 int func( A(D) a ) {
     ....
 }

 int other() { return func( new B() ); }

 arrays/new arrays might cause parsing problems as the types A and D may

 be known at the time the line is parsed

Yes. Need to be able to parse D without needing to do semantic analysis.
 A(D)[] ar = new A(D)[4];

 forcing an alias first would solve any problems there, no bigger issue

 having to instatiate templates first.
 alias A(D) AD; or use the asme syntax as real templates.

That would likely be better.
Mar 04 2003
parent reply "Mike Wynn" <mike.wynn l8night.co.uk> writes:
 why not ;

 class A( T : C ) // must define the base class
 {
      T c;
 }

 class B : A(D)
 {
 }

 I think the syntax is O.K.

It leads to similar ambiguity problems that C++ suffers from with A<D>

you already have to deal with type [type] which can look like an array lookup not a type and type(type) would only appear in the same places and again looks like it might be a func call in the class declare is class <name>['(' <lwt> ')' ] [':' <super> [ '(' <type> [',' <type>]* ')' ]] '{' <classdef> '}' rather than class <name> [':' <super>] '{' <classdef> '}' I don't see an ambiguity there. also the problem of A a = new B(); a.c = new D(); does not exists you would have to write A(D) a = new B(); allowing an A without defining its specialisation as a param void func ( A a ) { /* consider a as a read only ref to an A(C) */ } with c++ an array or banana is not an array of fruit. in D you can't have an array of obj (only obj ref like C#/Java) an array of references to banana however is a readonly array of fruit (Java allows an array of banana's to be passed as an array of fruit a) because its an array of refs, b) Java performs runtime checks on all array writes) have you considered allow a 'checked' keyword to allow a ref/array to sub class be passes as array/ref to superclass, and the same for redefinable members (basically implement a write barrier on checked items). void func( inout Fruit f ) { f = new Apple(); } void func2( checked inout Fruit f ) { f = new Apple(); } void afunc( Fruit[] f ) { f[0] = new Apple(); } void afunc2( checked Fruit[] f ) { f[0] = new Apple(); } Banana b; func( b ); // error (inout) ('out' would also require a check 'in' would not) func2( b ); // ok but will throw an exception Banana[] ar; afunc( ar ); // error unchecked array afunc2( ar ); // ok but will throw an exception allowing the programmer to determine the safety speed trade off and nothing to stop the compiler writing two versions of func2/afunc2 one with runtime checks when the compiler can not determine if the call is safe, and one fast version if it can. from the original example useing A without specifing the type is considered as a 'checked' item so all writes to the templated member are runtime checked.
Mar 05 2003
parent "Walter" <walter digitalmars.com> writes:
At the moment, I'm going to defer the virtual types based on the discussion
here, as it's pretty obvious that a *lot* more thought needs to go into it.
There are some more compelling things to do with D at the moment that have a
clear path to getting it done.
Mar 05 2003
prev sibling parent reply Dan Liebgold <Dan_member pathlink.com> writes:
In article <b42l2l$beu$1 digitaldaemon.com>, Walter says...
What I was thinking is to allow:

class C { }
class D : C { }

class A
{
    C c;
}

class B : A
{
    D c;
}

where A.c shares its storage with B.c, instead of B.c creating a new,
distinct member. It will work just like virtual functions (but no vtable is
required). With my reading of virtual types, this mechanism looks like it
should cover the territory. What do you think?

Here's one problem: (reusing C and D from above) class A { C c; this () { c = new C(...); } } class B : A { D c; this () { super(); } // oops, now my c will refer to a C rather than a D } Eiffel solves this by not requiring you to name the type to construct it -- think "c = new();" rather than "c = new C();". That would seem to require virtual constructors, so you wouldn't even define the constructor in B. Since every other type of method in a class is virtual, there should be ways of designing for this feature. Dan
Mar 04 2003
next sibling parent "Walter" <walter digitalmars.com> writes:
"Dan Liebgold" <Dan_member pathlink.com> wrote in message
news:b42u22$ho6$1 digitaldaemon.com...
 In article <b42l2l$beu$1 digitaldaemon.com>, Walter says...
What I was thinking is to allow:

class C { }
class D : C { }

class A
{
    C c;
}

class B : A
{
    D c;
}

where A.c shares its storage with B.c, instead of B.c creating a new,
distinct member. It will work just like virtual functions (but no vtable


required). With my reading of virtual types, this mechanism looks like it
should cover the territory. What do you think?

Here's one problem: (reusing C and D from above) class A { C c; this () { c = new C(...); } } class B : A { D c; this () { super(); } // oops, now my c will refer to a C rather than a D }

Yeah, Daniel pointed out an equivalent hole.
 Eiffel solves this by not requiring you to name the type to construct

 think "c = new();"  rather than "c = new C();". That would seem to require
 virtual constructors, so you wouldn't even define the constructor in B.

 Since every other type of method in a class is virtual, there should be

 designing for this feature.

I think the only way to make it work would be to do a runtime check. That also leads to having to set off the declaration of c with some distinct syntax: virtual C c; but I don't like that because it is inconsistent with virtual functions not needing a keyword. I could say it is virtual unless declared final, but that will be too ugly methinks.
Mar 04 2003
prev sibling parent Burton Radons <loth users.sourceforge.net> writes:
Dan Liebgold wrote:
 In article <b42l2l$beu$1 digitaldaemon.com>, Walter says...
 
What I was thinking is to allow:

class C { }
class D : C { }

class A
{
   C c;
}

class B : A
{
   D c;
}

where A.c shares its storage with B.c, instead of B.c creating a new,
distinct member. It will work just like virtual functions (but no vtable is
required). With my reading of virtual types, this mechanism looks like it
should cover the territory. What do you think?

Here's one problem: (reusing C and D from above) class A { C c; this () { c = new C(...); } } class B : A { D c; this () { super(); } // oops, now my c will refer to a C rather than a D } Eiffel solves this by not requiring you to name the type to construct it -- think "c = new();" rather than "c = new C();". That would seem to require virtual constructors, so you wouldn't even define the constructor in B.

It would require a virtual constructor and an item in the vtable. But I think it's inevitable - either this energy will come from here, or it will come from constructor methods that have to be overloaded in each subclass. The thing is, that this seriously violates the spirit of OO. "A" is no longer a gray box to "B", nor can it be, because large classes will balk at the implicit casting involved when you don't use a covariant overload for all methods that refer to class "C", or worse they won't and we'll have type violations: class A { C c; /* But the C object might not be a D! */ void setC(C value) { c = value; } } So it's semantically more complex than Sweeney's Frameworks, with pitfalls, while providing the exact same thing. The only benefit I'm getting from this is that you don't need to pack everything into one master class, which is a serious problem in itself.
Mar 04 2003
prev sibling parent reply "Sean L. Palmer" <seanpalmer directvinternet.com> writes:
Can we have support for "typename" as in C++?  It doesn't have to have the
same keyword.

It's mainly for templates, to indicate to the compiler that something is a
type not a value, and for when you don't know whether something is a class,
basic type, enum, or whatever.

I would specifically like for it not to require being in a template, thus we
could use it for any kind of forward declaration where the exact type isn't
needed.

Unless D doesn't ever need a forward declaration?  I suspect that it still
would require them in certain cases..

Sean
Mar 04 2003
parent "Walter" <walter digitalmars.com> writes:
"Sean L. Palmer" <seanpalmer directvinternet.com> wrote in message
news:b42s8h$g8r$1 digitaldaemon.com...
 Can we have support for "typename" as in C++?  It doesn't have to have the
 same keyword.

 It's mainly for templates, to indicate to the compiler that something is a
 type not a value, and for when you don't know whether something is a

 basic type, enum, or whatever.

But that's already syntactically distinguishable: template<T> // T is a type template<U V> // V is a value of type U
 I would specifically like for it not to require being in a template, thus

 could use it for any kind of forward declaration where the exact type

 needed.

 Unless D doesn't ever need a forward declaration?  I suspect that it still
 would require them in certain cases..

I think D has it covered, but if you have a case in mind, please post it.
Mar 04 2003
prev sibling next sibling parent reply Dan Liebgold <Dan_member pathlink.com> writes:
In article <b3vdgg$1f8t$1 digitaldaemon.com>, Walter says...
Maintenance.

www.digitalmars.com/d/changelog.html

Are there plans to support initializing arrays with function literals, like this: //------------------------------------------------// typedef void function (char*) print_proc; print_proc functbl[4] = [ (print_proc)function void (char * text) { printf(" %s,\n", text); }, (print_proc)function void (char * text) { printf(" [%s],\n", text); }, (print_proc)function void (char * text) { printf("%s,\n", text); }, (print_proc)function void (char * text) { printf(" {%s},\n", text); }, ]; void test () { for (int i = 0; i < tbl.length; ++i) functbl[i]("nonsense"); } //------------------------------------------------// Currently, the compiler complains with "non-constant expression __anonymous". Perhaps its the above code has an error? This will work if I separate out the definitions of the functions and name them, then put the names in the array. Dan
Mar 03 2003
parent "Walter" <walter digitalmars.com> writes:
"Dan Liebgold" <Dan_member pathlink.com> wrote in message
news:b40ko4$28l7$1 digitaldaemon.com...
 Are there plans to support initializing arrays with function literals,

 this:

 //------------------------------------------------//
 typedef void function (char*) print_proc;

 print_proc functbl[4] = [
 (print_proc)function void (char * text) { printf(" %s,\n", text); },
 (print_proc)function void (char * text) { printf(" [%s],\n", text); },
 (print_proc)function void (char * text) { printf("%s,\n", text); },
 (print_proc)function void (char * text) { printf(" {%s},\n", text); },
 ];

 void test () {
 for (int i = 0; i < tbl.length; ++i)
 functbl[i]("nonsense");
 }
 //------------------------------------------------//

 Currently, the compiler complains with "non-constant expression

 Perhaps its the above code has an error?

Looks like a compiler bug.
 This will work if I separate out the definitions of the functions and name

 then put the names in the array.

Mar 03 2003
prev sibling next sibling parent Burton Radons <loth users.sourceforge.net> writes:
This one must be long-standing:

    void main()
    {
    }

This program, when compiled, returns 1244984 - I was hoping for zero. 
If this isn't a well-formed main (which I do want it to be), I'd like 
for it to be erroneous.  Also:

    float main(real x)
    {
       return 0;
    }

Yeah, it links.
Mar 03 2003
prev sibling next sibling parent Patrick Down <pat codemoon.com> writes:
"Walter" <walter digitalmars.com> wrote in news:b3vdgg$1f8t$1
 digitaldaemon.com:

 Maintenance.
 
 www.digitalmars.com/d/changelog.html

Value of v is wrong in the following code. Seems the stack indexing for delegates isn't quite right yet. alias bit delegate(int) callback; bit foo(callback a) { return a(12); } class Bar { int func(int v) { foo(delegate bit(int a) { printf("%d %d\n",a,v); return true; } ); return v; } } int main(char[][] argv) { Bar b = new Bar(); b.func(15); return 0; }
Mar 03 2003
prev sibling next sibling parent Burton Radons <loth users.sourceforge.net> writes:
Long-standing:

    interface Interface
    {
        int foo;
    }

    class Class : Interface
    {
    }

    int main()
    {
        Class x = new Class;
        Interface y = x;

        printf("%d\n", y.foo);
        return 0;
    }

This links, although of course it doesn't work properly - Interface 
should be rejected by semantic0 for having a field.
Mar 06 2003
prev sibling next sibling parent Farmer <itsFarmer. freenet.de> writes:
Here are two minor bugs:


// 1. bug
template Ttest(T)
{
   class Base
   {
   }
}
// DMD crashes if type ".Base" is ommitted 
class MyClass : instance Ttest(MyClass)/*.Base*/   
{
}


// 2. bug
void func(void function () v)
{

}
int main(char args[][])
{
   static void f1();
   
   func(&f1);  // works

// error: function func (void(*v)()) does not match argument types (void())

   func(f1);  
   return 0; 
} 
Mar 07 2003
prev sibling next sibling parent Burton Radons <loth users.sourceforge.net> writes:
Using 0.59.  Long-standing, I think:

    char[][2][] foo;

    void main()
    {
       char[][2] bar;

       foo ~= bar;
    }

This fails compilation with "Internal error: ..\ztc\cod1.c 2608".
Mar 12 2003
prev sibling next sibling parent Burton Radons <loth users.sourceforge.net> writes:
With DMD 0.59.  This code fails compilation with "Assertion failure: 
'!scopesym->isWithScopeSymbol()' on line 2241 in file 'mtype.c'":

    class Foo
    {
       struct Bar
       {
       }
    }

    void main()
    {
       with (new Foo)
       {
          Bar z; /* Offending line here. */
       }
    }
Mar 12 2003
prev sibling next sibling parent Burton Radons <loth users.sourceforge.net> writes:
DMD 0.59.  This code fails to compile with "non-constant expression 
_init_array___anonymous_ArrayRank__Rank":

     template ArrayRank()
     {
         struct Rank
         {
         }
     }

     template Array()
     {
         struct Array
         {
             typedef instance ArrayRank().Rank Rank1;

             Rank1 data;
         }
     }

     typedef instance Array().Array Array_int1;

This code causes a null memory reference when compiling:

     template ArrayRank()
     {
         struct Rank
         {
         }
     }

     template Array()
     {
         typedef instance ArrayRank() foo;

         struct Array
         {
             foo.Rank data;
         }
     }

     typedef instance Array().Array Array_int1;
Mar 12 2003
prev sibling next sibling parent Burton Radons <loth users.sourceforge.net> writes:
With DMD 0.59:

    struct vec { int x; }

    typedef vec vec2;

    class Node
    {
       vec2 v;
    }

This fails compilation with "non-constant expression _init_f_vec".

    struct vec { int x; }

    typedef vec vec2 = { 0 };

    class Node
    {
       vec2 v;
    }

Note the initialiser.  This fails compilation with "Assertion failure: 
'0' on line 154 in file 'init.c'".
Mar 13 2003
prev sibling next sibling parent Burton Radons <loth users.sourceforge.net> writes:
DMD 0.59, long standing.  This code does not compile, reporting "cannot 
implicitly convert void* to Object":

    void main()
    {
       Object x;

       x = 0 ? x : null;
    }
Mar 13 2003
prev sibling next sibling parent Burton Radons <loth users.sourceforge.net> writes:
DMD 0.59.  This code compiles and runs but produces incorrect results:

    interface I
    {
    }

    class C : I
    {
       int x = 432;
    }

    int main()
    {
       C c = new C;

       printf("%p %d\n", c, c.x);
       printf("%p\n", (I) c);
       c = (C) (I) c;
       printf("%p %d\n", c, c.x);
       return 0;
    }

This prints:

    00880FD0 432
    00880FDC
    00880FDC 8720156

So casting from the interface to the instance doesn't adjust the 
pointer.  When I add a method such as in the following, the cast from 
the interface to the class results in an Access Violation:

    interface I
    {
       void foo();
    }

    class C : I
    {
       int x = 432;
       void foo() { }
    }
Mar 18 2003
prev sibling next sibling parent Burton Radons <loth users.sourceforge.net> writes:
DMD 0.59, a two-module error.  Here's module f.d:

    class F
    {
       import g;

       void method();
    }

Here's module g.d:

    import f;

    class G : F
    {
       override void method();
    }

Compiling with "dmd f.d g.d" or "dmd f.d", I get "g.d(5): function 
method function method does not override any".  This error disappears if 
the import statement in f.d is moved below the method declaration.
Mar 19 2003
prev sibling next sibling parent reply Burton Radons <loth users.sourceforge.net> writes:
DMD 0.59.  This code prints 0 when I expect 4:

     real x = 4;
     long y;

     void main ()
     {
         y = x;
         printf ("%Ld\n", y);
     }

Changing the assignment to "y = (double) x;" amends the problem.
Mar 19 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Burton Radons" <loth users.sourceforge.net> wrote in message
news:b5bi8e$s6d$1 digitaldaemon.com...
 DMD 0.59.  This code prints 0 when I expect 4:
      real x = 4;
      long y;

      void main ()
      {
          y = x;
          printf ("%Ld\n", y);
      }
 Changing the assignment to "y = (double) x;" amends the problem.

To print D longs, use the %lld format. (D longs are equivalent to C++ long longs.)
Mar 22 2003
parent Burton Radons <loth users.sourceforge.net> writes:
Walter wrote:
 "Burton Radons" <loth users.sourceforge.net> wrote in message
 news:b5bi8e$s6d$1 digitaldaemon.com...
 
DMD 0.59.  This code prints 0 when I expect 4:
     real x = 4;
     long y;

     void main ()
     {
         y = x;
         printf ("%Ld\n", y);
     }
Changing the assignment to "y = (double) x;" amends the problem.

To print D longs, use the %lld format. (D longs are equivalent to C++ long longs.)

It's not casting properly regardless.
Mar 22 2003
prev sibling next sibling parent Burton Radons <loth users.sourceforge.net> writes:
DMD 0.59.  This code improperly fails compilation with "f.d(7): cannot 
implicitly convert int to foo":

   typedef int foo;

   foo [foo] list;

   void main ()
   {
       foo x = list.keys [(foo) 0]; // This line fails.
   }

It appears that list.keys is int[] and not foo[] as it should be.
Mar 22 2003
prev sibling parent reply Burton Radons <loth users.sourceforge.net> writes:
DMD 0.59.  I'm getting the "circular initialization dependency with 
module diggl" error really bad - it's never spawned correctly, and if it 
were correctly spawned there would be no way to detect when I address 
the problem by making init functions.  So I have to put some 
initialisation in the wrong file, which can lead to mysterious errors 
when the part of the library which has the initialiser isn't included in 
an executable but the part the initialiser is for is.  For example, I 
have this in digcanvasgl.d:

   static this ()
   {
       ...
       gl = new GL;
   }

GL is in diggl.d, and it only depends upon digcanvasgl for some member 
fields, so using diggl doesn't necessarily include digcanvasgl in the 
executable.  El presto, initialiser isn't called, and code which is in 
this class will fail completely mysteriously.  I don't like having to 
write incorrect code just to get a compiler to shut up.
Mar 22 2003
parent "Walter" <walter digitalmars.com> writes:
To get rid of the error, two modules which import each other, one of them
has to not have any static initializers.

"Burton Radons" <loth users.sourceforge.net> wrote in message
news:b5j4tr$boi$1 digitaldaemon.com...
 DMD 0.59.  I'm getting the "circular initialization dependency with
 module diggl" error really bad - it's never spawned correctly, and if it
 were correctly spawned there would be no way to detect when I address
 the problem by making init functions.  So I have to put some
 initialisation in the wrong file, which can lead to mysterious errors
 when the part of the library which has the initialiser isn't included in
 an executable but the part the initialiser is for is.  For example, I
 have this in digcanvasgl.d:

    static this ()
    {
        ...
        gl = new GL;
    }

 GL is in diggl.d, and it only depends upon digcanvasgl for some member
 fields, so using diggl doesn't necessarily include digcanvasgl in the
 executable.  El presto, initialiser isn't called, and code which is in
 this class will fail completely mysteriously.  I don't like having to
 write incorrect code just to get a compiler to shut up.

Mar 30 2003