digitalmars.D - forbid field name conflict in class hierarchy
- spir (35/35) Nov 14 2010 Hello,
- Stanislav Blinov (9/43) Nov 14 2010 This issue has been brought up several times before. I myself see no
- spir (21/65) Nov 14 2010 the same name as super-classes. After all, names (in addition to types) ...
- Daniel Gibson (5/58) Nov 14 2010 No, only shadowing private fields is harmless (because the sub-class can...
- Stanislav Blinov (9/36) Nov 15 2010 Well, yes. Even shadowing of private fields is as bad as long as a
- Jonathan M Davis (7/12) Nov 15 2010 Personally, it's the kind of thing that I generally avoid, but there are...
- Jonathan M Davis (10/23) Nov 14 2010 Private fields are effectively hidden from derived classes. Derived clas...
- Manfred_Nowak (4/5) Nov 15 2010 Detecting a problem requires having a model.
- Jonathan M Davis (9/14) Nov 15 2010 You're going to have to be more specific in your question than that. It'...
- spir (22/37) Nov 15 2010 not at=20
- Manfred_Nowak (3/4) Nov 14 2010 ... support protocols for variables in non-release mode.
- spir (15/32) Nov 15 2010 ate
- bearophile (13/14) Nov 14 2010 I have a bug report on it:
- spir (11/26) Nov 14 2010 the same name as super-classes.
- bearophile (4/5) Nov 14 2010 I don't know. C# shows a warning if an attribute is masked by another on...
- Jonathan M Davis (12/43) Nov 15 2010 I'm not sure that pure OO would even allow for public variables. I do re...
- spir (33/80) Nov 15 2010 It's
- bearophile (5/6) Nov 16 2010 What do you mean? Do you have an example?
- spir (19/28) Nov 16 2010 ght, for any reason), so I add fields to the top type.
- Dmitry Olshansky (56/72) Nov 16 2010 Looks like a good question for D.learn.
- spir (8/17) Nov 16 2010 ght, for any reason), so I add fields to the top type.
- Jonathan M Davis (9/34) Nov 16 2010 Well, I think that I'd have to study your code to get quite what you're ...
Hello, I think the compiler should complain when sub-classes hold fields with the = same name as super-classes. After all, names (in addition to types) are use= d to identify. Intentionally reusing the same name would not only be bad de= sign, but open the door to hidden bugs. Remain unintentional name crash: eg forgot to remove a field when establish= ed type hierarchy. Allowing same names lead to strange contradictions by th= e language -- see below. Without such a rigor imposed the compiler, we can = easily fall into traps such as: class C { int i; this (int i) { this.i =3D i; } } class C1 : C { // forgot to remove i int i; int j; this (int i, int j) { super(i); // think i is set? this.j =3D j; } } void main () { auto c1 =3D new C1(1,2); writeln(c1.i); // 0 } Got me 3 times already. I don't understand how it is even possible that C.i= is not the same as C1.i, but evidence is here... There is a contradiction:= i is set && not set. (explaination welcome ;-) Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Nov 14 2010
spir wrote:Hello, I think the compiler should complain when sub-classes hold fields with the same name as super-classes. After all, names (in addition to types) are used to identify. Intentionally reusing the same name would not only be bad design, but open the door to hidden bugs. Remain unintentional name crash: eg forgot to remove a field when established type hierarchy. Allowing same names lead to strange contradictions by the language -- see below. Without such a rigor imposed the compiler, we can easily fall into traps such as: class C { int i; this (int i) { this.i = i; } } class C1 : C { // forgot to remove i int i; int j; this (int i, int j) { super(i); // think i is set? this.j = j; } } void main () { auto c1 = new C1(1,2); writeln(c1.i); // 0 } Got me 3 times already. I don't understand how it is even possible that C.i is not the same as C1.i, but evidence is here... There is a contradiction: i is set && not set. (explaination welcome ;-) Denis -- -- -- -- -- -- -- vit esse estrany ☣ spir.wikidot.comThis issue has been brought up several times before. I myself see no harm in this shadowing, though making a compiler issue a warning when shadowing *public* fields occurs would be a good thing. Shadowing non-public fields, in my opinion, is harmless, and preventing it would actually narrow down name choice with each subsequent subclassing. The other option that comes to mind is simply disallow public fields for classes. This may sound too strict, but I think that public fields is something that's not as usable for classes as for structs.
Nov 14 2010
On Sun, 14 Nov 2010 22:09:59 +0300 Stanislav Blinov <stanislav.blinov gmail.com> wrote:spir wrote:the same name as super-classes. After all, names (in addition to types) are= used to identify. Intentionally reusing the same name would not only be ba= d design, but open the door to hidden bugs.Hello, =20 =20 I think the compiler should complain when sub-classes hold fields with =lished type hierarchy. Allowing same names lead to strange contradictions b= y the language -- see below. Without such a rigor imposed the compiler, we = can easily fall into traps such as:Remain unintentional name crash: eg forgot to remove a field when estab=C.i is not the same as C1.i, but evidence is here... There is a contradict= ion: i is set && not set. (explaination welcome ;-)=20 class C { int i; this (int i) { this.i =3D i; } } class C1 : C { // forgot to remove i int i; int j; this (int i, int j) { super(i); // think i is set? this.j =3D j; } } void main () { auto c1 =3D new C1(1,2); writeln(c1.i); // 0 } =20 Got me 3 times already. I don't understand how it is even possible that=g. I don't understand in which case you need to reuse the same name in a subcl= ass for a _different_ field -- whether the field is public or private does = not seem really relevant to me. But maybe I overlook some common use case.=20 Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 =20 spir.wikidot.com =20=20 This issue has been brought up several times before. I myself see no=20 harm in this shadowing, though making a compiler issue a warning when shadowing *public* fields occurs would be a good thing. Shadowing non-public fields, in my opinion, is harmless, and preventing=20 it would actually narrow down name choice with each subsequent subclassin=The other option that comes to mind is simply disallow public fields for==20classes. This may sound too strict, but I think that public fields is=20 something that's not as usable for classes as for structs.Here, I guess you're touching programming style. I personly am allergic to = accessors for everything. Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Nov 14 2010
Stanislav Blinov schrieb:spir wrote:No, only shadowing private fields is harmless (because the sub-class can't access them anyway), but shadowing protected fields is about as bad as shadowing public fields.Hello, I think the compiler should complain when sub-classes hold fields with the same name as super-classes. After all, names (in addition to types) are used to identify. Intentionally reusing the same name would not only be bad design, but open the door to hidden bugs. Remain unintentional name crash: eg forgot to remove a field when established type hierarchy. Allowing same names lead to strange contradictions by the language -- see below. Without such a rigor imposed the compiler, we can easily fall into traps such as: class C { int i; this (int i) { this.i = i; } } class C1 : C { // forgot to remove i int i; int j; this (int i, int j) { super(i); // think i is set? this.j = j; } } void main () { auto c1 = new C1(1,2); writeln(c1.i); // 0 } Got me 3 times already. I don't understand how it is even possible that C.i is not the same as C1.i, but evidence is here... There is a contradiction: i is set && not set. (explaination welcome ;-) Denis -- -- -- -- -- -- -- vit esse estrany ☣ spir.wikidot.comThis issue has been brought up several times before. I myself see no harm in this shadowing, though making a compiler issue a warning when shadowing *public* fields occurs would be a good thing. Shadowing non-public fields, in my opinion, is harmless, and preventing it would actually narrow down name choice with each subsequent subclassing.The other option that comes to mind is simply disallow public fields for classes. This may sound too strict, but I think that public fields is something that's not as usable for classes as for structs.Disallowing public fields is too restrictive IMHO.
Nov 14 2010
Daniel Gibson wrote:Stanislav Blinov schrieb:Well, yes. Even shadowing of private fields is as bad as long as a subclass is in the same module as base class. Come to think of it, maybe, it'd be better if the compiler warned about shadowing whenever shadowed name is directly visible, not just in case of public fields. Though the problem fully manifests itself in client code, where only public members are exposed.spir wrote:No, only shadowing private fields is harmless (because the sub-class can't access them anyway), but shadowing protected fields is about as bad as shadowing public fields.Hello, I think the compiler should complain when sub-classes hold fields with the same name as super-classes. After all, names (in addition to types) are used to identify. Intentionally reusing the same name would not only be bad design, but open the door to hidden bugs.This issue has been brought up several times before. I myself see no harm in this shadowing, though making a compiler issue a warning when shadowing *public* fields occurs would be a good thing. Shadowing non-public fields, in my opinion, is harmless, and preventing it would actually narrow down name choice with each subsequent subclassing.Maybe. I just always view public fields as encapsulation breakers. And silent invariant breakers. And maintenance cripplers :)The other option that comes to mind is simply disallow public fields for classes. This may sound too strict, but I think that public fields is something that's not as usable for classes as for structs.Disallowing public fields is too restrictive IMHO.
Nov 15 2010
On Monday 15 November 2010 02:29:55 Stanislav Blinov wrote:Daniel Gibson wrote:Personally, it's the kind of thing that I generally avoid, but there are situations where it makes good sense to have them. I think that it's one of those cases where the programmer should have the freedom to choose. Most of the time that choice should probably be property functions over public member variables, but forcing the issue is definitely too restrictive. - Jonathan M DavisDisallowing public fields is too restrictive IMHO.Maybe. I just always view public fields as encapsulation breakers. And silent invariant breakers. And maintenance cripplers :)
Nov 15 2010
On Sunday 14 November 2010 11:29:55 spir wrote:On Sun, 14 Nov 2010 22:09:59 +0300 Stanislav Blinov <stanislav.blinov gmail.com> wrote:Private fields are effectively hidden from derived classes. Derived classes shouldn't care what they're named and shouldn't have to care. The only time that it becomes any kind of issue is if both the base class and derived class are in the same module, since then the derived class has access to the base class' private members and functions (even though it probably shouldn't actually use them) from being in the same module. Having public fields shadow each other is problematic. Having private fields do so should be irrelevant. - Jonathan M DavisThis issue has been brought up several times before. I myself see no harm in this shadowing, though making a compiler issue a warning when shadowing *public* fields occurs would be a good thing. Shadowing non-public fields, in my opinion, is harmless, and preventing it would actually narrow down name choice with each subsequent subclassing.I don't understand in which case you need to reuse the same name in a subclass for a _different_ field -- whether the field is public or private does not seem really relevant to me. But maybe I overlook some common use case.
Nov 14 2010
Jonathan M Davis wrote:Having public fields shadow each other is problematic.Detecting a problem requires having a model. What does your model look like? -manfred
Nov 15 2010
On Monday, November 15, 2010 06:00:33 Manfred_Nowak wrote:Jonathan M Davis wrote:You're going to have to be more specific in your question than that. It's not at all clear what you're asking. Public and protected functions use polymorphism. Public and protected member variables do not. So, it becomes error prone to have public or protected member variables which shadow each other. It becomes easy to end up in a situation where you're not using the one that you think that you're using - especially when code gets changed. - Jonathan M DavisHaving public fields shadow each other is problematic.Detecting a problem requires having a model. What does your model look like?
Nov 15 2010
On Mon, 15 Nov 2010 09:45:26 -0800 Jonathan M Davis <jmdavisProg gmx.com> wrote:On Monday, November 15, 2010 06:00:33 Manfred_Nowak wrote:not at=20Jonathan M Davis wrote:=20 You're going to have to be more specific in your question than that. It's=Having public fields shadow each other is problematic.=20 Detecting a problem requires having a model. What does your model look like?all clear what you're asking. =20 Public and protected functions use polymorphism. Public and protected mem=ber=20variables do not. So, it becomes error prone to have public or protected =member=20variables which shadow each other. It becomes easy to end up in a situati=on=20where you're not using the one that you think that you're using - especia=lly=20when code gets changed.True. There is an issue in the static model of OO, with class hierarchy: me= thods are dispatched, data fields are not. If there are "same" fields (same= name & type), then the one of the superclass is used. The only safe altern= ative would be to have runtime dispatch of fields like of methods, but this= is indeed costly. (This "staticity" also leads to the side-effect that one cannot write gener= ic routines which variables (from parameters or result of calls) have the s= uperclass as declared type but also use subclass fields. To be able to do i= t, I end up adding subclass fields to the superclass. I know it's wrong, bu= t haven't found the right way to do it. I don't feel like "downcasting" mos= t variables in most routines.) Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Nov 15 2010
Stanislav Blinov wrote:The other option that comes to mind is... support protocols for variables in non-release mode. -manfred
Nov 14 2010
On Sun, 14 Nov 2010 16:25:56 -0800 Jonathan M Davis <jmdavisProg gmx.com> wrote:On Sunday 14 November 2010 11:29:55 spir wrote:ateI don't understand in which case you need to reuse the same name in a subclass for a _different_ field -- whether the field is public or priv=sedoes not seem really relevant to me. But maybe I overlook some common u=es=20case.=20 Private fields are effectively hidden from derived classes. Derived class=shouldn't care what they're named and shouldn't have to care. The only ti=me that=20it becomes any kind of issue is if both the base class and derived class =are in=20the same module, since then the derived class has access to the base clas=s'=20private members and functions (even though it probably shouldn't actually=use=20them) from being in the same module. =20 Having public fields shadow each other is problematic. Having private fie=lds do so=20should be irrelevant. =20 - Jonathan M DavisRight, this makes sense. Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Nov 15 2010
spir:I think the compiler should complain when sub-classes hold fields with the same name as super-classes.I have a bug report on it: http://d.puremagic.com/issues/show_bug.cgi?id=5187 programmer wants to hide: public class Foo { public int x = 10; } public class Test : Foo { new public int x = 20; public static void Main() {} } Bye, bearophile
Nov 14 2010
On Sun, 14 Nov 2010 14:22:56 -0500 bearophile <bearophileHUGS lycos.com> wrote:spir: =20the same name as super-classes.I think the compiler should complain when sub-classes hold fields with ==20 I have a bug report on it: http://d.puremagic.com/issues/show_bug.cgi?id=3D5187You have bug reports for everything and the rest ;-)the programmer wants to hide:=20 public class Foo { public int x =3D 10; } public class Test : Foo { new public int x =3D 20; public static void Main() {} }What are use cases for this? (And wouldn't it be better practice to change = name even in supposed sensible cases?) denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Nov 14 2010
spir:What are use cases for this? (And wouldn't it be better practice to change name even in supposed sensible cases?)I think they have added that "new" syntax as a clean way to silence that design decisions. Such explanations are often not present even inside books about a programming language. TDPL has some of such explanations). Bye, bearophile
Nov 14 2010
On Monday 15 November 2010 11:44:11 spir wrote:On Mon, 15 Nov 2010 09:45:26 -0800 Jonathan M Davis <jmdavisProg gmx.com> wrote:I'm not sure that pure OO would even allow for public variables. I do really have to wonder what you're doing though that you feel the need to access subclass fields using super class references. That just screams that it shouldn't be a public member variable (and truth be told, public member variables are generally considered bad practice except in simple objects - which would generally be structs in D). And if you really need the subclass type, then you should be using the subclass type, not the super class type. Also, return types are covariant, so you can return a subclass from overridden functions instead of the super class like the function which was overridden does. Maybe that would help. It would depend on what exactly you're doing though. - Jonathan M DavisOn Monday, November 15, 2010 06:00:33 Manfred_Nowak wrote:True. There is an issue in the static model of OO, with class hierarchy: methods are dispatched, data fields are not. If there are "same" fields (same name & type), then the one of the superclass is used. The only safe alternative would be to have runtime dispatch of fields like of methods, but this is indeed costly. (This "staticity" also leads to the side-effect that one cannot write generic routines which variables (from parameters or result of calls) have the superclass as declared type but also use subclass fields. To be able to do it, I end up adding subclass fields to the superclass. I know it's wrong, but haven't found the right way to do it. I don't feel like "downcasting" most variables in most routines.)Jonathan M Davis wrote:You're going to have to be more specific in your question than that. It's not at all clear what you're asking. Public and protected functions use polymorphism. Public and protected member variables do not. So, it becomes error prone to have public or protected member variables which shadow each other. It becomes easy to end up in a situation where you're not using the one that you think that you're using - especially when code gets changed.Having public fields shadow each other is problematic.Detecting a problem requires having a model. What does your model look like?
Nov 15 2010
On Mon, 15 Nov 2010 12:32:07 -0800 Jonathan M Davis <jmdavisProg gmx.com> wrote:On Monday 15 November 2010 11:44:11 spir wrote:It'sOn Mon, 15 Nov 2010 09:45:26 -0800 =20 Jonathan M Davis <jmdavisProg gmx.com> wrote:On Monday, November 15, 2010 06:00:33 Manfred_Nowak wrote:Jonathan M Davis wrote:=20 You're going to have to be more specific in your question than that. =Having public fields shadow each other is problematic.=20 Detecting a problem requires having a model. What does your model look like?hatnot at all clear what you're asking. =20 Public and protected functions use polymorphism. Public and protected member variables do not. So, it becomes error prone to have public or protected member variables which shadow each other. It becomes easy to end up in a situation where you're not using the one that you think t=feyou're using - especially when code gets changed.=20 True. There is an issue in the static model of OO, with class hierarchy: methods are dispatched, data fields are not. If there are "same" fields (same name & type), then the one of the superclass is used. The only sa=avealternative would be to have runtime dispatch of fields like of methods, but this is indeed costly. =20 (This "staticity" also leads to the side-effect that one cannot write generic routines which variables (from parameters or result of calls) h=re=20the superclass as declared type but also use subclass fields. To be able to do it, I end up adding subclass fields to the superclass. I know it's wrong, but haven't found the right way to do it. I don't feel like "downcasting" most variables in most routines.)=20 I'm not sure that pure OO would even allow for public variables. [...] That just screams that it shouldn't=20 be a public member variable (and truth be told, public member variables a=generally considered bad practice except in simple objects - which would==20generally be structs in D).The issue does not require fields to be public. The same problem happens wh= en writing methods of the class hierarchy.I do really=20 have to wonder what you're doing though that you feel the need to access==20subclass fields using super class references. [...] And if you really nee=d the subclass type, then you=20should be using the subclass type, not the super class typeFor instance a nested/recursive structure analog to a tree. There may be le= af nodes (only element), branch nodes (only subnodes), both, special ones w= ith different kinds of values, etc... Custom routines may need to use other methods to explore a branch's childre= n, get its leaves, filter, or whatever. All these tool methods are generic = (meaning must use the top Node type), but the custom routines need to acces= s subtype-specific fields. Thus, "down-casting" all the time. I find it tiresome (and bug-prone, because sometimes the absence of a field= s seems not caught, for any reason), so I add fields to the top type.Also, return types=20 are covariant, so you can return a subclass from overridden functions ins=tead of=20the super class like the function which was overridden does. Maybe that w=ould=20help. It would depend on what exactly you're doing though.Yes, but doesn't this mean I should override all tool methods for all subty= pes, just so that I don't need to down-cast their results (in the routines = that use them)? I think a better solution would be that the compiler does not prevent us to= use subtype fields. Why does it do so? In the worst case, if the field doe= s not exist, we'll get an error, anyway.- Jonathan M DavisDenis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Nov 15 2010
spir:(and bug-prone, because sometimes the absence of a fields seems not caught, for any reason), so I add fields to the top type.What do you mean? Do you have an example? (Adding fields to the top type doesn't look like a good idea, generally). Bye, bearophile
Nov 16 2010
On Tue, 16 Nov 2010 05:37:52 -0500 bearophile <bearophileHUGS lycos.com> wrote:spir: =20ght, for any reason), so I add fields to the top type.(and bug-prone, because sometimes the absence of a fields seems not cau==20 What do you mean? Do you have an example? (Adding fields to the top type doesn't look like a good idea, generally). =20 Bye, bearophileFor instance, I have 2 sub-classes of nodes: one leaf kind with element (he= re called slice), one branch kind with an array of (child) nodes. They are = exclusive, and none of the data fields should appear on the top Node type. = But everywhere the Node class must be used, since a branch (as the top tree= ) can indifferently hold leaves or sub-branches, right? Each time I need to post-process results, since I apparently get Nodes (eve= n if I know they are actually of one or the other type), I would first have= to down-cast each node to the proper kind before doing anything. Else, I w= ould get compiler errors, or plain bugs, for not having the proper field. S= o, I ended up setting fake fields on Node (and remove them from the sub-cla= sses). And yes, I agree it's A Bad Thing to do. Just tell me of an elegant = solution, and I apply it at once. Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Nov 16 2010
On 16.11.2010 14:40, spir wrote:On Tue, 16 Nov 2010 05:37:52 -0500 bearophile<bearophileHUGS lycos.com> wrote:Looks like a good question for D.learn. That's what opApply is made for. Namely: internal iteration. Idea - basically what you need is apply some block of code (delegate) on each element. If you provide in your node-like classes function opApply with signature: int opApply(int delegate(ref A)); //where A is your data-type foreach(a; node){ writeln(a);//here a is element of data not Node or some such } Is rewritten as node.opApply((ref a){ writeln(a); return 0;}); compiler rewrites code with breaks and so on to return 1, while at the normal end of flow to return 0 To get that idea better, try this example program import std.stdio; class Node{ abstract int opApply(int delegate(ref int)); } class Leaf: Node{ this(int _data){ data = _data; } int data; int opApply(int delegate(ref int) dg){ return dg(data); } } class Branch: Node{ Node[] nodes; this(Node[] _nodes...){ nodes = _nodes.dup; } int opApply(int delegate (ref int) dg){ Node[] n = nodes; while(n.length){ int result = n[0].opApply(dg); if(result) return result; ///to handle breaks n = n[1..$]; } return 0; } } void main(){ Branch b = new Branch(new Leaf(17), new Leaf(19)); Node n = new Branch(new Leaf(10),new Leaf(20),b); foreach(val;n){ if(val == 17)//try playing around with break break; writeln(val); } } Also check the section 12.10 in TDPL if you have one, it goes in great detail about it.spir:For instance, I have 2 sub-classes of nodes: one leaf kind with element (here called slice), one branch kind with an array of (child) nodes. They are exclusive, and none of the data fields should appear on the top Node type. But everywhere the Node class must be used, since a branch (as the top tree) can indifferently hold leaves or sub-branches, right? Each time I need to post-process results, since I apparently get Nodes (even if I know they are actually of one or the other type), I would first have to down-cast each node to the proper kind before doing anything. Else, I would get compiler errors, or plain bugs, for not having the proper field. So, I ended up setting fake fields on Node (and remove them from the sub-classes). And yes, I agree it's A Bad Thing to do. Just tell me of an elegant solution, and I apply it at once.(and bug-prone, because sometimes the absence of a fields seems not caught, for any reason), so I add fields to the top type.What do you mean? Do you have an example? (Adding fields to the top type doesn't look like a good idea, generally). Bye, bearophileDenis -- -- -- -- -- -- -- vit esse estrany ☣ spir.wikidot.com-- Dmitry Olshansky
Nov 16 2010
On Tue, 16 Nov 2010 05:37:52 -0500 bearophile <bearophileHUGS lycos.com> wrote:spir: =20ght, for any reason), so I add fields to the top type.(and bug-prone, because sometimes the absence of a fields seems not cau==20 What do you mean? Do you have an example? (Adding fields to the top type doesn't look like a good idea, generally). =20 Bye, bearophilePS: And I guess clients of the lib face the same issues. denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Nov 16 2010
On Tuesday, November 16, 2010 03:40:24 spir wrote:On Tue, 16 Nov 2010 05:37:52 -0500 bearophile <bearophileHUGS lycos.com> wrote:Well, I think that I'd have to study your code to get quite what you're doing. However, I would consider _any_ case in code where you specifically cast to a derived class from a base class to be a code smell. My general reaction is that there _has_ to be a better, cleaner way to do it, and that it stinks of bad design. However, I'd have to really understand what you're doing to give a better suggestion, and just because it's _almost_ always a bad idea doesn't mean that it's _always_ a bad idea. - Jonathan M Davisspir:For instance, I have 2 sub-classes of nodes: one leaf kind with element (here called slice), one branch kind with an array of (child) nodes. They are exclusive, and none of the data fields should appear on the top Node type. But everywhere the Node class must be used, since a branch (as the top tree) can indifferently hold leaves or sub-branches, right? Each time I need to post-process results, since I apparently get Nodes (even if I know they are actually of one or the other type), I would first have to down-cast each node to the proper kind before doing anything. Else, I would get compiler errors, or plain bugs, for not having the proper field. So, I ended up setting fake fields on Node (and remove them from the sub-classes). And yes, I agree it's A Bad Thing to do. Just tell me of an elegant solution, and I apply it at once.(and bug-prone, because sometimes the absence of a fields seems not caught, for any reason), so I add fields to the top type.What do you mean? Do you have an example? (Adding fields to the top type doesn't look like a good idea, generally). Bye, bearophile
Nov 16 2010