## digitalmars.D.learn - Subtypes with tighter constraints

• Victor Porton (8/8) Jan 01 2019 In Ada2012 there are "subtypes". Subtypes can have tighter
• Alex (38/45) Jan 01 2019 1. As Ada is strongly typed, this is the same there, no?
• Neia Neutuladh (14/22) Jan 01 2019 In D, structs don't participate in inheritance. Classes do, but invarian...
```In Ada2012 there are "subtypes". Subtypes can have tighter
constraints (such as type invariants) than their base types.

I have a struct X in D. Is it possible to define a type
equivalent to X except that having tighter invariants?

As I understand if I derive Y from X, then it is no more X; that
is I cannot use X (even provided it matches Y invariants) where I
need Y. So in D it is impossible, right?

I think in D it's impossible, but want to be sure and so ask.
```
Jan 01 2019
```On Tuesday, 1 January 2019 at 14:05:43 UTC, Victor Porton wrote:
In Ada2012 there are "subtypes". Subtypes can have tighter
constraints (such as type invariants) than their base types.

I have a struct X in D. Is it possible to define a type
equivalent to X except that having tighter invariants?

As I understand if I derive Y from X, then it is no more X;

1. As Ada is strongly typed, this is the same there, no?
2. You cannot derive structs in D. Therefore, I assume, that you
meant that X and Y are classes.

that is I cannot use X (even provided it matches Y invariants)
where I need Y. So in D it is impossible, right?

It is possible, as invariants are inherited implicitly, see
https://dlang.org/spec/contracts.html#Invariants
paragraph 9.

´´´
import std.experimental.all;

void main()
{
auto x = new X();
auto y = new Y();
x.d = 0.0;
y.d = 1.0;
x.fun;
y.fun;
}

class X
{
double d;

invariant
{
assert(!d.isNaN);
}
}

class Y : X
{
invariant
{
assert(d > 0);
}
}

void fun(T)(T t)
{
assert(t);
}
´´´
```
Jan 01 2019    Neia Neutuladh <neia ikeran.org> writes:
```On Tue, 01 Jan 2019 14:05:43 +0000, Victor Porton wrote:
In Ada2012 there are "subtypes". Subtypes can have tighter constraints
(such as type invariants) than their base types.

I have a struct X in D. Is it possible to define a type equivalent to X
except that having tighter invariants?

In D, structs don't participate in inheritance. Classes do, but invariants
aren't inherited; they're specific to the class in which the function is
defined. (Which is probably a bug and I filed https://issues.dlang.org/
show_bug.cgi?id=19537.)

I see three ways to make this work today:

1. Use alias this to wrap the struct. Add invariants that deal with the
wrapped struct's fields.
2. Use compile-time reflection to copy the fields over, then manually copy
the invariants over and add more.
3. Use a class. Define a virtual function like 'doInvariant()`. Call it
from the base class's invariant{} block.

As I understand if I derive Y from X, then it is no more X; that is I
cannot use X (even provided it matches Y invariants) where I need Y. So
in D it is impossible, right?

With classes, a derived class instance can be used anywhere you expect a
base class instance. The reverse is not true.
```
Jan 01 2019