3

I'm fairly new to scala from java and also pretty new to pattern matching. One of the things I'm trying to get my head around is when to use it and what it's costs/benefits are. For example this

def myThing(a: Int): Int = a match {
  case a: Int if a > 0 => a
  case _ => myThing(a + 1)
}

Does the same thing as this (unless I've really misunderstood something)

def myThing(a: Int): Int = {
  if (a > 0) a
  else myThing(a + 1)
}

So my actual question: But do they run the same way? Is my pattern matched example tail recursive? And if not, then why not when it is in the second example?

Are there any other things I should worry about, like resources? Or should I pretty much always try to use pattern matching?

I've searched around for these answers but haven't found any "best practices" for this!

Edit: I'm aware that the example used is a bit contrived - I've just added it to be clear about the question below it - thanks!

Hamish
  • 1,015
  • 9
  • 20

3 Answers3

6

Yes they do run the same. Best practice for every syntactic sugar is the same: use it whenever it provides more readable or flexible code. In your examples in case of if statement you may omit braces and write just

def myThing(a: Int): Int =  if (a > 0) a else myThing(a + 1)

Which is definitely more handy than pattern matching. Pattern matching is handy in situations where:

Also to ensure you function is tail-recursive you could use the @tailrec annotation

Community
  • 1
  • 1
Odomontois
  • 15,918
  • 2
  • 36
  • 71
2

Another 'Scala' way to do it would be to define an extractor for a positive number

  def myThing(a: Int): Int = a match {
    case PositiveNum(positive) => positive
    case negative => myThing(negative + 1)
  }


  object PositiveNum {
    def unapply(n: Int): Option[Int] = if (n > 0) Some(n) else None
  }
Maxim
  • 7,268
  • 1
  • 32
  • 44
1

Yet another way to pattern-match against the evaluated predicate (condition),

def myThing(a: Int): Int = a > 0 match {
  case true => a
  case _    => myThing(a + 1)
}

where matches include no (additional) guards or type declarations.

elm
  • 20,117
  • 14
  • 67
  • 113
  • 1
    It's confusing (at least for me), so what's the benefit to write it like this? – mucaho Apr 19 '15 at 11:59
  • 1
    The best approach is an if-else expression; for pattern matching this proves a bit more concise than the original, no guards, no additional type declarations. – elm Apr 19 '15 at 18:33