4 ms·
Not necessarily. Not only is it Option.Some/None/ProbablySomeBuyMaybeNoneBecauseJava, it doesn't offer the exact separation that Options can offer: you can stic
by ohgodplsno 5y ago
Not necessarily. Not only is it Option.Some/None/ProbablySomeBuyMaybeNoneBecauseJava, it doesn't offer the exact separation that Options can offer: you can stick a value in Option.None (String? can contain null or ""). Nullable types are different to options.
(Bonus point for Java that has introduced Option types, that can still be null)
- nemetroid 5y agoThat sounds like an Option type to me: String? :: Option String :: Option.Some null :: Option.None
- Nullabillity 5y agoThe problem with Kotlin is that it only has one global "anything-but-null", so nested ?s are collapsed (String?? is equivalent to String?). This is because it needs to run on the JVM, which only knows about is-null and is-not-null. This interacts terribly with generics, since it means that only one side of the generic boundary can "own" the null value at any one time. To simplify a case where this can cause issues: class Loadable<T>( // null until value is loaded var valueIfLoaded: T?, ) // returns null if user is not found fun getUser(id: String): Loadable<User?> Code that interprets Loadable<T> will get stuck showing a loading bar, since it has no idea about getUser using null for anything else. This doesn't even generate a warning! The "correct thing to do here would be to add a `T: Any` bound on Loadable, which prevents T from itself being a nullable type. That would notify the author of getUser that they need to box the User?, so that the cases are kept separate: data class Box<T>(val value: T) class Loadable<T>( // null until value is loaded var valueIfLoaded: T?, ) // returns null if user is not found fun getUser(id: String): Loadable<Box<T?>> These are things you don't even have to consider when using a typical well-designed Option type (which, mind you, could still have a syntax sugar for T? if you wanted it).