One of the things I don't like about Option[T] in Nim is when you are handed an optional large structure as a function argument, such as "Option[seq[Thing]]" or "Option[BigObject]", or those types as fields of an object passed as argument.<p>It works fine, but the act of unwrapping the value inside with x.get <i>copies</i> the large data structure inside to return it. So it's incredibly slow to access the value inside. Even one such access can be unacceptably slow.<p>Receiving the optional itself as a function argument is fast, because Nim passes a pointer for those arguments. The problem is when you need to use the value wrapped inside.<p>Nim encourages "value oriented programming", where things are written as value types, on the assumption that most of the time Nim is able to use temporary read-only aliases to data instead of copies. So this is the style of passing optionals around that I see in typical code.<p>If you have been handed a mutable option ("var Option[..]") that's different. Then you can unwrap the value inside as a mutable as well, which avoids the copy.<p>But you don't tend to be handed a mutable option in a function argument, except from code that was written in an unusual style with performance in mind, and a contract outside the type system: "I'm giving you a var, but only for performance reasons; don't write to it!".
The comparison of Nim to Ada seems appropriate. I've never used Ada but wrote a paper on it in school and found the concepts intruiging. Pretty interesting that a design by committee language had such rich integer types.<p>Nim looks like Python but really it reminds me more of a nicer looking Pascal. It's been great having ranged integers in Nim, especially when doing embedded work, without having the verbosity of Ada.
The key idea: Optional[T] is more ergonomic through pattern matching, because inside the matched case, we definitely know whether it's carrying a value or not. The whole problem of nullability gets an elegant solution.<p>The fun premise from the beginning is that booleans do not need their special type, they are effectively Optional[Void], or for FP-heads here, Optional[Unit]. That is, it just does not need to carry a value. But when an Optional <i>does</i> carry a value, a lot of if-then-else logic for handling that value just gets eliminated, replaced by a pattern match that combines both the boolean aspect and the value-handling aspect.