From b8136ad5b2d9950006e4a440e4a73bbbec553169 Mon Sep 17 00:00:00 2001 From: pavelpavlov Date: Thu, 23 Aug 2012 20:31:30 +0400 Subject: pull request feedback Added note about role of `fallback_pf` in the implementation --- src/library/scala/PartialFunction.scala | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src/library') 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]) -- cgit v1.2.3