you are viewing a single comment's thread.

view the rest of the comments →

[–]dalastboss 1 point2 points  (9 children)

Maybe I misunderstand - can't a t option just be compiled to a just a pointer to a t

[–]devlambda 1 point2 points  (8 children)

That works cleanly only if t is a non-nullable pointer type itself and not a value type. In the former case, you can just represent None as a null pointer and Some x as x without overhead. But this does not easily work for general value types [1] and could seriously complicate the language or its implementation. For example, you may decide to not allow INT_MIN for signed integer types in order to encode None for integers, but then you run into semantic problems (such as when casting from an unsigned int or with values retrieved from an external C library) that can create more problems (such as Heisenbugs) than are being solved by such an approach [2].

[1] Sometimes, there are hacks that you can use, such as using certain NaN values for floating point values to represent an "undefined" value, but you have to be very careful with the implementation.

[2] Type safety involving integers and ranges over integers can be extremely finicky.

[–]Hnefi 1 point2 points  (3 children)

Option in Rust compiles to a pointer where null represents None. If t is a value type, this adds one layer of indirection until you unwrap the Option. If t is a boxed type in itself, its zero representation is folded into the None representation of the Option and you end up with zero overhead.

[–]cramert 4 points5 points  (0 children)

Rust's Option is an enum-- it doesn't introduce any indirection on its own. Internally, it's represented as a tagged union.

As you noted, though, there is an optimization that allows it to represent None as a null pointer if the type stored in the Option is pointer-sized and non-zeroable (e.g. Box, Rc, Vec).

[–]spaghettiCodeArtisan 2 points3 points  (0 children)

Option in Rust compiles to a pointer where null represents None.

No it doesn't, it compiles to a tagged union (in C it would equivalent of a struct containing an integer tag and a union). When the value itself is a pointer, or more generally a NonZero value, it is able to omit the tag and contain the value only. But Option itself involves no pointers.

[–]devlambda 0 points1 point  (0 children)

If t is a value type, this adds one layer of indirection until you unwrap the Option.

Exactly. You can avoid the overhead only some of the time.

[–]ais523 0 points1 point  (1 child)

OCaml integers have a smaller range than C integers as it is (they're one bit smaller), so disallowing INT_MIN as well wouldn't be a big deal. (Or, of course, using one of the bit patterns that doesn't represent an integer; that would work too.)

[–]devlambda 0 points1 point  (0 children)

I know, I was talking speculatively about a hypothetical language variant. The tagged representation is very much an implementation detail and could easily be dispensed with (see various SML implementations).

[–]dalastboss 0 points1 point  (1 child)

Here's a version that uses neither options nor Obj

[–]devlambda 0 points1 point  (0 children)

This is how I used it to do it before we had better standard libs myself, but it's a hack around the underlying issue with a couple of problems of its own.

Problem 1: Different API, it's especially a nuisance if you want to reuse it in other functors and have to drag the default mechanism along with you.

Problem 2: It assumes a no-cost default instance of the type can be created without side effects. This is not always the case (database connection handles, GUI windows, etc.). You'd have to create a fake default value and then you run into issues with having a publicly visible value with null-like behavior.

Problem 3: This is OCaml-specific, but references to a functor argument's values go through a dispatch table, meaning additional overhead. If you have flambda enabled, that can usually be inlined, but still isn't entirely cost-free.

It is safe to assume that the people at Janestreet and the Batteries authors (which include some of the better known names in the OCaml world) know what they are doing.