Thread overview
Inheritance and in-contracts
Dec 05, 2014
Ali Çehreli
Dec 05, 2014
bearophile
Dec 22, 2014
aldanor
Dec 22, 2014
Ali Çehreli
Dec 22, 2014
aldanor
December 05, 2014
Suppose I have a base class where one of the methods has an in-contract, and a derived class that overrides it:

/////////////////////////////////////////
import std.stdio;

abstract class Base
{
    abstract void foo(int n)
    in
    {
        assert(n > 5);
    }
    body
    {
        assert(false, "Shouldn't get here");
    }
}

class Deriv : Base
{
    override void foo(int n)
    {
        writeln("n = ", n);
    }
}


void main()
{
    Base b = new Deriv;

    b.foo(7);
    b.foo(3);
}
/////////////////////////////////////////

This outputs,

n = 7
n = 3

In other words, the lack of explicit in-contract on Deriv.foo is being taken as an _empty_ in-contract, which is being interpreted as per the rule that a derived class can have a less restrictive contract than its base (cf. TDPL pp.329-331).

Question: is there any way of indicating that Deriv.foo should inherit the in-contract from the base method, without actually calling super.foo ... ?

Following the example on p.331, I did try calling super.__in_contract_format(n) (... or this.Base.__in_contract_format(n) or other variants), but that doesn't seem to work:

    Error: no property '__in_contract_foo' for type 'incontract.Base'

... so can anyone advise if there is a reasonable way of achieving this?

Thanks,

     -- Joe
December 05, 2014
On 12/05/2014 02:39 PM, Joseph Rushton Wakeling via Digitalmars-d-learn wrote:

> In other words, the lack of explicit in-contract on Deriv.foo is being
> taken as an _empty_ in-contract, which is being interpreted as per the
> rule that a derived class can have a less restrictive contract than its
> base (cf. TDPL pp.329-331).

This is a known problem with contract inheritance. The following bug report mentions the ugly hack of defining assert(0) as the derived's 'in' contract:

  https://issues.dlang.org/show_bug.cgi?id=6856

Ali

December 05, 2014
Joseph Rushton Wakeling:

> Suppose I have a base class where one of the methods has an in-contract,

It's named "precondition" or "pre-condition".


> Following the example on p.331, I did try calling super.__in_contract_format(n) (... or this.Base.__in_contract_format(n) or other variants), but that doesn't seem to work:
>
>     Error: no property '__in_contract_foo' for type 'incontract.Base'
>
> ... so can anyone advise if there is a reasonable way of achieving this?

Is this a strong need?

Bye,
bearophile
December 05, 2014
On 05/12/14 23:45, Ali Çehreli via Digitalmars-d-learn wrote:
> This is a known problem with contract inheritance. The following bug report
> mentions the ugly hack of defining assert(0) as the derived's 'in' contract:
>
>    https://issues.dlang.org/show_bug.cgi?id=6856

Thanks for the clarification.  This is a not-nice situation; FWIW I would second Don's proposal that the absence of an explicit in-contract on the derived-class method ought to indicate inheritance of the base contract.

I guess the assert(false) method will do, but I find it as ugly as you do :-(

One further annoyance, pointed out to me by a colleague earlier today: given that base and derived in-contracts basically come down to,

   try
   {
       Base.in()
   }
   catch (Throwable)
   {
      Derived.in()
   }

... aren't there some nasty consequences here for memory allocation and the generation of garbage?

December 05, 2014
On 06/12/14 00:24, bearophile via Digitalmars-d-learn wrote:
> Is this a strong need?

Let's put it this way: I don't mind copy-pasting the same in-contract into derived class methods.  I'd just rather avoid it, and was hoping there was a way to do so which was trivial.

It's disappointing that the lack of an explicitly empty in-contract doesn't imply inheritance of the base contract, but I could live with it much more easily if I could explicitly indicate that desired inheritance.
December 22, 2014
https://github.com/D-Programming-Language/dmd/pull/4200
December 22, 2014
On 12/22/2014 10:06 AM, aldanor wrote:
> https://github.com/D-Programming-Language/dmd/pull/4200

Thank you! This fixes a big problem with the contracts in D.

Ali

December 22, 2014
On Monday, 22 December 2014 at 19:11:13 UTC, Ali Çehreli wrote:
> On 12/22/2014 10:06 AM, aldanor wrote:
>> https://github.com/D-Programming-Language/dmd/pull/4200
>
> Thank you! This fixes a big problem with the contracts in D.
>
> Ali

It's not my PR but I just thought this thread would be happy to know :)
December 22, 2014
On 22/12/14 19:06, aldanor via Digitalmars-d-learn wrote:
> https://github.com/D-Programming-Language/dmd/pull/4200

Yes, I saw that PR with some joy -- thanks for the link! :-)
December 22, 2014
On 22/12/14 20:12, aldanor via Digitalmars-d-learn wrote:
> On Monday, 22 December 2014 at 19:11:13 UTC, Ali Çehreli wrote:
>> On 12/22/2014 10:06 AM, aldanor wrote:
>>> https://github.com/D-Programming-Language/dmd/pull/4200
>>
>> Thank you! This fixes a big problem with the contracts in D.
>>
>> Ali
>
> It's not my PR but I just thought this thread would be happy to know :)

Actually, the author is a friend of mine, and an all-round wonderful guy. :-)