5 ms·
That's just a problem with ordering. If a condition implies a non null pointer then a non null pointer can imply the condition as well. This is true unless the
by webkike 9y ago
That's just a problem with ordering. If a condition implies a non null pointer then a non null pointer can imply the condition as well. This is true unless the condition being false does not guarantee a null pointer, in which case the condition is not useful.
If some condition implies multiple non null pointers then the option type can be defined on a tuple of references
- tomsmeding 9y ago> in which case the condition is not useful I contest. The reason for the condition need not be only to indicate whether the other value isn't null; if it was, you could just remove the condition and check nullity. In fact, unless there is either a case where the condition is true and the pointer is null or a case where the condition is false and the pointer is non-null, the condition is useless because checking the pointer would've been enough. Consider the following silly example, where we have a function f(Conductor *c, bool isDriving, Train *t) with the guarantees that c != NULL, and isDriving==true => t!=NULL. Note that the case isDriving==false does not imply t==NULL; indeed, c could just be waiting for the signal to start driving.
- webkike 9y agoisDriving remains connected to t. Specifying an Option reference for t allows you to convey two pieces of information: if None, that isDriving is false and you do not care about t, and if Some, you have train t
- dbaupp 9y agoOne can express the states more clearly with a slightly upgraded Option/Optional/Maybe, i.e. a full sum-type/enum. For instance, that function could be, in Rust syntax (but the same thing works in Haskell, OCaml, Swift, ...): enum ConductorTask { Nothing, Waiting(Train), Driving(Train) } fn f(c: Conductor, task: ConductorTask) I think this says everything that your text says, but in a way the compiler understands and can assist the programmer with. Alternatively, since isDriving only makes sense when there's a train, t could be Option<(bool, Train)>, i.e. an optional train along with a boolean for if it's being driven or not.
- cwzwarich 9y agoAn Option type in Rust forces a particular memory layout by requiring the components to be contiguous, which might not be what you want if you are doing low-level optimizations of data layout.
- jjnoakes 9y agoSo put a ref or a box in your optional.
- dbaupp 9y agoI don't think adding indirection is what the parent was thinking of. It's more like storing the Option<T> Some vs. None bit in its own separate bitvector along with a packed vector of Ts. This layout, due to padding, may be significantly less memory than alternating bool, T like a vector of Option<T>s gives, but it still retains properties like contiguous layout and minimal allocation/indirection.
- dbaupp 9y agoThat's true, and does mean one has to drop down to C/C++-style pointers and manual layout when the default enums don't work. However, that's somewhat orthogonal to the semantics about what they can express, especially for function arguments where the value isn't being stored in memory. One common approach is for an enum to be teased apart to be stored, and then rematerialised at the API surface (e.g. HashMap and it semantically storing an Option<(K, V)>).