-1

This is a follow-up to my previous question.

I would like to write a non-recursive retry function using the signature from the reply. Note that this implementation uses view as a lazy sequence.

def withRetries[T](retries: Short)(fun: => T): Try[T] = {
    (0 until retries).view.map(_ => Try(fun)).partition(_.isFailure) match {
        case (a, b) if b.isEmpty => a.last
        case (_, b) => b.head
    }
}

Does it make sense ? How would you improve it ?

Michael
  • 41,026
  • 70
  • 193
  • 341
  • 4
    What's the point of making it non-recursive? Is it just a brain teaser, like swapping two ints without using a temporary variable? This is not a good implenentation, because it will run `fun` N times, even if every one of them succeeds. – Dima Jan 29 '18 at 11:21
  • Also you may have to use mutable variable to keep track of past result and stuff. – Nagarjuna Pamu Jan 29 '18 at 11:23
  • @pamu I don't want to use mutable state. – Michael Jan 29 '18 at 11:27
  • Michael, but what's exactly wrong with recursion especially given Scala has @tailrec annotation? – SergGr Jan 29 '18 at 11:28
  • @Dima Thanks. You are right. The implementation is not good. It does not run `fun` N times if every run succeeds but it runs it _twice_. Need to fix it. – Michael Jan 29 '18 at 11:31
  • Yeah, twice indeed. I still don't get it what is the point of his exercise. – Dima Jan 29 '18 at 11:50

2 Answers2

1

This does what you are asking ... but for the life of me I can't begin to imagine why you would want that ...

 def withRetries[T](retries: Int)(fun: => T) = (1 to retries)
   .foldLeft[Try[T]](Failure(new Exception)) {
     case (x@Success(_), _) => x
     case _ => Try(fun)
   }
Dima
  • 39,570
  • 6
  • 44
  • 70
0

The view-based solution is poor since it executes fun twice even the first run succeeds. My new solution is:

def withRetries[T](retries: Short)(fun: => T): Try[T] = {
    val stream = (0 until retries).toStream.map(_ => Try(fun))
    stream.find(_.isSuccess) getOrElse stream.last
}

The code looks nice but I believe its performance is poor because of Stream.
On the other hand if the number of retries is small and fun is time consuming the Stream performance does not matter that much.

Michael
  • 41,026
  • 70
  • 193
  • 341