Emerging Technologies Laboratory (ETL) Blog

Mar 10 2011 laufer

Successive Pattern Matching and the Happy Path

Before

Successive (nested) pattern matching with exhaustive matching at each point, 16 LOC in Scala.

    case req @ DELETE(Path(Seg("users" :: name :: "bookmarks" :: uri))) => {
      val uriString = uri mkString "/"
      logger.debug("DELETE /users/%s/bookmarks/%s".format(name, uriString))
      userRepository findByName name match {
        case Some(user) => req match {
    	  case BasicAuth(u, p) if verify(u, p, user) => {
    	    user.bookmarks.remove(uriString) match {
    	      case Some(_) => NoContent
    	      case _ => NotFound
    	    }
    	  }
    	  case _ => NotFound
        }
        case _ => NotFound
      }
    }

After

Successive happy-path style pattern matching with non-exhaustive patterns and MatchError exception handling, 9 LOC in Scala.

    case req @ DELETE(Path(Seg("users" :: name :: "bookmarks" :: uri))) => try {
      val uriString = uri mkString "/"
      logger.debug("DELETE /users/%s/bookmarks/%s".format(name, uriString))
      val Some(user) = userRepository findByName name
      val BasicAuth(u, p) = req
      val true = verify(u, p, user)
      val Some(_) = user.bookmarks.remove(uriString)
      NoContent
    } catch { case _: MatchError => NotFound }

Using for-comprehensions

A similar happy-path style with similar conciseness but without exceptions can be achieved using for-comprehensions with the Option monad. 8 LOC plus 4 LOC abstracted into the custom extractor.

    case req @ DELETE(Path(Seg("users" :: name :: "bookmarks" :: uri))) => {
      val uriString = uri mkString "/"
      logger.debug("DELETE /users/%s/bookmarks/%s" format (name, uriString))
      (for {
        MatchingBasicAuth(_) <- Some(req)
        _ <- repository.removeBookmark(name, uriString)
      } yield NoContent) getOrElse NotFound  
    }

Discussion

  • The nested style is ugly because it is verbose and includes multiple branches with the same result. The happy-path style is much more concise and easy to read.
  • The happy-path style “misuses” exceptions (in this case, MatchError) for non-erroneous control flow. This needs to be weighed against the conciseness and readability gains.
  • Why not an assertion instead of using true as a pattern? Because this is a functional concern, whereas assertions are a testing concern that might be disabled in production use.
  • The for-comprehension style using the Option monad is the most clean and concise. It also integrates beautifully with custom extractors.
  • Other thoughts?

95 notes  /  

By: laufer
  1. quotes-about-life-daily reblogged this from etl-luc-edu
  2. alltoyotalexusparts reblogged this from etl-luc-edu
  3. coupons-for-food reblogged this from etl-luc-edu
  4. best-buy-online-coupon-codes reblogged this from etl-luc-edu
  5. deep-discount-promotional-code reblogged this from etl-luc-edu
  6. deep-discount-promo-code reblogged this from etl-luc-edu
  7. free-printable-coupons-for-groce reblogged this from etl-luc-edu
  8. free-proxy-sites reblogged this from etl-luc-edu
  9. printablecouponsforgroceries reblogged this from etl-luc-edu
  10. printablecouponsforgroceries reblogged this from etl-luc-edu
  11. los-angeles-carpet-cleaning reblogged this from etl-luc-edu
  12. onlinesizzlinghot reblogged this from etl-luc-edu
  13. lanobis reblogged this from etl-luc-edu
  14. etipznet1 reblogged this from etl-luc-edu
  15. air-conditioning-service-miami reblogged this from etl-luc-edu
  16. duct-cleaning-ft-lauderdale reblogged this from etl-luc-edu
  17. air-duct-cleaning-miami reblogged this from etl-luc-edu
  18. discount-coupon-codes-daily reblogged this from etl-luc-edu
  19. luxury-car-rental reblogged this from etl-luc-edu
  20. alkaline-ionizers reblogged this from etl-luc-edu
  21. carpet-cleaning-in-davis reblogged this from etl-luc-edu
  22. carpet-cleaning-sacramento reblogged this from etl-luc-edu
  23. 24-hour-locksmith-service reblogged this from etl-luc-edu
  24. air-duct-cleaning reblogged this from etl-luc-edu
  25. alkaline-water-ionizers reblogged this from etl-luc-edu
  26. luckyladycharm reblogged this from etl-luc-edu
  27. luckyladycharm reblogged this from etl-luc-edu
  28. find-a-financial-advisor reblogged this from etl-luc-edu
  29. free-poker-money-1 reblogged this from etl-luc-edu
  30. novolinegames reblogged this from etl-luc-edu
  31. grout-stain reblogged this from etl-luc-edu
  32. how-to-text--a-girl reblogged this from etl-luc-edu
  33. penge-finansforum reblogged this from etl-luc-edu
  34. pengar-direkt reblogged this from etl-luc-edu
  35. tjen-penger-online reblogged this from etl-luc-edu
Page 1 of 1