the generated bytecode would be the same, but we would also get a
    compile-time assertion that B is indeed total on A, and an error
    message when it is not. (There was a long thread about this, but
    basically: I started programming with sealed classes, and found it
    almost irrersistible to use such blind casts, because “of course”
    they would succeed, but this makes for brittle code.  There’s a
    separate discussion on whether we should just allow A to be
    assigned to B, but this is kind of orthogonal.)


I prefer a declaration site keyword instead of a use site declaration, use site declarations are not very Java-ish.
So something along the line
  sealed interface A permits only B {}

But the problem is not at the declaration site.  The declaration is fine; the problem is that the use site makes use of an assumption-at-a-distance, one that could be invalidated by someone else's action, and users might want to engage the compiler to help them detect when that happens.  The declaration site hint doesn't add anything to the status quo, as it can't prevent the "only" from being dropped in the future.

I recently as an exercise tried to write a part of ZIO in Java, just for fun and because it uses patterns extensively. This type of cast appears so often that I think i'm tilting toward just allowing A to be assigned to B.

I agree (see earlier argument about "it's like a union type"), but I'm not sure that means that we are never interested in marking a cast total also.



         case Foo(Bar(total Baz b)):

    we might insert an extra case right after for:

         caes Foo(Bar(var remainder)): throw

    to close off the side paths.


By inserting a new case, you don't mean literally inserting a new case ?

Sorry, I meant an extra dynamic *cast*.


Reply via email to