News for hackers. Stuff that matters.
Re:Notes on a Smaller Rust by barrkel on Thursday July 18, 2019 @09:55AM (#20469774)
The "right" thing in Java would be to parameterize map() by the error type declared on the lambda passed in. In other words:

    interface Function<T,U,Err> {
       U apply(T value) throws Err;
    }

    interface List<T> {
        <U,Err> List<U> map(Function<T,U,Err> f) throws Err;
    }
Re:Notes on a Smaller Rust by lmm on Thursday July 18, 2019 @10:02AM (#20469840)
That only works for exactly one exception type. Err cannot be no errors, nor can it be two or more unrelated exceptions. You end up having to have n different overloads (for 0, 1, 2, ... exceptions) for every functions, and since Java's type system is not up to "varidic generics" you have to write them all manually.
Re:Notes on a Smaller Rust by cjhopman on Thursday July 18, 2019 @07:54PM (#20475108)
While you're correct about the two or more unrelated exceptions, Java will happily infer Err to RuntimeException and so the no errors case works just fine there. It's only work in a case where the type is only needed by inference, though.
Re:Notes on a Smaller Rust by barrkel on Thursday July 18, 2019 @11:26AM (#20470805)
Oh indeed, you need |, and the ability to compose the type parameters, etc. It's why I said "right" rather than right.
Re:Notes on a Smaller Rust by Nullabillity on Thursday July 18, 2019 @10:31AM (#20470169)
You could solve that with sum types (for 2+ exceptions) and never types (for 0),
Re:Notes on a Smaller Rust by lmm on Thursday July 18, 2019 @10:39AM (#20470271)
It's not actually a sum, it's an inclusive union which are much harder to reason about and compromise your type system more (IMO). In any case, Java does not have any of those, and this is what makes checked exceptions impractical to work with; Rust has sum types but I don't think it has either inclusive unions or never types.
Re:Notes on a Smaller Rust by Nullabillity on Thursday July 18, 2019 @08:31PM (#20475287)
> It's not actually a sum, it's an inclusive union

Right, whoops. My bad!

> In any case, Java does not have any of those, and this is what makes checked exceptions impractical to work with

Absolutely. I was approaching it from the standpoint of "what would I change about Java's type system to make checked exceptions usable?".

> Rust has sum types but I don't think it has either inclusive unions or never types.

Rust is working on stabilizing a true never type[0], and until then you can emulate it with an empty enum.[1] There is also a RFC for unions, but that doesn't seem to have gone anywere.[2]

[0]: https://github.com/rust-lang/rust/issues/57012

[1]: Such as https://crates.io/crates/void which also provides helpers for safely coercing `Void` `Result`s

[2]: https://github.com/rust-lang/rfcs/pull/1154

Re:Notes on a Smaller Rust by Quekid5 on Saturday July 20, 2019 @08:08PM (#20489107)
My comment was actually made with many of these issues in mind -- I was trying to avoid needless nitpicking by being a bit vague. Perhaps that was a mistake.

The point wasn't that these things couldn't be solved -- they could, at least in theory[0] -- but that the current practical limitations of Java[1] are such that the interaction of higher-order functions and checked exceptions make checked exceptions a really bad idea.

[0] At least I think so... given anonymous or adhoc sum types, etc.

[1] Interestingly, this is not a JVM-wide issue. It's just the Java compiler that imposes these restrictions, for example: You cannot "catch" a checked exception which hasn't been declared at least one method in the "try" scope. This makes sense at first glance ("cannot happen"), but means that re-wrapping by higher-order functions must entail extremely error-prone inspection of any exception by calling code, etc. etc. It's a huge mess.

Re:Notes on a Smaller Rust by Quekid5 on Friday July 26, 2019 @02:02PM (#20536859)
A bit late... but as others have pointed out:

This only works to the first order. If you have functions-that-call-functions-that-call-functions, you end up not being able to write(!) the correct throws clauses in Java.