www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 2946] New: Make 'abstract' mandatory if the class is intended to be abstract

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2946

           Summary: Make 'abstract' mandatory if the class is intended to be
                    abstract
           Product: D
           Version: unspecified
          Platform: PC
               URL: http://www.digitalmars.com/d/archives/digitalmars/D/Make
                    _abstract_mandatory_if_the_class_is_intended_to_be_abstr
                    act_70660.html
        OS/Version: All
            Status: NEW
          Keywords: accepts-invalid
          Severity: normal
          Priority: P3
         Component: DMD
        AssignedTo: bugzilla digitalmars.com
        ReportedBy: gide nwawudu.com


 On Mon, 28 Apr 2008 10:11:23 -0300, Ary Borenszweig
A class can either be abstract or not abstract. Currently in D, if you don't mark a class as abstract, it can still be it if it contains an abstract method: class Foo { abstract void someAbstract(); void nonAbstract() { } } When designing a class, you have in mind whether the class is going to be abstract or not. If it's not going to be abstract, you want the compiler to help you by telling you "You made a mistake. This class is still abstract because you didn't implement method foo". So I want to extend Foo with a class Bar, but I want Bar to be not abstract. class Bar : Foo { } I compile, and it gives no error, of course. But I want there to be an error there. The only way I can get an error is by making a dummy function that instantiates Bar: void blah() { Bar bar = new Bar(); } main.d(14): Error: cannot create instance of abstract class Bar main.d(14): Error: function someAbstract is abstract The problems with this approach are two: - You have to make a dummy function to check whether you implemented Bar correctly. - You get two errors for each instantiation of Bar, if it's abstract (ugly). Why not make "abstract" mandatory for a class if it's intended to be abstract, and the absence of "abstract" to mean "not abstract"? Java works this way, and I think it is for the reasons I mentioned. Another advantage is that just by seeing the start of class definition you can tell whether a class is abstract or not. You don't have to see if any method is marked as abstract, or go to the superclasses to see if there is a method that is still not implemented. (also, it would be nice if the compiler could tell you all the methods that still need an implementation, rather than just one) --
May 06 2009
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2946





------- Comment #1 from gide nwawudu.com  2009-05-06 10:17 -------
Another example.

main.d
------
class Foo1 {
    abstract void foo();
}

class Bar1 : Foo1 {
}

abstract class Foo2 {
    abstract void foo();
}

class Bar2 : Foo2 {
}

void main () { 
    debug {
        auto f1 = new Bar1;
        auto f2 = new Bar2;
    }
}

C:> dmd -w -debug main.d
main.d(17): Error: cannot create instance of abstract class Bar1
main.d(17): Error: function foo is abstract
main.d(18): Error: cannot create instance of abstract class Bar2
main.d(18): Error: function foo is abstract

Should not compile or at least give a warning, but does neither.
C:> dmd -w main.d


-- 
May 06 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2946


smjg iname.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |smjg iname.com
           Severity|normal                      |enhancement
           Keywords|accepts-invalid             |diagnostic, spec




------- Comment #2 from smjg iname.com  2009-05-06 16:42 -------
http://www.digitalmars.com/d/2.0/attribute.html#abstract (and similarly 1.0)
"Classes become abstract if they are defined within an abstract attribute, or
if any of the virtual member functions within it are declared as abstract."

The compiler is behaving correctly, therefore this is an enhancement request.


-- 
May 06 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2946


Gide Nwawudu <gide nwawudu.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bearophile_hugs eml.cc


--- Comment #3 from Gide Nwawudu <gide nwawudu.com> 2010-07-27 07:17:03 PDT ---
*** Issue 4512 has been marked as a duplicate of this issue. ***

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 27 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2946



--- Comment #4 from bearophile_hugs eml.cc 2010-10-29 05:01:02 PDT ---
(In reply to comment #2)
 The compiler is behaving correctly, therefore this is an enhancement request.
We need a different term to tell apart true enhancement requests (where someone asks for a new feature or new subfeature) from bugs in the specs. This is a case where the specs are suboptimal, so this is not a true enhancement request, it's a way to fix a little mistake in the D specs. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 29 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2946



--- Comment #5 from Stewart Gordon <smjg iname.com> 2010-10-30 05:57:20 PDT ---
(In reply to comment #4)
 This is a case where the specs are suboptimal, so this is not a true
 enhancement request, it's a way to fix a little mistake in the D specs.
Have you evidence that this is a mistake, i.e. not what Walter intended to write? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 30 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2946



--- Comment #6 from bearophile_hugs eml.cc 2010-10-30 14:56:35 PDT ---
(In reply to comment #5)
 Have you evidence that this is a mistake, i.e. not what Walter intended to
 write?
I have no evidence, but regardless the origin of this current situation, the Java design is the correct one (unless someone shows me otherwise) and I think here it's better to modify D specs & implementation. And I think it's better to do this change as soon as possible, before lot of D2 code is written, to reduce troubles of fixing code later. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 30 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2946



--- Comment #7 from Stewart Gordon <smjg iname.com> 2010-10-30 17:22:30 PDT ---
Certainly the Java design is more sensible on this.  But "correct" in terms of
design is to some degree a matter of opinion.  There are a number of aspects of
D's design that I would consider mistakes - inheritance protection, archaic
switch syntax, implicit narrowing conversions just to name a few.  There are
probably lots filed here.  How would we label such issues on this basis,
anyway?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 30 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2946


Andrej Mitrovic <andrej.mitrovich gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |andrej.mitrovich gmail.com
           Platform|x86                         |All
         Resolution|                            |WONTFIX


--- Comment #8 from Andrej Mitrovic <andrej.mitrovich gmail.com> 2013-01-20
12:26:13 PST ---
I don't think this will fly. Abstract on the class name itself makes it
non-instantiable, however subclasses are not abstract and can be instantiated:

// can't be instantiated
abstract class Foo { void foo() { } }  

// is not abstract and can be instantiated
class Bar : Foo { }

Whether or not there's an abstract keyword next to the class name doesn't tell
you whether the class actually has abstract methods, so there's no benefit
forcing you to add 'abstract' to the name.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 20 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2946


Stewart Gordon <smjg iname.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
         Resolution|WONTFIX                     |


--- Comment #9 from Stewart Gordon <smjg iname.com> 2013-01-21 05:27:53 PST ---
(In reply to comment #8)
 I don't think this will fly.
It's up to Walter whether this will be implemented.
 Abstract on the class name itself makes it non-instantiable, 
 however subclasses are not abstract and can be instantiated:
It isn't clear to me what relevance this has. The point of this request is to require abstract classes to be declared as abstract. You're talking about classes that already are declared as abstract.
 Whether or not there's an abstract keyword next to the class name 
 doesn't tell you whether the class actually has abstract methods, 
 so there's no benefit forcing you to add 'abstract' to the name.
It isn't supposed to tell you whether it has abstract methods. It's supposed to tell you whether the class is abstract, i.e. barred from direct instantiation. With the abstract attribute being optional on the class declaration itself, one has to look through all the methods to determine whether the class is abstract or not. With it being mandatory, the information is right in front of you when you look at the class. It would also be useful for documentation generators. Whether a class has any abstract methods depends not only on methods declared directly within the body of the class, but also on those in superclasses of the class, interfaces the class implements, and method declarations generated by mixins. The last of these effectively means that no standalone documentation generator (unless it contains a full D conditional compilation and CTFE engine) can correctly indicate which classes are abstract and which aren't. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 21 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2946


Jacob Carlborg <doob me.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |doob me.com


--- Comment #10 from Jacob Carlborg <doob me.com> 2013-01-21 11:12:53 PST ---
(In reply to comment #0)
 On Mon, 28 Apr 2008 10:11:23 -0300, Ary Borenszweig
A class can either be abstract or not abstract. Currently in D, if you don't mark a class as abstract, it can still be it if it contains an abstract method: class Foo { abstract void someAbstract(); void nonAbstract() { } } When designing a class, you have in mind whether the class is going to be abstract or not. If it's not going to be abstract, you want the compiler to help you by telling you "You made a mistake. This class is still abstract because you didn't implement method foo". So I want to extend Foo with a class Bar, but I want Bar to be not abstract. class Bar : Foo { } I compile, and it gives no error, of course. But I want there to be an error there.
There might be a problem with this since D supports separate compilation. There can be another object file that contains the implementation of Bar.someAbstract. I'm not sure if this applies here. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 21 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2946



--- Comment #11 from Stewart Gordon <smjg iname.com> 2013-01-21 12:40:39 PST ---
(In reply to comment #10)
 There might be a problem with this since D supports separate 
 compilation. There can be another object file that contains the 
 implementation of Bar.someAbstract. I'm not sure if this applies 
 here.
No, for this to apply, Bar would need to contain its own declaration of someAbstract. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 21 2013
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2946



--- Comment #12 from Andrej Mitrovic <andrej.mitrovich gmail.com> 2013-01-21
12:55:16 PST ---
(In reply to comment #0)
 (also, it would be nice if the compiler could tell you all the methods 
 that still need an implementation, rather than just one)
This seems to be fixed now. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 21 2013