www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Should certain abstract classes be instantiable?

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Consider:

class A {
     abstract void fun() {}
}

The class defines a function that is at the same time abstract (so it 
requires overriding in derivees) and has implementation.

Currently the compiler disallows creation of objects of type A, although 
technically that is feasible given that A defines the abstract method.

Should A be instantiable? What designs would that help or hinder?


Andrei
Oct 01 2009
next sibling parent reply Jeremie Pelletier <jeremiep gmail.com> writes:
Andrei Alexandrescu wrote:
 Consider:
 
 class A {
     abstract void fun() {}
 }
 
 The class defines a function that is at the same time abstract (so it 
 requires overriding in derivees) and has implementation.
 
 Currently the compiler disallows creation of objects of type A, although 
 technically that is feasible given that A defines the abstract method.
 
 Should A be instantiable? What designs would that help or hinder?
 
 
 Andrei
What's the point of marking fun() abstract if it has an implementation, I thought the compiler disallowed that.
Oct 01 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Jeremie Pelletier wrote:
 Andrei Alexandrescu wrote:
 Consider:

 class A {
     abstract void fun() {}
 }

 The class defines a function that is at the same time abstract (so it 
 requires overriding in derivees) and has implementation.

 Currently the compiler disallows creation of objects of type A, 
 although technically that is feasible given that A defines the 
 abstract method.

 Should A be instantiable? What designs would that help or hinder?


 Andrei
What's the point of marking fun() abstract if it has an implementation, I thought the compiler disallowed that.
It may offer incomplete functionality that is to be reused and enhanced by descendants. Andrei
Oct 01 2009
next sibling parent reply dsimcha <dsimcha yahoo.com> writes:
== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s article
 Jeremie Pelletier wrote:
 Andrei Alexandrescu wrote:
 Consider:

 class A {
     abstract void fun() {}
 }

 The class defines a function that is at the same time abstract (so it
 requires overriding in derivees) and has implementation.

 Currently the compiler disallows creation of objects of type A,
 although technically that is feasible given that A defines the
 abstract method.

 Should A be instantiable? What designs would that help or hinder?


 Andrei
What's the point of marking fun() abstract if it has an implementation, I thought the compiler disallowed that.
It may offer incomplete functionality that is to be reused and enhanced by descendants. Andrei
If you are in that situation, then don't declare the class abstract. I thought the whole point of abstract classes was that they can't be instantiated. If it can be instantiated, then what does abstract even mean?
Oct 01 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
dsimcha wrote:
 == Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s article
 Jeremie Pelletier wrote:
 Andrei Alexandrescu wrote:
 Consider:

 class A {
     abstract void fun() {}
 }

 The class defines a function that is at the same time abstract (so it
 requires overriding in derivees) and has implementation.

 Currently the compiler disallows creation of objects of type A,
 although technically that is feasible given that A defines the
 abstract method.

 Should A be instantiable? What designs would that help or hinder?


 Andrei
What's the point of marking fun() abstract if it has an implementation, I thought the compiler disallowed that.
It may offer incomplete functionality that is to be reused and enhanced by descendants. Andrei
If you are in that situation, then don't declare the class abstract. I thought the whole point of abstract classes was that they can't be instantiated. If it can be instantiated, then what does abstract even mean?
They can't be instantiated. Andrei
Oct 01 2009
parent Lutger <lutger.blijdestijn gmail.com> writes:
Andrei Alexandrescu wrote:

 dsimcha wrote:
 == Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s
 article
 Jeremie Pelletier wrote:
 Andrei Alexandrescu wrote:
 Consider:

 class A {
     abstract void fun() {}
 }

 The class defines a function that is at the same time abstract (so it
 requires overriding in derivees) and has implementation.

 Currently the compiler disallows creation of objects of type A,
 although technically that is feasible given that A defines the
 abstract method.

 Should A be instantiable? What designs would that help or hinder?


 Andrei
What's the point of marking fun() abstract if it has an implementation, I thought the compiler disallowed that.
It may offer incomplete functionality that is to be reused and enhanced by descendants. Andrei
If you are in that situation, then don't declare the class abstract. I thought the whole point of abstract classes was that they can't be instantiated. If it can be instantiated, then what does abstract even mean?
They can't be instantiated. Andrei
Exactly, to return to your original question: if you allow abstract classes to be instantiable it hinders a design where a class is mandated to be a base class only with default implementations of all methods.
Oct 01 2009
prev sibling parent reply Lutger <lutger.blijdestijn gmail.com> writes:
Andrei Alexandrescu wrote:

 Jeremie Pelletier wrote:
 Andrei Alexandrescu wrote:
 Consider:

 class A {
     abstract void fun() {}
 }

 The class defines a function that is at the same time abstract (so it
 requires overriding in derivees) and has implementation.

 Currently the compiler disallows creation of objects of type A,
 although technically that is feasible given that A defines the
 abstract method.

 Should A be instantiable? What designs would that help or hinder?


 Andrei
What's the point of marking fun() abstract if it has an implementation, I thought the compiler disallowed that.
It may offer incomplete functionality that is to be reused and enhanced by descendants. Andrei
Then again, if it offers incomplete functionality why would you want it to be instantiable? Instantiable should mean you can use this guy no? I tried hard to think of a reason but can't find any.
Oct 01 2009
parent Jeremie Pelletier <jeremiep gmail.com> writes:
Lutger wrote:
 Andrei Alexandrescu wrote:
 
 Jeremie Pelletier wrote:
 Andrei Alexandrescu wrote:
 Consider:

 class A {
     abstract void fun() {}
 }

 The class defines a function that is at the same time abstract (so it
 requires overriding in derivees) and has implementation.

 Currently the compiler disallows creation of objects of type A,
 although technically that is feasible given that A defines the
 abstract method.

 Should A be instantiable? What designs would that help or hinder?


 Andrei
What's the point of marking fun() abstract if it has an implementation, I thought the compiler disallowed that.
It may offer incomplete functionality that is to be reused and enhanced by descendants. Andrei
Then again, if it offers incomplete functionality why would you want it to be instantiable? Instantiable should mean you can use this guy no? I tried hard to think of a reason but can't find any.
Exactly, I only mark members as abstract if they have no implementations, if any members have an incomplete implementation then i mark the class as abstract. I never had any problems that way. Besides it just makes no sense to have an implemented member as abstract.
Oct 01 2009
prev sibling next sibling parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Thu, Oct 1, 2009 at 4:30 PM, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> wrote:
 Consider:

 class A {
 =A0 =A0abstract void fun() {}
 }

 The class defines a function that is at the same time abstract (so it
 requires overriding in derivees) and has implementation.

 Currently the compiler disallows creation of objects of type A, although
 technically that is feasible given that A defines the abstract method.

 Should A be instantiable? What designs would that help or hinder?
Uh... why?
Oct 01 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Jarrett Billingsley wrote:
 On Thu, Oct 1, 2009 at 4:30 PM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 Consider:

 class A {
    abstract void fun() {}
 }

 The class defines a function that is at the same time abstract (so it
 requires overriding in derivees) and has implementation.

 Currently the compiler disallows creation of objects of type A, although
 technically that is feasible given that A defines the abstract method.

 Should A be instantiable? What designs would that help or hinder?
Uh... why?
Because I want to give a good argument one way or another in TDPL. FWIW, "I can't imagine why you'd ever..." or "Never needed that" are not strong enough arguments. Andrei
Oct 01 2009
parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Thu, Oct 1, 2009 at 8:49 PM, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> wrote:
 Jarrett Billingsley wrote:
 On Thu, Oct 1, 2009 at 4:30 PM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 Consider:

 class A {
 =A0 abstract void fun() {}
 }

 The class defines a function that is at the same time abstract (so it
 requires overriding in derivees) and has implementation.

 Currently the compiler disallows creation of objects of type A, althoug=
h
 technically that is feasible given that A defines the abstract method.

 Should A be instantiable? What designs would that help or hinder?
Uh... why?
Because I want to give a good argument one way or another in TDPL. FWIW, =
"I
 can't imagine why you'd ever..." or "Never needed that" are not strong
 enough arguments.
But.. you mark something abstract when you want it to be .. abstract. How would you argue that abstract is basically a no-op when used on methods with bodies? And there's a reasonable use for it, so why suddenly allow something that.. doesn't really make all that much sense to begin with?
Oct 01 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Jarrett Billingsley wrote:
 On Thu, Oct 1, 2009 at 8:49 PM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 Jarrett Billingsley wrote:
 On Thu, Oct 1, 2009 at 4:30 PM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 Consider:

 class A {
   abstract void fun() {}
 }

 The class defines a function that is at the same time abstract (so it
 requires overriding in derivees) and has implementation.

 Currently the compiler disallows creation of objects of type A, although
 technically that is feasible given that A defines the abstract method.

 Should A be instantiable? What designs would that help or hinder?
Uh... why?
Because I want to give a good argument one way or another in TDPL. FWIW, "I can't imagine why you'd ever..." or "Never needed that" are not strong enough arguments.
But.. you mark something abstract when you want it to be .. abstract. How would you argue that abstract is basically a no-op when used on methods with bodies?
It's not a no-op. Try it. Andrei
Oct 01 2009
parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Thu, Oct 1, 2009 at 11:48 PM, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> wrote:
 But.. you mark something abstract when you want it to be .. abstract.
 How would you argue that abstract is basically a no-op when used on
 methods with bodies?
It's not a no-op. Try it.
Yeah, not *currently*, but isn't that what you're proposing?
Oct 02 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Jarrett Billingsley wrote:
 On Thu, Oct 1, 2009 at 11:48 PM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 But.. you mark something abstract when you want it to be .. abstract.
 How would you argue that abstract is basically a no-op when used on
 methods with bodies?
It's not a no-op. Try it.
Yeah, not *currently*, but isn't that what you're proposing?
No. I think it would help going back to my original message instead of asking one-liner questions. This would work much better in real life, but it's a time sink in a newsgroup. You spend five seconds on asking a question with a foregone answer just because you don't want to invest fifteen seconds in re-reading my initial post, and then you have me spend five minutes explain things again. It's counter-productive. If a class defines an abstract method and also provides a body for it, it still requires the derived class to override the method. So abstract still has some meaning. On the other hand, technically such a class would become instantiable because it defines all of its methods. I wanted to explain that, however, that wouldn't be a good idea because... and here's where 1-2 good examples would have helped. I guess I'm going to drop it. Andrei
Oct 02 2009
next sibling parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Fri, Oct 2, 2009 at 11:00 AM, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> wrote:
 No. I think it would help going back to my original message instead of
 asking one-liner questions. This would work much better in real life, but
 it's a time sink in a newsgroup. You spend five seconds on asking a question
 with a foregone answer just because you don't want to invest fifteen seconds
 in re-reading my initial post, and then you have me spend five minutes
 explain things again. It's counter-productive.

 If a class defines an abstract method and also provides a body for it, it
 still requires the derived class to override the method. So abstract still
 has some meaning.
Yes, I see now the parenthesized "requires overriding in derivees" now.
 On the other hand, technically such a class would become instantiable
 because it defines all of its methods. I wanted to explain that, however,
 that wouldn't be a good idea because... and here's where 1-2 good examples
 would have helped. I guess I'm going to drop it.
Speaking of counterproductive timesinks, why would you bring up a proposal only to argue that it's a bad idea?
Oct 02 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Jarrett Billingsley wrote:
 On Fri, Oct 2, 2009 at 11:00 AM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 No. I think it would help going back to my original message instead of
 asking one-liner questions. This would work much better in real life, but
 it's a time sink in a newsgroup. You spend five seconds on asking a question
 with a foregone answer just because you don't want to invest fifteen seconds
 in re-reading my initial post, and then you have me spend five minutes
 explain things again. It's counter-productive.

 If a class defines an abstract method and also provides a body for it, it
 still requires the derived class to override the method. So abstract still
 has some meaning.
Yes, I see now the parenthesized "requires overriding in derivees" now.
 On the other hand, technically such a class would become instantiable
 because it defines all of its methods. I wanted to explain that, however,
 that wouldn't be a good idea because... and here's where 1-2 good examples
 would have helped. I guess I'm going to drop it.
Speaking of counterproductive timesinks, why would you bring up a proposal only to argue that it's a bad idea?
It was a question, you one-liner-asker you. Andrei
Oct 02 2009
parent Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Fri, Oct 2, 2009 at 1:34 PM, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> wrote:
 It was a question, you one-liner-asker you.
What? ;)
Oct 02 2009
prev sibling parent reply Ary Borenszweig <ary esperanto.org.ar> writes:
Andrei Alexandrescu wrote:
 Jarrett Billingsley wrote:
 On Thu, Oct 1, 2009 at 11:48 PM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 But.. you mark something abstract when you want it to be .. abstract.
 How would you argue that abstract is basically a no-op when used on
 methods with bodies?
It's not a no-op. Try it.
Yeah, not *currently*, but isn't that what you're proposing?
No. I think it would help going back to my original message instead of asking one-liner questions. This would work much better in real life, but it's a time sink in a newsgroup. You spend five seconds on asking a question with a foregone answer just because you don't want to invest fifteen seconds in re-reading my initial post, and then you have me spend five minutes explain things again. It's counter-productive. If a class defines an abstract method and also provides a body for it, it still requires the derived class to override the method. So abstract still has some meaning.
Umm... so it defines a body that will never be used because that class can't be instantiated and the method must be redefined by subclasses? Isn't that the same as "doesn't provide a body"?
Oct 03 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Ary Borenszweig wrote:
 Andrei Alexandrescu wrote:
 Jarrett Billingsley wrote:
 On Thu, Oct 1, 2009 at 11:48 PM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 But.. you mark something abstract when you want it to be .. abstract.
 How would you argue that abstract is basically a no-op when used on
 methods with bodies?
It's not a no-op. Try it.
Yeah, not *currently*, but isn't that what you're proposing?
No. I think it would help going back to my original message instead of asking one-liner questions. This would work much better in real life, but it's a time sink in a newsgroup. You spend five seconds on asking a question with a foregone answer just because you don't want to invest fifteen seconds in re-reading my initial post, and then you have me spend five minutes explain things again. It's counter-productive. If a class defines an abstract method and also provides a body for it, it still requires the derived class to override the method. So abstract still has some meaning.
Umm... so it defines a body that will never be used because that class can't be instantiated and the method must be redefined by subclasses? Isn't that the same as "doesn't provide a body"?
import std.stdio; class A { abstract void fun() { writeln("wyda"); } } class B : A { void fun() { A.fun(); } } unittest { A a = new B; a.fun(); a.A.fun(); } Andrei
Oct 03 2009
parent reply "Nick Sabalausky" <a a.a> writes:
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message 
news:ha8beq$2tn9$1 digitalmars.com...
 Ary Borenszweig wrote:
 Umm... so it defines a body that will never be used because that class 
 can't be instantiated and the method must be redefined by subclasses? 
 Isn't that the same as "doesn't provide a body"?
import std.stdio; class A { abstract void fun() { writeln("wyda"); } } class B : A { void fun() { A.fun(); } } unittest { A a = new B; a.fun(); a.A.fun(); }
Not a rhetorical or a loaded question: Has that sort of thing ever been useful?
Oct 04 2009
parent Ary Borenszweig <ary esperanto.org.ar> writes:
Nick Sabalausky wrote:
 "Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message 
 news:ha8beq$2tn9$1 digitalmars.com...
 Ary Borenszweig wrote:
 Umm... so it defines a body that will never be used because that class 
 can't be instantiated and the method must be redefined by subclasses? 
 Isn't that the same as "doesn't provide a body"?
import std.stdio; class A { abstract void fun() { writeln("wyda"); } } class B : A { void fun() { A.fun(); } } unittest { A a = new B; a.fun(); a.A.fun(); }
Not a rhetorical or a loaded question: Has that sort of thing ever been useful?
I was wondering the same. It's also very bug prone because when overriding the function you must remember to invoke the super method, a thing you can forget.
Oct 05 2009
prev sibling next sibling parent reply Lionello Lunesu <lio lunesu.remove.com> writes:
On 2-10-2009 4:30, Andrei Alexandrescu wrote:
 Consider:

 class A {
 abstract void fun() {}
 }

 The class defines a function that is at the same time abstract (so it
 requires overriding in derivees) and has implementation.

 Currently the compiler disallows creation of objects of type A, although
 technically that is feasible given that A defines the abstract method.

 Should A be instantiable? What designs would that help or hinder?


 Andrei
If it were instantiable, what would be the difference between "abstract" and "virtual"? L.
Oct 01 2009
parent Lionello Lunesu <lio lunesu.remove.com> writes:
On 2-10-2009 8:32, Lionello Lunesu wrote:
 On 2-10-2009 4:30, Andrei Alexandrescu wrote:
 Consider:

 class A {
 abstract void fun() {}
 }

 The class defines a function that is at the same time abstract (so it
 requires overriding in derivees) and has implementation.

 Currently the compiler disallows creation of objects of type A, although
 technically that is feasible given that A defines the abstract method.

 Should A be instantiable? What designs would that help or hinder?


 Andrei
If it were instantiable, what would be the difference between "abstract" and "virtual"?
OK, so I reread your post and yes, "it requires overriding in derivees." Derived classes would still be allowed to do super.fun(), calling the 'abstract' class's implementation. It's like NVI, only worse? L.
Oct 02 2009
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 01 Oct 2009 16:30:43 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 Consider:

 class A {
      abstract void fun() {}
 }

 The class defines a function that is at the same time abstract (so it  
 requires overriding in derivees) and has implementation.

 Currently the compiler disallows creation of objects of type A, although  
 technically that is feasible given that A defines the abstract method.

 Should A be instantiable? What designs would that help or hinder?
If you want to force a class to be abstract, even though it technically could be concrete given it has implementations for all functions, you could allow that by marking the class abstract. i.e.: abstract class A { void fun() {} } The other side, allowing A to be instantiated, makes no sense whatsoever. If you (as a class designer) want something to be instantiated, and it has all methods implemented, why mark it abstract? IMO, it should be a compiler error to give implementation to an abstract method. -Steve
Oct 02 2009
prev sibling parent reply Justin Johansson <no spam.com> writes:
Andrei Alexandrescu Wrote:

 Jarrett Billingsley wrote:
 On Thu, Oct 1, 2009 at 4:30 PM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 Consider:

 class A {
    abstract void fun() {}
 }

 The class defines a function that is at the same time abstract (so it
 requires overriding in derivees) and has implementation.

 Currently the compiler disallows creation of objects of type A, although
 technically that is feasible given that A defines the abstract method.

 Should A be instantiable? What designs would that help or hinder?
Uh... why?
 Because I want to give a good argument one way or another in TDPL. FWIW, 
 "I can't imagine why you'd ever..." or "Never needed that" are not 
 strong enough arguments.
 Andrei
I had a brilliant maths teacher at high school. Every now and then someone would ask a question which everyone else though was silly. Often he would jokingly reply, "Good question. Next question." and then, after a pause, explore the subtleties of the "silly" question to everyone's total amazement. There was one really, really smart guy who asked enough "silly" questions and ended up getting his Ph.D. in Mathematics before the age of 20.
 "Because I want to give a good argument one way or another in TDPL."
Fair enough, Andrei. I'm trying hard with the following use case to demonstrate that instantiation of the abstract is possibly useful. Hope this helps or leads to further insight. class NonNegativeInteger { static NonNegativeInteger infinity; static this() { infinity = new NonNegativeInteger(); } /+abstract+/ long value() { // In Andrei's scenario, this method is marked abstract // so we don't really care what we return here; // For moment comment out abstract keyword so that the // initialization of the singleton instance of // NonNegativeInteger, infinity, gets past the current // compiler. // Other than the private singleton instantiation inside // the static this block, no external code is allowed to // call new NonNegativeInteger() because the class // is, for all intensive purposes, abstract (once the // abstract keyword is uncommented). assert(false); return infinity.value; } void print() { writefln( "Infinity"); } } class FiniteNonNegativeInteger: NonNegativeInteger { private long val; this( long value) { val = value; } long value() { return val; } NonNegativeInteger opDiv( NonNegativeInteger divisor) { return (divisor.value != 0) ? new FiniteNonNegativeInteger( value / divisor.value) : NonNegativeInteger.infinity; } void print() { writefln( "%d", val); } } void main() { auto hundred = new FiniteNonNegativeInteger( 100); auto two = new FiniteNonNegativeInteger( 2); auto zero = new FiniteNonNegativeInteger( 0); auto fifty = hundred / two; auto infinity = hundred / zero; hundred.print(); two.print(); fifty.print(); infinity.print(); } Outputs: 100 2 50 Infinity Cheers Justin Johansson.
Oct 02 2009
parent Justin Johansson <no spam.com> writes:
Justin Johansson Wrote:

 Andrei Alexandrescu Wrote:
 
 Jarrett Billingsley wrote:
 On Thu, Oct 1, 2009 at 4:30 PM, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 Consider:

 class A {
    abstract void fun() {}
 }

 The class defines a function that is at the same time abstract (so it
 requires overriding in derivees) and has implementation.

 Currently the compiler disallows creation of objects of type A, although
 technically that is feasible given that A defines the abstract method.

 Should A be instantiable? What designs would that help or hinder?
Uh... why?
 Because I want to give a good argument one way or another in TDPL. FWIW, 
 "I can't imagine why you'd ever..." or "Never needed that" are not 
 strong enough arguments.
 Andrei
Fair enough, Andrei. I'm trying hard with the following use case to demonstrate that instantiation of the abstract is possibly useful. Hope this helps or leads to further insight.
Just in case I'm misunderstood .. I don't believe the concept is particularly useful; just that Andrei was looking for some example, presumably to expand upon in TDPL, and my sample was just an exploratory idea. Obviously the sample that I dreamed up results in an infinite loop if the "abstract" base class value() method is actually called. -- Justin
Oct 03 2009