In a message dated Fri, 25 Aug 2006, Mark J. Reed writes:

On 8/25/06, Trey Harris <[EMAIL PROTECTED]> wrote:
> subclasses can remove functionality as well as adding it

Can someone suggest some reading I can do to understand how that works?
I can't wrap my head around the idea of subclasses removing functionality.

Why not?  Is it any weirder than simply changing that functionality
beyond recognition?

If "changing that functionality beyond recognition" means changing its external behavior (as opposed to its internal behavior) so that it acts differently from what the superclass had promised to do, then no, it's not any weirder--but I can't figure out how the contract would work, either.

To extend the "contract" analogy, if I lease you a house, I may allow you to sublease the house, and I may even agree to take my rent directly from the sublessee rather than from you. But the sublessee can't just say to me, "yeah, so, I'm going to pay you 1000 yen, not 1000 dollars," and expect me to just put up with it or work around the missing money. I made assumptions based on the original contract. If the sublessee says he wants to pay me more or more promptly or in cash under the table, great. If he wants to listen to opera in the evenings instead of of watching TV, that's internal behavior having nothing to do with our contract and I don't care.

The changes have to be either in my favor or irrelevant to the contract. Otherwise, I'm going to demand we renegotiate--in other words, that you don't pretend to be a superclass whose behavior you're not willing to emulate, so that when I see you I can treat you as what you are, not what you're pretending to be.

"isa" means "is a".  It doesn't mean "is roughly of a class analogous to".

You can always fake removing functionality even if the language
doesn't actually support it.  Consider:

class Super { method something {...} }

class Sub is Super { method something { throw new MissingMethodException; } }

or whatever that ends up looking like.

In Ruby and C++, a subclass can make a method private that is public
in its superclass, effectively removing it.  (Java disallows such
shenanigans).

But why would you want to, just because "ConstArray isa Array, not the other way around" just feels right? "Pluto isa Planet" feels right too, but one can't construct a reasonable definition that doesn't pull things in that you don't want to consider Planets.

Remember, one of the goals of Perl 6 is to make it more friendly to very large software projects. "Java disallows such shenanigans" is one example of precisely why Java has become so popular for large projects. (The exception-throwing example is clearly, well, an exception, and you can always do that.)

When software gets large, you need to be able to impose some constraints on behavior. Maybe this is a stricture or something. In any case, I'm not trying to make a ideological argument here. I don't care if you can remove functionality or add constraints if that helps me get my job done (I'm just skeptical that it will).

I just want to think about the DBC features of Perl 6, and I don't know how they could work in the context of loosening contracts in subclasses, and I'd like somebody to point me to how, that's all. Design-by-Contract is all about formal definitions.

Does this mean you can't [...] expect foo($obj) to work

Of course you can expect foo($obj) to work.  It might not, if the
subclass definition does something weird, but that's always the case
whether "removing functionality" is on the table or not, and it's no
reason to change your reasonable expectations. You can be paranoid
about it if you want, but it's not a very Perlish form of paranoia.
(Yes, there are Perlish forms of paranoia.  Taintedness checking, for
instance...)

When I said "expect it to work", that was shorthand for "it *will* work, in the absence of a bug". That's what DBC is all about--that one can program based on the expectations of the contract, and you don't have to write error-catching code every single time you use an object's exported functionality.

I'll agree that DBC isn't very Perlish, in much the same way that strict was not very Perlish in Perl 5 (for at least the first five years of its existence, and probably even till today). But in Perl 6 strict is the default, so by definition now Perlish. :-)

If DBC is in the language, then some people will use it, most people won't because they don't like the inconvenience, and over time if it actually results in more solid software, more people will choose to adopt it (like strict).

But in order to allow that choice, the language has to impose some groundrules for everyone. strict couldn't exist in Perl 5 if lexicals could autovivify. And--*by my understanding of DBC*--subclasses can't remove promised functionality or impose surprising constraints. So a) Perl 6 can't support DBC, contrary to the Synopses, b) you can't remove functionality or impose new constraints in subclasses, or c) my understanding of DBC is incorrect.

Trey

Reply via email to