December 02, 2011
Ok, fine, let me put it THIS way.

Suppose I use a parent library, and *I* don't update it.

The USER of my library provides an updated version for some unrelated reason.

So, NOT testing that something is instantiable or not - JUST that it's instantiable - is bad programming...

...but requiring 8 characters to a class definition *is ok*?

So the only way to deal with this is *discipline*?

What you're telling me is that instead of requiring a class to be explicitly abstract or not, it's instead a requirement of *good programming* to test that something IS, in fact, ABSTRACT OR NOT?

What?
December 02, 2011
On Fri, 02 Dec 2011 17:24:11 -0000, Adam <Adam@anizi.com> wrote:

> Ok, fine, let me put it THIS way.
>
> Suppose I use a parent library, and *I* don't update it.
>
> The USER of my library provides an updated version for some
> unrelated reason.
>
> So, NOT testing that something is instantiable or not - JUST that
> it's instantiable - is bad programming...
>
> ...but requiring 8 characters to a class definition *is ok*?
>
> So the only way to deal with this is *discipline*?
>
> What you're telling me is that instead of requiring a class to be
> explicitly abstract or not, it's instead a requirement of *good
> programming* to test that something IS, in fact, ABSTRACT OR NOT?
>
> What?

No-one is saying this, this is a "strawman".  What has been said, is that if you were to distribute a library you should test it before releasing it.

R

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
December 02, 2011
On Fri, 02 Dec 2011 17:24:11 -0000, Adam <Adam@anizi.com> wrote:
> Ok, fine, let me put it THIS way.
>
> Suppose I use a parent library, and *I* don't update it.
>
> The USER of my library provides an updated version for some
> unrelated reason.

So.. the user has:

Parent.dll
Your.dll
Their.exe

and everything is working ok.  Then they update Parent.dll to a new version.  And because D does not require 'abstract' on classes, it all breaks?

But.. Your.dll has not been recompiled.. so how is D supposed to detect this?

Or, were you suggesting the user supply a new Parent.dll to you, and you rebuild Your.dll with it?  In which case, when you run your unit tests you will get an error, right?

Regan

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
December 02, 2011
I grant you that I should test it, and I never said otherwise. If
I'm attacking a strawman, it's the same one that was just put in
front of me as a misinterpretation of my argument.
What I contest and addressed was a test for the sole purpose of
determining if my class, assumed to be non-abstract, was
instantiable or not.

Other tests being necessary for something to be good programming or not, the issue here is that a test or a manual perusal of the base class for changes (specifically, for the addition of new abstract members) is required *just* to assert that my class is or is not abstract.

Yes, I should test my class, but I shouldn't have to test it just to ensure that it's the class I *intended* to create, rather than the one the compiler assumes because of a base class change.
December 02, 2011
Or I provide it as source, in which case, D *can* check it. But it means that when the parent is changed, my class type and instantiability implicitly changes, too.
December 02, 2011
On Fri, 02 Dec 2011 17:43:04 -0000, Adam <Adam@anizi.com> wrote:

> I grant you that I should test it, and I never said otherwise. If
> I'm attacking a strawman, it's the same one that was just put in
> front of me as a misinterpretation of my argument.

Well, I believe I understand your argument and I admit that I did find it odd that the error was not detected until the class was instantiated.  But, once I thought about it I understood why this is the case, and I believe you understand it as well.  I also understand that you'd rather it wasn't the case.  I think the only area of disagreement here is how much of a problem this is likely to be.

Using the library example you gave, and assuming 'basic' testing of the exported classes etc, you would discover the problem immediately.  No harm done.  In most other cases, you're either the producer of the parent, or a consumer of the immediate child and you'll discover the problem immediately.  So, again no harm done.

The only remaining case (I can see) is the one I mentioned in my other thread/reply.  That of the end user swapping out the parent library, in which case your library is not recompiled and D can't help you here.. unless it throws a runtime exception for this case.. hmm.

So.. adding abstract to the class definition doesn't seem to gain us much.  You can argue, as Jonathan did that it's more consistent, or provides a visual clue to the programmer.  But, the flip side is that it can be irritating to have to add it in the cases where it's already obvious to anyone reading the code - I have moments like that writing C#, even with good intelisense and good auto code generation.

Regan

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
December 02, 2011
On Fri, 02 Dec 2011 17:44:44 -0000, Adam <Adam@anizi.com> wrote:

> Or I provide it as source, in which case, D *can* check it.
> But it means that when the parent is changed, my class type and
> instantiability implicitly changes, too.

True.  This is a case I hadn't considered before.  In this case the user will get an error instantiating your class and report a bug to you.  Not ideal, but assuming you document the versions of the parent library you're compatible with, and run your unit tests against these it shouldn't happen and when it does it will be because the user upgraded the parent library past your compatibility guarantee, so it's on them.

R

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
December 02, 2011
>> Well, I believe I understand your argument and I admit that I did
find it
>> odd that the error was not detected until the class was
instantiated.
>> But, once I thought about it I understood why this is the case,
and I
>> believe you understand it as well.  I also understand that you'd
rather it
>> wasn't the case.  I think the only area of disagreement here is
how much
>> of a problem this is likely to be.

>> Using the library example you gave, and assuming 'basic' testing
of the
>> exported classes etc, you would discover the problem immediately.
No harm
>> done.  In most other cases, you're either the producer of the
parent, or a
>> consumer of the immediate child and you'll discover the problem immediately.  So, again no harm done.

>> The only remaining case (I can see) is the one I mentioned in my
other
>> thread/reply.  That of the end user swapping out the parent
library, in
>> which case your library is not recompiled and D can't help you
here..
>> unless it throws a runtime exception for this case.. hmm.

>> So.. adding abstract to the class definition doesn't seem to gain
us
>> much.  You can argue, as Jonathan did that it's more consistent,
or
>> provides a visual clue to the programmer.  But, the flip side is
that it
>> can be irritating to have to add it in the cases where it's
already
>> obvious to anyone reading the code - I have moments like that
writing C#,
>> even with good intelisense and good auto code generation.

(I really need to get a client for this - I just had to manually copy out your message and RegEx it to add the little >> marks)

Well, specifically, here's what it *does* give you:
It means that a class *not* marked as abstract is not intended by
the programmer to be abstract (equivalent to explicitly marking
something as nonabstract). If we accept that the default class
declaration (class X {}) is non-abstract, then we probably don't
need to consider explicit specification of non-abstraction.
It means that a class *marked* as abstract is intended to be
abstract.

The difference is that the compiler can then decide at the definition of a class - where this error belongs - if a Class actually conforms to its contract of being abstract / concrete.

No harm is done if sufficient testing in place, but it still puts the onus in *some* (probably quite specific or rare) circumstances on the user of my class, because it's feasible for my class to have been previously valid.

On the other hand, I should not require a unittest just to ensure that my class is the same class it was between some (potentially unknown) change. That's not to say that I shouldn't test, but I shouldn't have to for this one, particular case.

But D does not allow me to explicitly make it clear that my class is intended to be concrete, and it's relying on usage, rather than definition, for this information.

December 02, 2011
On Fri, 02 Dec 2011 11:05:00 -0500, Adam <Adam@anizi.com> wrote:

> 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.

How do you run your normal tests without instantiating?  There is no need to test instantiability, since it's implicitly tested in your unit tests.

> 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.

No.  It's covered by testing the functionality of the class.  You must instantiate to test anything related to the class.

> 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

The benefit is, I don't have to declare something is abstract *twice*, I only have to do it by leaving the function unimplemented.  This does not stop you from putting abstract on the class if you want to add that extra documentation.  The doc generator probably can put whether the class is abstract directly in the docs anyway.

The burden of proving benefit is on *changing* the language, not leaving it the same.  What benefit is there to requiring it?  You already have to instantiate to test the class, or use it, so what is the risk of not letting the compiler imply it?

Contrary to something like function purity, which must be declared on the function signature for prototypes, you always know all the members of a class and its base classes.  There is no hidden information, and no chance the compiler could get it wrong.

-Steve
December 02, 2011
Your presumption is that someone is required to run tests just to ensure that their class definition is what they expect. If I define a class and it's concrete (because I've defined everything), and later someone changes the parent class, my class is no longer concrete (it no longer conforms to my intention, despite having no way to actually *declare* my intentions in some explicit form). A programmer should do testing, but may not (does D require a programmer to test? No). You are implicitly testing the *definition* of a class, rather than it's *use* (or accuracy, or stability, etc).

Testing or not testing is TANGENTIAL to the issue. Assume that someone is not going to do unit test declarations (and do so without running off on the wild notion that it's "bad programming," because we've already established that). WITHOUT that test, I cannot *know* that my class *IS* what I originally defined it to be.

You mean you don't have to type 8 characters?

I've already given you the benefit of requiring it (or in another argument, but I'm actually assuming you read the rest of this thread). I shouldn't have to instantiate to test the DEFINITION of my class. My class is concrete. Or, rather, it WAS concrete. Now it's not. I have to test this? Unittests making use of an instantiated case of my class will catch this, but what you're saying is that, in the absence of a test case instantiating my class, I have to go ahead and test the definition.

In other words, I've declared this class. At the time of declaring it, it's concrete. Now I have to add a unittest to *ensure* it's concrete for an instantiation of this - and all of this ignores my previous posts and comments about USAGE of my class by others.

The compiler can't get it wrong, of course (and that's a ridiculous notion, anyway), but it means that something can change implicitly and transitively.