DefaultPromise violates encapsulation

There are so many ways to break code, but hidden type overlap makes is surprisingly easy to break code and is quite hard to detect.

2 Likes

I’m with @curoli. I would want to have a way to future-proof all my union types, to validate that none of the element types overlap.

Forget about the traits.

Today I can manually validate that libfoo's foo.Foo and libbar's bar.Bar don’t overlap and that, therefore, my Foo | Bar union type is safe. But tomorrow libbar v1.1 is released and it has a brand new dependency on libfoo and it made Foo the parent of Bar. Now I’m hoping that I matched on Foo cases before Bar cases, because all of a sudden that ordering really matters…

1 Like

Isn’t that just better solved with a general rule of “Don’t treat pattern matching as casting unknown types”? If you’re casting an instance and don’t know it’s concrete type, you will get surprises in tons of ways. Don’t even need union types for those surprises either. I’m confused why union types would get such a special treatment.

1 Like

If you insist on refusing my opinion that “if a library breaks its API, then it can break code”, then you have to only use | in the alternative case that I mentioned earlier:

(Or with one of the branches being a private type that you can guarantee will be disjoint from any other type, irrespective of what other libraries do.)

1 Like

This seems extremely reasonable to me. It’s just the Liskov Substitution Principle: if an operation is valid on A, the operation is valid on an A that also extends B, because extending B doesn’t make it any less of an A. Maybe there’s an operation that is valid on it as a B, but that also doesn’t remove the fact that there’s an operation that’s valid on it as a A.

If you want to live with OO-style open class hierarchies, you have to live with OO-style principles like LSP, which are entirely self-consistent once you buy into the OO style of doing things. If you try and treat OO-style open class hierarchies like FP-style closed type hierarchies, you’re going to have a bad time, but that’s probably unavoidable. If you want FP-style closed type hierarchies, use sealed traits and sealed case classes, or the typeclass pattern if you want extensibility.

6 Likes