Comment by tialaramex

Comment by tialaramex a day ago

4 replies

> I don't thing there is any substantial difference between `Option<Thing>` and `@Nullable Thing` or `Thing | null`

I object to @Nullable and similar arrangements as a magic special case. If the sum types only solved this one issue then it's a wash but they do a lot more too.

Either of the sum types, the concrete `Option<Thing>` or the ad hoc `Thing | null` are OK because they're not magic, less magic is better.

simonask a day ago

I’m confused. You seem to think Option is magical? It is not, and neither is Result. They are regular sum types defined in the standard library, nothing special about them.

  • tialaramex a day ago

    That's certainly not what I was trying to get across. Perhaps I wrote something confusing, for which I apologise, but, since we're here anyway...

    Technically Option is actually magic, though it's for a subtle reason unconnected to the current topic. If you go read its source Option is a langitem, that is, Rust literally isn't allowed to exist without this type. Rust's core libraries are defined, so you shouldn't and most people never will use Rust without them, but the Rust language actually doesn't require that all of core exists, it does require a handful of types, functions etc. and those are called "langitems".

    So, why is Option a langitem? Well, Rust's language has for-each loops. But what it actually does (there's literally a compiler step doing this) is treat those loops as if they'd been written as a slightly clunky loop { } block making and then consuming an Iterator. To do that the IntoIterator and Iterator traits must exist, and further as the return type from the next call needed in Iterator is an Option the Option generic type must exist too!

    Technically this type wouldn't have to be called Option, the Rust compiler doesn't care what it is called, but it must exist or else the compiler doesn't know how a for-each loop can work.

    • simonask 14 hours ago

      Being a langitem means that the compiler can use it in desugaring, and `for ... in ...` happens to be syntactic sugar in Rust, just like `for (auto x: y) {}` is in C++. `Range` et al are also compiler builtins, because `a..b` desugars to that type. It doesn't imply that the type itself is a compiler builtin, for example.

      Another example is the `Deref` trait, which roughly corresponds to `operator->()` or `operator*()`, or an implicit reference conversion. It is called implicitly so you can use `smart_ptr.foo` without special syntax for dereferencing.

      I think I fundamentally don't understand why any of this is a problem?

      • tialaramex 12 hours ago

        I think maybe your fundamental misunderstanding was just a misreading of what I actually wrote?

        I don't like @Nullable (or the ? syntax used in C# for example) because they're a special case magic. They handle exactly one narrow idea (Tony's Billion Dollar Mistake, the "null" pointer) and nothing else.

        I prefer sum types - both Option<T> and T | null are syntax for sum types. The former, which Rust has, is an explicit generic type, while the latter is an ad hoc typing feature. I don't have a strong preference between them.