Simplify API to no longer expose internal Option #106
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Motivation: Clump in general does a very good job of hiding its implementation details. For example, it's not required to know about
ClumpFlatMap
,ClumpOrElse
, etc. to use the API. However, I feel like there's one place where this abstraction leaks: namely that values not returned by sources are internally stored as anOption
.This presents a major problem when working with
Clump[Option[T]]
because several APIs are overloaded and takeOption
to mean the underlying implementationOption
and not the user facingOption
.Here's some examples of real problems we've had with this:
1: It leads to surprising types.
2: It requires awkward constructions to work with
Clump[Option[T]]
.3: It can cause very subtle exceptions that are hard to find.
Solution: The solution is to remove any reference to the inner
Option
from the outer API. This includes removing any methods which were overloaded to accept bothT
andOption[T]
.Here's how using the API would change:
Clump[T]
Clump.value(None)
Clump.empty
Clump[Int]
Clump.value(Some(3))
Clump.value(3)
Clump.value(3)
already worked so you were probably using that anywayClump[Option[Int]]
Clump.value(Some(None))
Clump.value(None)
Clump[Int]
Clump.future(Future(Some(3)))
Clump.future(Future(3))
Clump.future(Future(3))
already workedClump[Option[Int]]
Clump.future(Future(Some(None)))
Clump.future(Future(None))
Clump[T]
Clump.fallback(None)
Clump.fallbackTo(Clump.empty)
fallback
becomesfallbackTo
Clump[Int]
Clump.fallback(Some(3))
Clump.fallback(3)
Clump[T]
Clump.handle { case _ => None }
Clump.rescue { case _ => Clump.empty }
handle
has to becomerescue
Clump[Int]
Clump.handle { case _ => Some(3) }
Clump.handle { case _ => 3 }
Benefits:
ClassTag
hack to overload methods withOption[T]
andT
versions (1)Some(None)
no longer needed(1) This is not technically true,
orElse
is still overloaded to accept bothT
andClump[T]
. To fix this, we'd have to come up with a different name for one of the methods. PerhapsorDefault
?