www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Subtypes with tighter constraints

reply Victor Porton <porton narod.ru> writes:
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
next sibling parent Alex <sascha.orlov gmail.com> writes:
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
prev sibling parent 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