In the code snippet included below, I have a recursive function call, used to facilitate a retry if a network call fails (Amazon SimpleDB will occasionally return a 503 and require retry.)
When I try to compile, the Scala complains recursive method simpledb_update needs result type
.
// sends data to SimpleDB. Retries if necessary def simpledb_update(name: String, metadata: Map[String,String], attempt: Int) = { try { db(config("simpledb_db")) += (name, metadata) } catch { case e => // if it fails, try again up to 5 times if(attempt < 6) { Thread.sleep(500) simpledb_update(name, metadata, attempt + 1) } else AUlog(name + ": SimpleDB Failed") } }
Why is this required on recursive functions? My thought is to just return a true/false boolean to satisfy the compiler... the following compiles fine.
// sends data to SimpleDB. Retries if necessary def simpledb_update(name: String, metadata: Map[String,String], attempt: Int): Boolean = { try { db(config("simpledb_db")) += (name, metadata) true } catch { case e => // if it fails, try again up to 5 times if(attempt < 6) { Thread.sleep(500) simpledb_update(name, metadata, attempt + 1) } else AUlog(name + ": SimpleDB Failed") false } }
All functions - recursive or not - have one or more return . The return may or may not include a value. It is for you to decide when you write the function. All explicit written return statements must return the correct type.
With recursion, we are waiting for return values coming from other execution contexts. These other contexts are higher up the stack. When the last item on the stack finishes execution, that context generates a return value. This return value gets passed down as a return value from the recursive case to the next item.
Explanation: A recursive function needn't have a return value.
"Recursion is avoided generally because it makes the code less readable and harder to maintain and debug" - This seems a rather rough generalisation. With some mathematical background, recursive solutions can be pretty readable.
As I understand it, recursive functions need a return type because the type inference algorithm is not powerful enough to determine return types for all recursive functions.
However, you don't need to make up a return type, you just need to declare the return type you were already using: Unit. Unit is a special type with only one element (). It's also the type of most "statements" in Scala, and is the return type to declare for methods that don't need to return anything, but are executed only for their side-effects (as yours is). You can either declare your method as returning unit as you would other types
def simpledb_update(name: String, metadata: Map[String,String], attempt: Int):Unit = {
More idiomatically Scala provides a special syntax for Unit-returning methods, just leave off the return type and the equals sign
def simpledb_update(name: String, metadata: Map[String,String], attempt: Int){
According to scala style guide you should prefer to use equal sign
http://docs.scala-lang.org/style/declarations.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With