7 ms·
That's a generic container of 0 or 1 elements ;) It's also incredibly unsafe and why generics aren't enough. C++, Java, and so on have had generics for ages an
by AaronFriel 6y ago
That's a generic container of 0 or 1 elements ;)
It's also incredibly unsafe and why generics aren't enough. C++, Java, and so on have had generics for ages and with types like the one above, null pointer exceptions are incredibly common. Nothing prevents the user from attempting to retrieve the data without first retrieving the success status.
On the other hand, this improves on it dramatically:
enum Result<T, E> {
Success(T),
Failure(E)
}
- jcelerier 6y ago> It's also incredibly unsafe and why generics aren't enough. C++, Java, and so on have had generics for ages and with types like the one above, null pointer exceptions are incredibly common. uh, you'd never get a null-pointer exception in C++ given the type that OP mentioned. Value types in C++ cannot be null (and most things are value types by a large margin).
- nine_k 6y agoWell, T can be a pointer / reference here.
- jcelerier 6y agoThat wouldn't change anything to Result<T>'s implicit safety properties. "safe + unsafe == unsafe" - to have a meaningful discussion we should focus on the safe part, else it's always possible to bring up the argument of "but you can do ((char*)&whatever)[123] = 0x66;"
- sedatk 6y agoYou can also constrain a generic type only to value types in C#: class Result<T> where T: struct { ... } In that case it can't be null with C# either.
- AaronFriel 6y agoThen you can't construct it unless it's successful, no? A Result<T> that can only contain successful values doesn't seem very useful
- sedatk 6y agoYou can, it's possible to address "missing values" with a default construct. Example: int x = default; // x becomes zero T x = default; // x becomes whatever the default value for struct is
- AaronFriel 6y agoThen we're back to accessing that value being an enormous footgun, yes?
- loopz 6y agoInstead you can have undefined behaviour in C++. Don't think get;set is C++, though it breaks encapsulation.
- AaronFriel 6y agoThen you can't construct it unless it's successful, no? A Result<T> that can only contain successful values doesn't seem very useful
- joshuamorton 6y agoNo, you just are forced to use methods like foo.UnwrapOr(default_value) to get the Result. Or depending on the language, you get a compile error if you don't handle both possible values of the Result enum in a switch statement or if/else clause. See for example https://doc.rust-lang.org/std/result/enum.Result.html#method.unwrap_or_default https://doc.rust-lang.org/std/result/enum.Result.html#method... in rust, https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html#orElse-T- https://docs.oracle.com/javase/8/docs/api/java/util/Optional... in Java, and https://en.cppreference.com/w/cpp/utility/optional/value_or https://en.cppreference.com/w/cpp/utility/optional/value_or in C++.
- AaronFriel 6y agoWho are you replying to? Is any of your elaboration related to this result type? class Result<T> { bool IsSuccess {get; set;} string Message {get; set;} T Data {get; set;} }
- joshuamorton 6y agoAh you're quite correct.
- grandmczeb 6y agoYes you can? The equivalent type in C++ is std::expected[1] which doesn't even contain a pointer that could be dereferenced (unless T is a pointer obviously). [1] unfortunately not standardized yet https://github.com/TartanLlama/expected https://github.com/TartanLlama/expected
- AaronFriel 6y agoWho are you replying to? Is it in any way related to the original comment I replied to and this type? class Result<T> { bool IsSuccess {get; set;} string Message {get; set;} T Data {get; set;} }
- temac 6y ago> Value types in C++ cannot be null They can just not exist. And C++ being C++, dereferencing an empty std::optional is UB. In practice this particular UB often leads to way worse consequences than more "conventional" null-pointer derefs.
- gpderetta 6y agoThen write your own optional that always checks on dereference or toggle whatever compilation flag enables checking in the standard library you are using.
- masklinn 6y ago> That's a generic container of 0 or 1 elements ;) Then chances are so are most if not all of the uses of generics OP criticises. The only "non-container" generics I can think of is session types where the generic parameter represents a statically checked state.
- polskibus 6y agoWith c# 8 you have nullable references and you can use the compiler to guard you against null pointer exceptions.
- nicoburns 6y agoI'm convinced that lack of Sum Types like this in languages like Java/C#/Go are one of the key reasons that people prefer dynamic languages. It's incredibly freeing to be able to express "or". I do it all the time in JavaScript (variables in dynamic languages are basically one giant enum of every possible value), and I feel incredibly restricted when using a language that requires a class hierarchy to express this basic concept.
- dragonwriter 6y ago> I'm convinced that lack of Sum Types like this in languages like Java/C#/Go are one of the key reasons that people prefer dynamic languages. It doesn't hurt that static languages (TypeScript) or tools (mypy) that lightly lay on top of dynamic languages often do support sum types.
- fgonzag 6y agoI completely agree. Every passing day I become more convinced that a statically typed language without sum types or more broadly ADTs is fundamentally incomplete. The good news is that many languages seem to be cozying up to them, and both the JVM (through Kotlin, Scala, et all) and .net (through F# or C# w/ language-ext) support them. Even better news is that the C# team has stated that they want to implement Sum Types and ADTs into the language, and are actively looking into it.
- wvenable 6y agoI just don't see, in properly designed code, that there would be that much use for sum types if you have generics. When are you creating functions take or return radically different types that need to be expressed this way? I dislike dynamic languages where parameters and variables can take on any type -- it's rarely the case that same variable/parameter would ever need to contain a string, a number, or a Widget in the same block of code. I find it much more freeing to have the compiler be in charge of exactness so I can make whatever changes I need knowing that entire classes of mistakes are now impossible.
- deleted 6y ago[deleted]