sumtype 0.5.0

Paul Backus snarwin at gmail.com
Sat Aug 11 01:58:48 UTC 2018


On Friday, 10 August 2018 at 21:28:40 UTC, Everlast wrote:
> Yes, but
>
>>> alias Z = SumType.Union(X,Y);
>
> is not the same as
>
>>> alias Z = SumType!(int, float, string, complex, vector).
>
> In the first case Z is actually a union of 2 types while in the 
> second it is of 5. There is a subtle difference in that in the 
> second case the types lose relation. E.g., there is no way to 
> recover X or Y from Z but in the first we can:
>
> [...]
>
> ZZ is flat while Z is hierarchical.

If you want to nest SumTypes, there's nothing stopping you from 
doing that already. `alias Z = SumType!(X, Y);` will work just 
fine. I wouldn't necessarily recommend it, since each layer 
introduces additional memory overhead to store the type tag, but 
it will work.

> I'm not sure how SumType deals with type info, if it is local 
> or global. If it were global, then Z would definitely be 
> different than ZZ.

I assume by type info, you mean the tag values? If so, they're 
local to each instantiation of SumType. For example, in 
SumType!(A, B), a tag value of `0` corresponds to the type `A`, 
whereas in SumType!(C, D), the same tag value of `0` corresponds 
to the type `C`.

> alias Z = SumType!(X,Y) is a type itself and effectively 
> inherits from X and Y but this relationship is not expressed in 
> any meaningful way in SumType.

I think we may each have a slightly different idea of what 
"inheritance" means, in this context. When you say "Z inherits 
from X and Y", I interpret that as meaning "Z is a subtype of X 
and Y"--which isn't true. A subtype should obey the 
substitutability principle: anywhere I can use an object of the 
supertype, I should be able to substitute an object of the 
subtype, and my program should still be correct when I do.

But suppose I have a function that accepts an X, and I pass it a 
Z instead. What happens if it turns out, at runtime, that the Z 
contains a Y? The function won't be prepared to handle it--in 
other words, my program is now incorrect. That means the 
substitution was invalid, and Z is not a subtype of X after all.

Now, the relationship *does* hold in the opposite direction: if I 
have a function that accepts a Z, I can pass it an X, and it will 
be able to handle it. Granted, I'll have to do a little bit of 
extra typing to wrap the X (i.e., `f(Z(x))` rather than just 
`f(x)`), because D doesn't allow user-defined implicit 
conversions, but that's not a terribly large burden. (And if I 
really want to write `f(x)`, I can always define an overload of 
`f` that takes an `X` argument and forwards to the `Z` version.)

> Maybe SumType!(X,Y) could return a new type that is a class 
> that inherits from X and Y? (unfortunately this can't work 
> because of single inheritance but these types could probably be 
> wrapped in interfaces and properties could be used)

It sounds like I may not have been clear enough about what 
SumType's goal actually is. SumType's goal is not, and has never 
been, to be a feature-complete alternative to OOP language 
features like classes, interfaces, and inheritance. Those 
features already exist in D; there's no need to duplicate them.

SumType's goal is, instead, to provide a much more limited, much 
less flexible version of polymorphism--one that requires every 
possible "subclass" (i.e., member type) and every "method 
override" (i.e., match handler) to be fixed up-front, in one 
place, at compile time. You cannot add new member types to an 
existing SumType, the way you can add new derived classes to an 
existing base class--and this is by design!

Why is SumType designed this way? Because it turns out that this 
very limited version of polymorphism can be implemented *much* 
more efficiently than the real thing. It doesn't require virtual 
methods, it doesn't require heap allocation, and it doesn't 
require runtime type information. In fact, the only thing keeping 
SumType from being BetterC compatible right now is the fact that 
it uses DRuntime features *during CTFE*!

Anyway, I hope I've explained things clearly enough now to avoid 
further misunderstanding. Please let me know if you have any more 
questions or ideas--I really appreciate the thought you've put 
into this discussion.


More information about the Digitalmars-d-announce mailing list