View mode: basic / threaded / horizontal-split · Log in · Help
December 02, 2011
Re: Abstract functions in child classes
Even if the current behavior (what Adam mentioned) is not a bug, I think
it seems to be a pitfall for std::programmer. The language/compiler
should be more restrictive in this case.
December 02, 2011
Re: Abstract functions in child classes
mta`chrono Wrote:

> Even if the current behavior (what Adam mentioned) is not a bug, I think
> it seems to be a pitfall for std::programmer. The language/compiler
> should be more restrictive in this case.

If you think so, then write it in Bugzilla :-)

Bye,
bearophile
December 02, 2011
Re: Abstract functions in child classes
On Fri, 02 Dec 2011 03:06:37 -0500, mta`chrono  
<chrono@mta-international.net> wrote:

> Even if the current behavior (what Adam mentioned) is not a bug, I think
> it seems to be a pitfall for std::programmer. The language/compiler
> should be more restrictive in this case.

No, this is not a matter of allowing an invalid situation, the OP's code  
is perfectly viable and legal.  Here is a simpler example:

abstract class Parent
{
   abstract void foo();
}

class Child : Parent
{
   override void foo() {}
}

void main()
{
   Parent parent;

   parent = new Child();
}

why should it be disallowed to declare a variable of abstract type?  You  
aren't instantiating it.  It's the act of instantiation which is not and  
should not be allowed.

-Steve
December 02, 2011
Re: Abstract functions in child classes
To sort of put my two cents back in, and also to be one of those "D
should be like Java!" advocates, the problem is largely that a class
that inherits from an abstract and does *not* override some abstract
member becomes implicitly (to the user) abstract.

The way abstracts work in Java is that, in order to maintain that
"child" is an abstract (so that the actual implementation is
GrandChild), you must declare that both Child is an abstract class
and redeclare the function in question.

Now, perhaps there are good reasons in D for not requiring Child to
be declared abstract, but I'm not sure what they are. If a class
having any members that are abstract is implicitly abstract, then
the programmer should probably have to declare that the class is
abstract, as well.

The problem I ran into is that, until instantiation, the only way I
knew that Child was abstract would have been to go look at Parent
and see that I had forgotten to override a method.

Overall, the behavior seems "unexpected" (even if it's a personal
problem).
December 02, 2011
Re: Abstract functions in child classes
On Fri, 02 Dec 2011 09:54:10 -0500, Adam <Adam@anizi.com> wrote:

> To sort of put my two cents back in, and also to be one of those "D
> should be like Java!" advocates, the problem is largely that a class
> that inherits from an abstract and does *not* override some abstract
> member becomes implicitly (to the user) abstract.

Yes that is the state of affairs.

>
> The way abstracts work in Java is that, in order to maintain that
> "child" is an abstract (so that the actual implementation is
> GrandChild), you must declare that both Child is an abstract class
> and redeclare the function in question.

This appears superfluous to me.  A class is abstract either because you  
say it is, or because you haven't fully implemented all methods.

Your same line of thinking is used to promote mandatory overrides, which  
alerts you when something that was an override stops overriding or vice  
versa.  However, we aren't in the same place with abstract, since you  
*can* declare a class abstract even though all its methods are concrete.

> Now, perhaps there are good reasons in D for not requiring Child to
> be declared abstract, but I'm not sure what they are. If a class
> having any members that are abstract is implicitly abstract, then
> the programmer should probably have to declare that the class is
> abstract, as well.
>
> The problem I ran into is that, until instantiation, the only way I
> knew that Child was abstract would have been to go look at Parent
> and see that I had forgotten to override a method.

Exactly.  When you actually try to instantiate Child you find that it's  
abstract.  It's not a silent error (and is caught at compile time).

Now, I can see if you weren't expecting this, and you didn't test it, you  
may end up releasing code that is not what you wanted.  But what are the  
chances someone doesn't test their code before release?

In other words, we only gain from the compiler refusing to compile an  
abstract class not marked as 'abstract' if you don't instantiate it.  How  
often would this happen?

> Overall, the behavior seems "unexpected" (even if it's a personal
> problem).

It's unexpected, but caught at compile-time during development.  The error  
message is clear.  I see no reason to change things.

-Steve
December 02, 2011
Re: Abstract functions in child classes
I'm not sure how the fact that a class can be abstract with defined
functions impacts the case either way.

It's caught at compile time, but it requires explicitly testing that
any given time is or is not instantiable - how else would you test
for this particular case? It seems to be adding an additional test
case wherein for every abstract or implementation of abstract (or
supposed implementation of abstract, as is my case), you must test
for instantiability.

If you admit that the error is unexpected, but caught at compile-
time and only if you actually test for the specific case of if a
given implementation *is* instantiable, then you've clearly
demonstrated that the lack of a mandatory re-declaration of an
abstract results in an additional test case.

This *appears* to be at odds with a few of the other things I've
seen in D, which goes out of its way to ensure you do *not*
accidentally do things. In particular, I'm thinking of concurrency,
which does not even *allow* function-level synchronized declaration
(though it does allow synchronized blocks within functions) - it's
either at the class, or not at all.

To step back a bit, what is the *benefit* of not requiring a class
to be declared abstract if it does not override an abstract member?
It introduces implicit behavior and the potential for an additional
test case (in *what* sane world should I even HAVE to test that
something is instantiable?) for the sake of not typing 8 characters
in a Class definition
December 02, 2011
Re: Abstract functions in child classes
On Friday, December 02, 2011 14:54:10 Adam wrote:
> To sort of put my two cents back in, and also to be one of those "D
> should be like Java!" advocates, the problem is largely that a class
> that inherits from an abstract and does *not* override some abstract
> member becomes implicitly (to the user) abstract.
> 
> The way abstracts work in Java is that, in order to maintain that
> "child" is an abstract (so that the actual implementation is
> GrandChild), you must declare that both Child is an abstract class
> and redeclare the function in question.
> 
> Now, perhaps there are good reasons in D for not requiring Child to
> be declared abstract, but I'm not sure what they are. If a class
> having any members that are abstract is implicitly abstract, then
> the programmer should probably have to declare that the class is
> abstract, as well.
> 
> The problem I ran into is that, until instantiation, the only way I
> knew that Child was abstract would have been to go look at Parent
> and see that I had forgotten to override a method.
> 
> Overall, the behavior seems "unexpected" (even if it's a personal
> problem).

The class is abstract whether you mark it that way or not, because it has 
abstract methods. All marking the class as absract is going to do is give the 
programmer a visual clue that it's abstract. So, arguably, it really doesn't 
matter. Now, I personally think that it should be required if the class is 
abstract, since it's more consistent that way, but it's not going to have any 
effect on error messags are anything like that. From the compiler's 
perspective, there just isn't any need.

- Jonathan M Davis
December 02, 2011
Re: Abstract functions in child classes
Ok, let me give a more *specific* case of why this is a problem.

Suppose we have our Parent and Child cases from before

Parent exists in Library A
Child exists in my library, B
Library C, used by some developer, uses my library, B.

My Child is not meant to be abstract - it's intended to me
instantiable, and I document it as such. My documentation might even
include examples of construction.

I override all abstract methods of Parent.

Users of my library use instances of Child regularly.

Now, one day, the maintainer of Parent adds a new abstract function
to Parent. Please don't contest that this could happen - I see it
regularly in every language and every model of maintenance in real-
world development. Sometimes those interface developers are just
sadists.

Now, my library still compiles.

But, suddenly, users of my library are seeing errors on trying to
instantiate.

So what do I have to do to prevent this? I have to *explicitly*
check that Child is or is not instantiable, probably via unittest.
The alternative is that I must check over and read for every change
to the Parent library, even though the only reason I need to be
looking for new abstract functions is the exact same reason I'd need
to explicitly check that something is instantiable.
December 02, 2011
Re: Abstract functions in child classes
How can you put out a library where you don't even test your classes?
That's just bad programming, period.
December 02, 2011
Re: Abstract functions in child classes
On Fri, 02 Dec 2011 17:10:33 -0000, Adam <Adam@anizi.com> wrote:
> So what do I have to do to prevent this? I have to *explicitly*
> check that Child is or is not instantiable, probably via unittest.

YES!  If you're releasing a library and not doing this... bad, bad, bad  
you :)

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
1 2 3 4 5
Top | Discussion index | About this forum | D home