5 ms·
Yet `Maybe<T> | Option<T> | ...` is not an option (pun intended), as Rich Hickey explains here: https://www.youtube.com/watch?v=YR5WdGrpoug https://www.youtube.
by sharpercoder 8y ago
Yet `Maybe<T> | Option<T> | ...` is not an option (pun intended), as Rich Hickey explains here: https://www.youtube.com/watch?v=YR5WdGrpoug https://www.youtube.com/watch?v=YR5WdGrpoug.
In effect, his argument is:
1) You have `public X Do(Y y)` changed into `public X Do(Option<Y> y)`. This will break your API.
2) You have `public X Do(Y y)` changed into `Option<X> Do(Y y)`. This will break your API.
Thus, do not use Option<T> or equivalent in your API's. Only use a language-supported construct such as C#8's upcoming `string?` and `string`.
- bunderbunder 8y agoThis is a spot where I've got to respectfully disagree with Mr. Hickey. Changing a public API call that used to guarantee that it returned a value so that it might now return nothing is a breaking change, and, as an API consumer, I want my APIs to broadcast that change loudly. Compiler errors are a good (but not the only) way to do that. Changing a public API member so that its arguments are now `Maybe[T]` is just silly. There's no need to introduce a breaking change there. Just overload it so that you now have versions that do and do not take the argument and get on with life. If there's an argument to be made here, it's that statically and dynamically typed languages require different ways of doing things. In a statically typed language, I expect the compiler to keep an eye on a lot of these things, and I'm used to leaning on the compiler to catch things like a function's return value changing. In a dynamic language, I'm not. I'm also, when working in a dynamic language, used to having to deal with the possibility that, at all times, any variable could contain data of literally any type. Removing nullability there changes the set of possible "this reference does not refer to what I expected" situations from (excuse the hand waving) a set with infinite cardinality to a set whose cardinality is infinity minus 1. If you think of NULL as effectively being a special type with a single value (call it "void"), then eliminating it reduces the number of classes of errors I have to worry about in a dynamic language by 0. I'm hard pressed to see any value there.
- tatut 8y agoThis is backwards. Rich did not advocate for changes that break promises. The point in the talk is that "strengthening a promise" should not be a breaking change. Changing return type from "T or NULL" to always returning T. The case where you previously couldn't guarantee a result, but now you can. The other case "relaxing a requirement" also should not be a problem. The case where you previously had to give me a value, but now I don't need it and can do my calculation without it.
- bunderbunder 8y agoTBH, I'm happy with that being a breaking change, too. Just keep returning a T? that happens to always have a value until the next major version # increment (or whatever), and then make the breaking change, and then I get a clear signal that I can delete some lines of code. The alternative seems like a path that, in any decently complex software project, ultimately leads to an accumulation of useless cruft that'll probably continue to grow over time as people keep copy/pasting code that contained the now-useless null-handling logic.