diff options
author | pavelpavlov <pavel.e.pavlov@gmail.com> | 2012-08-23 20:31:30 +0400 |
---|---|---|
committer | pavelpavlov <pavel.e.pavlov@gmail.com> | 2012-08-23 20:49:16 +0400 |
commit | b8136ad5b2d9950006e4a440e4a73bbbec553169 (patch) | |
tree | c2d60d3e9855389668e0f3720b9fe4f922fc52a9 /src/library | |
parent | 42c6fb8ce814ed109f6418bcc5809d23e1db1965 (diff) | |
download | scala-b8136ad5b2d9950006e4a440e4a73bbbec553169.tar.gz scala-b8136ad5b2d9950006e4a440e4a73bbbec553169.tar.bz2 scala-b8136ad5b2d9950006e4a440e4a73bbbec553169.zip |
pull request feedback
Added note about role of `fallback_pf` in the implementation
Diffstat (limited to 'src/library')
-rw-r--r-- | src/library/scala/PartialFunction.scala | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/src/library/scala/PartialFunction.scala b/src/library/scala/PartialFunction.scala index 91eae2984a..d0a339bdd5 100644 --- a/src/library/scala/PartialFunction.scala +++ b/src/library/scala/PartialFunction.scala @@ -186,6 +186,27 @@ object PartialFunction { } } + /** To implement patterns like {{{ if(pf isDefinedAt x) f1(pf(x)) else f2(x) }}} efficiently + * the following trick is used: + * + * To avoid double evaluation of pattern matchers & guards `applyOrElse` method is used here + * instead of `isDefinedAt`/`apply` pair. + * + * After call to `applyOrElse` we need both the function result it returned and + * the fact if the function's argument was contained in its domain. The only degree of freedom we have here + * to achieve this goal is tweaking with the continuation argument (`default`) of `applyOrElse` method. + * The obvious way is to throw an exception from `default` function and to catch it after + * calling `applyOrElse` but I consider this somewhat inefficient. + * + * I know only one way how you can do this task efficiently: `default` function should return unique marker object + * which never may be returned by any other (regular/partial) function. This way after calling `applyOrElse` you need + * just one reference comparison to distinguish if `pf isDefined x` or not. + * + * This correctly interacts with specialization as return type of `applyOrElse` + * (which is parameterized upper bound) can never be specialized. + * + * Here `fallback_pf` is used as both unique marker object and special fallback function that returns it. + */ private[this] final val fallback_pf: PartialFunction[Any, Any] = { case _ => fallback_pf } @inline private final def checkFallback[B] = fallback_pf.asInstanceOf[PartialFunction[Any, B]] @inline private final def fallbackOccurred[B](x: B) = (fallback_pf eq x.asInstanceOf[AnyRef]) |