4 ms·
The problem with colors is, as most things, bad programmers. The seminal example for me is Java Exceptions. Java tried to color functions based on which errors
by delusional 5y ago
The problem with colors is, as most things, bad programmers. The seminal example for me is Java Exceptions. Java tried to color functions based on which errors you had to handle in order to call that function. Well, most beginners didn't understand what an "exception" was, so in order to learn they were told to just ignore if for now. A Decade of bad advice like "just extend RuntimeException" and most of the production code at my job now is littered with catch(Exception e) because colored function were too hard for people. I still get confused looks when I say "Well if I change the types of errors this function can produce, i want the compiler to stop me until I've actually handled them".
You see the same thing happen in async circles. All of a sudden every single function has to be labeled async, whether it needs to or not.
- CornCobs 5y agoI don't think it's fair to label the failure of checked exceptions as "beginners didn't understand". It's the fact that returning null was deemed an acceptable return value on some types of failure throughout the standard library, rendering the whole idea basically moot since it didn't actually give you much guarantees. And later on, checked exceptions were incompatible with new stuff like lambdas and streams
- anonymoushn 5y agoOne reason checked exceptions are a not great is that library authors would like you to implement their interfaces or extend their classes, but they've decided that you can't throw anything :) Zig actually does pretty well on this front. you can write a library that accepts functions that return errors, and your functions will be specialized to return those errors in addition to their own if you don't handle them. Callers who want to handle errors exhaustively with a switch will get compile errors if the error set changes and they fail to handle new errors.
- mananaysiempre 5y agoI’m not convinced programmers are the problem. Haskell’s use of monads is perhaps the ultimate in colouring (for values not functions, but that doesn’t make that much of a difference); you routinely colour everything with which pieces of state it needs to read and/or write to do its thing. The result is you either have everything painted in “global state”, which just feels like unnecessary boilerplate, or you spend most of your time defining and converting between elaborately carved pieces of said state. People could and did invent various intricate constructions which would do the conversions and possibly even the carving for you, but overall I think most agreed it was a gigantic pain. It’s possible the situation is fixable with a correct combination of features (records, polymorphic variants, implicit parameters, possibly even algebraic effects), as a good portion of the pain comes from not having a standard solution every library would use (they all have drawbacks). But then the checked exceptions story in Java, IIRC, is from pre-Java 5 times, and not being able to be polymorphic in the exception signature of a callback you take is really stupid however you look at it, as well as also a case of inadequate language features.
- int_19h 5y agoThe biggest problem with Java checked exceptions was that you couldn't generalize over them. Simply put, you can't write a method in Java that takes some object X, invokes X.Y(), and throws the same checked exceptions that X.Y() throws. This despite the fact that OO design is heavy on such equivalents of higher-order functions (think comparators, observers, visitors etc). In a similar vein, as another commenter above said, really the only problem with function coloring is that we're not treating it polymorphically.
- delusional 5y agoCan't you though? I'm pretty sure you can public class SomeClass<E extends Exception> { public someMethod() throws E {} } is valid java, I'm pretty sure.
- int_19h 5y agoIt is valid Java, but this code lets you specify only a single exception type, while exception specifications can (and usually do) have multiple types. And Java doesn't have the equivalent of C++ template parameter packs. The other problem with this approach is that it requires the caller to explicitly specify all the exceptions thrown by the function/object being wrapped. So every time you do map() or fold(), you have to spell out the full exception spec for the closure you're passing in. And god help you if there's nested maps...
- int_19h 5y agoBTW, the original structurally-typed proposal for closures in Java included generic exception specifications (among many other things). Unfortunately, that was killed off in favor of a much simpler take. http://javac.info/closures-v06a.html http://javac.info/closures-v06a.html