Created
November 24, 2011 19:23
-
-
Save zah/1392058 to your computer and use it in GitHub Desktop.
The case for Option[T]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Option[T] and safe navigation: | |
| # Some languages have a specialized syntax for what is usually called "safe navigation" | |
| foo?.bar[10]?.baz | |
| # Option[T] could be implemented as a proxy type that rewrites any operation on it | |
| # as a operation applied to the stored value (if there is any) | |
| # The original example then becomes: | |
| Option(foo).bar[10].baz # returns Option[type(baz)] | |
| # Another point to note: proxy types used in this fashion are pretty much equivalent to Haskell's monads | |
| # Option[T] and the HLO: | |
| # One can write a rule similar to this: | |
| template { if(x): body } (x: Option[T]) = | |
| if(x.hasValue): | |
| var x = x.value | |
| block: body | |
| # Thus achieving both achiving both convenient syntax and perfect generated code | |
| # Other similar clever tricks are possible with "symbol attached user properties" to implement the type state logic | |
| # And finally, Option[T] is a meta-type (type describing additional properties of another type) | |
| # using meta types is good because they encode the intention of the library writter and allow | |
| # algorithms similar to the above to be executed over the program as a whole. |
Author
Ok, fair enough. ;-)
However, the HLO can also easily deal with
if exists(key):
var value = get(key)
Author
For completeness, here is the other approach of optimizing Option[T] using "attached symbol properties" (cookies):
The if statement involving Option[T] is transformed to:
if x.hasValue:
addScopedSymProp(x, "ProvenToHaveValue", true)
bodythen the proxy macro code in Option[T] detects the ProvenToHaveValue "cookie" and generates code without checks
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The pattern here is intentionally simplified. In reality, it has to check that the matched symbol is a local variable of type Option[T]. Since, inside the if, it has been proven that the option[T] has value, the goal of the transformation is to hide the Option[T] variable and replace it with the actual value in the inner scope (the body of the if). Thus you don't pay for any further "is valid" checks inside the if.
Certainly, there exists cases for which Option[T] is overkill and sensible return value can be used instead (this spares the need for if on the result for users), but there are many problem domains in which sensible default just doesn't exist.
Also, there are many data structures for which the pattern:
will perform two expensive searches rather than just one as it is in:
Finally, the safe navigation feature is handled rather nicely with option[T] and there is no good alternative for that. (even if special syntax like foo?.bar.baz? is introduced, it still have to match agains some specific types - Option[T] is a good alternative to nullable pointer types, because its behaves better with stack value semantics)
Someone will implement the Option[T] type anyway, my suggestion is that it's better if the most popular implementation is in the standard library