summaryrefslogtreecommitdiff
path: root/src/library/scala/PartialFunction.scala
diff options
context:
space:
mode:
authorpavelpavlov <pavel.e.pavlov@gmail.com>2012-08-23 20:31:30 +0400
committerpavelpavlov <pavel.e.pavlov@gmail.com>2012-08-23 20:49:16 +0400
commitb8136ad5b2d9950006e4a440e4a73bbbec553169 (patch)
treec2d60d3e9855389668e0f3720b9fe4f922fc52a9 /src/library/scala/PartialFunction.scala
parent42c6fb8ce814ed109f6418bcc5809d23e1db1965 (diff)
downloadscala-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/scala/PartialFunction.scala')
-rw-r--r--src/library/scala/PartialFunction.scala21
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])