I wrote a zero-allocation `Option`-style (monadic) data structure for Scala a while ago [1]. Unlike all the previous attempts, it supports the distinction between `None`, `Some(None)`, `Some(null)`, `Some(Some(None))`, etc., which is what allows it to remain monadic. The surprise is that it does not use `null` as the `None` value. The downside is that `toString()` is altered: `Some("hello").toString()` returns `hello`, not `Some(hello)`.
There was an experiment to use it as a replacement for the implementation of `scala.Option` in the dotty compiler code base [2], but it is inconclusive so far; it should be tried directly in the collections library.
Just curious, if Some(hello).toString produces `hello`, what does None.toString() and Some(None).toString() and Some(Some(None)).toString() produce? (My guess is `None` for all)
I think it's impressive† that you got nesting to work, I'm really curious how you pulled that off for longs and doubles without incurring extra overhead.
† Though, given the magic you worked in getting Union types working in the ScalaJS facades I shouldn't be surprised.
Oh primitive types do get one level of boxing (on the JVM): a `Double` becomes a `java.lang.Double`. But it doesn't become a `Some` with a `java.lang.Double` inside, so we gained one allocation anyway. It is not possible to remove that box without compiler support, and even then not in all cases (return values for examples) because `Double` contains a finite amount of values 2^64, and `Option[None]` has 2^64 + 1 values.
And in that implementation, `None.toString == "None"`, `Some(None).toString == "Some(None)", etc. Although that could be changed.
Seems like one could use the wasted digit of signed numbers to stor options rather than have asymmetric range (two's complement) or positive/negative zero... IE have a [ed:bit string] that indicates none/some?
It's no longer monadic in the presence of a pervasive `null` value. Such is the power of null - it breaks abstractions that have nothing to do with it.
It is monadic if the monad laws about it hold. `null` has nothing to do with it. In the context of my unboxed option, `null` is like `5`: one of many primitive values, uninterpreted by the abstraction, and therefore it does not break the abstraction.
If you think my unboxed option is not monadic, please provide a counter-example to one of the monad laws.
There was an experiment to use it as a replacement for the implementation of `scala.Option` in the dotty compiler code base [2], but it is inconclusive so far; it should be tried directly in the collections library.
[1] https://github.com/sjrd/scala-unboxed-option
[2] https://github.com/lampepfl/dotty/pull/3181