Using exceptions as default arguments in Kotlin - function

I'm writing a function in Kotlin to retrieve items of type T from a database.
The user can specify an action to be invoked if no matching results are found, otherwise an IllegalArgumentException is thrown:
fun get(
...,
onNoneFound: () -> T = throw IllegalStateException("No matching results found")
): T {
...
return when (results.size) -> {
0 -> onNoneFound.invoke()
1 -> ...
else -> chooseResult(...)
}
}
The issue I'm having is that whenever the function is invoked, it seems that the IllegalStateException is thrown before the function body is executed.
In a way, that makes sense, and I suppose a workaround could be:
fun get(
...,
onNoneFound: (() -> T)? = null
): T {
...
return when (results.size) -> {
0 -> if (onNoneFound == null) {
throw IllegalArgumentException("No matching results found")
} else {
onNoneFound.invoke()
}
1 -> ...
else -> chooseResult(...)
}
}
I was wondering if there is a more elegant/preferable solution to this problem - ideally where I do not have to make the function nullable and do a null check later. Is there a way of doing this with Kotlin's default argument syntax?
Edit:
It occurred to me that I can use the elvis operator for the null check which does make the code more elegant:
onNoneFound?.invoke() ?: throw IllegalArgumentException("No matching results found")
But I'm still curious if Kotlin has a built-in way of doing this without the null check.

You shouldn't build the exception directly. Try:
fun get(
...,
onNoneFound: () -> T = { throw IllegalStateException("No matching results found") }
): T {
...
return when (results.size) -> {
0 -> onNoneFound.invoke()
1 -> ...
else -> chooseResult(...)
}
}

The problem is that throw IllegalStateException(...) is a perfectly fine expression of type () -> T, just as it is an expression of any other type; but it throws the exception immediately, what you want is a lambda which will throw the exception when invoked. And that's { throw IllegalStateException(...) } in Kotlin, as
Roger Lindsjö's answer says.

Related

Groovy - check if param is a function

In JavaScript, this is how I check if a function parameter is a function:
function foo ( p ) {
if ( typeof p === 'function' ) {
p();
}
// ....
}
How can I do the same in Groovy?
Groovy makes closures a first-class citizen. Each closure extends abstract class groovy.lang.Closure<V> and in case of undefined argument type you can use instanceof to check if parameter that was passed to a method is a closure. Something like that:
def closure = {
println "Hello!"
}
def foo(p) {
if (p instanceof Closure) {
p()
}
}
foo(closure)
Running this script generates output:
Hello!
Using concrete parameter type
Groovy allows you (and it's worth doing actually) to define a type of a method parameter. Instead of checking if p was a closure, you can require that caller passes a closure. Consider following example:
def closure = {
println "Hello!"
}
def foo2(Closure cl) {
cl()
}
foo2(closure)
foo2("I'm not a closure")
First call will do what closure does (prints "Hello!"), but second call will throw an exception:
Hello!
Caught: groovy.lang.MissingMethodException: No signature of method: test.foo2() is applicable for argument types: (java.lang.String) values: [I'm not a closure]
Possible solutions: foo2(groovy.lang.Closure), foo(java.lang.Object), find(), find(groovy.lang.Closure), wait(), run()
groovy.lang.MissingMethodException: No signature of method: test.foo2() is applicable for argument types: (java.lang.String) values: [I'm not a closure]
Possible solutions: foo2(groovy.lang.Closure), foo(java.lang.Object), find(), find(groovy.lang.Closure), wait(), run()
at test.run(test.groovy:18)
It's always a good practice to make your code type-safe, so you don't have to worry if a value passed as a parameter is a type you expect.
In Groovy, you'd want to check if p is an instanceof a Closure
def foo(p) {
if (p instanceof Closure) {
p()
} else {
println "p is $p and not a Closure"
}
}
foo { -> println "I'm a closure" }
foo('tim')
Outputs:
I'm a closure
p is tim and not a Closure
def eval = {o->([o].grep(Closure).find()?:{o})()}
println eval('foo')
println eval({->'bar'})
println eval{'baz'}

How to handle a PSQL exception and return in my JSON action

I have a JSON action that returns a very simple JSON object that looks like:
case class InsertResponse(success: Boolean, message: String)
My action that returns JSON looks like:
def insertUser = Action.async(BodyParsers.parse.json) { request =>
val userReq = request.body.validate[UserRequest]
userReq.fold(
errors => {
Future(Ok(....))
},
userR => {
val insertResultFut =
for {
user <- .......
} yield ....
Ok(insertResponse.toJson)
}
)
}
So I want to catch certain exceptions that the insertResultFut call may throw, as it calls my slick database layer that inserts into the database.
I want to guard against a PSQLException that is thrown if the users email is a duplicate, how can I catch this error with futures?
If there is an exception, and it is a PSQLException for a duplicate key, I want to catch that and also set my InsertResponse success flag to false etc.
Thoughts?
You can use Future#recover for this case:
insertResultFut.recover {
case exe: PSQLException if exe.getMessage.contains("duplicate") => BadRequest(InsertResponse(false, "duplicate").toJson)
}

Batch json strings processing using playframework in Scala

I use API which might either return a single json string, a batch of json strings or the string PROCESSING_TIMEOUT, e.g.:
{"id":123,"field1":"test1"}
or:
{"id":123,"field1":"test1"}
{"id":456,"field2":"test2"}
{"id":789,"field3":"test3"}
or (in case of asynchronous processing timeout in remote API)
PROCESSING_TIMEOUT
In the function getRestContent I want to be able to correcty process all these possible outputs, including also the timeout errors. In the current version of the function I lack the possibility to process batch json strings. I think that the best option would be that the function returns List<JsValue> instead of JsValue.
How can I do this modification using Play Framework.
def getRestContent(url:String,param:String,paramValue:String): JsValue = {
var output : JsValue = null
var httpOutput : String = null
try {
val response: HttpResponse[String] = Http(url).timeout(connTimeoutMs = 10000000, readTimeoutMs = 10000000).param(param,paramValue).asString
httpOutput = response.body
} catch
{
case ex: Exception => {
println("Failed connection with remote API")
}
}
if (!httpOutput.contains("PROCESSING_TIMEOUT") && httpOutput != null)
{
try {
output = Json.parse(httpOutput)
}
catch
{
case ex: Exception => {
println("Failed to process a document")
}
}
}
else
{
println("Asynchronous processing timeout")
}
if (output != null)
{
return output
}
else {
return new JsObject(Map("empty" -> JsNumber(0)))
}
}
Disregarding Play Framework your code is not Scala-flavored in general.
Below is a simple example of how better to approach such task in more Scala-way.
Highlights: use scala.util.Try wrapper to normally work with exceptions in a functional way, use pattern matching and monadic map and other methods of collections.
I hope the code below is self-explanatory. I mimicked the API. It returns Strings and not JSON but your 3 basic cases are sufficiently emulated: single line, multiple lines and exceptional case.
Try to run the program few times and you will see that all 3 cases are handled correctly:
import scala.util.{Failure, Success, Try, Random}
/**
* Created by Alex on 3/10/2016.
*/
object Temp {
case class Item(name:String, value:Int)
object API{
def getTimeOutResponse:String = throw new TimeoutException("no luck this time")
def getSingleLineResponse = "{name: \"Alex\", value: 1}"
def getMultiLineResponse = "{name: \"Alex\", value: 1}\n{name: \"HackerDuck\", value: 2}"
def getRandomResponse = (Math.abs(Random.nextInt() % 3)) match{
case 0 => getTimeOutResponse
case 1 => getSingleLineResponse
case 2 => getMultiLineResponse
}
}
def getResults:List[Item]={
Try(API.getRandomResponse) match{
case Success(s) =>{
s.split("\n").toList.map{item =>
val parts = item.split(", ")
Item(parts(0).replace("{name: ", "").replace("\"", ""), parts(1).replace("value: ", "").replace("}", "").toInt)
}
}
case Failure(_) =>{
println("API timeout happened")
List.empty[Item]
}
}
}
def main(args:Array[String])={
println(getResults)
println(getResults)
println(getResults)
}
}
A sample output from my console:
API timeout happened
List()
List(Item(Alex,1))
List(Item(Alex,1), Item(HackerDuck,2))
Process finished with exit code 0
The code becomes less cluttered without all these if statements and !=null and alike. Also you can streamline conversion of your elements sequence to List in one place.

Can you pass a typed array to a function within an enum in swift?

In a Swift app, I've created an enum with a function that takes an array of CLBeacon objects as it's only argument (i.e., [CLBeacon]). I get no clang errors with the enum, however when I try to use the enum, clang complains that I can't invoke the function with an argument list of ([CLBeacon]). Here's the code:
enum BeaconArrayState {
case NoObjectOnScreen, FirstObjectOnScreen, FirstObjectOffScreen
mutating func check(beacons: [CLBeacon]) -> BeaconArrayState {
switch self {
case FirstObjectOnScreen:
return .FirstObjectOnScreen
case FirstObjectOffScreen:
return .FirstObjectOffScreen
case NoObjectOnScreen:
if beacons.count > 0 {
println("push to screen associated with beacon \(beacons[0].minor)")
}
return .NoObjectOnScreen
}
}
}
var beaconArrayState: BeaconArrayState = .NoObjectOnScreen
func beaconManager(manager: AnyObject!, didRangeBeacons beacons: [AnyObject]!, inRegion region: CLBeaconRegion!) {
let knownBeacons = beacons.filter{$0.proximity != CLProximity.Unknown}
//send updated beacons array to perform parseBeacons
NSNotificationCenter.defaultCenter().postNotificationName("updateNotificationPriorities", object: knownBeacons)
beaconArrayState = BeaconArrayState.check(knownBeacons as [CLBeacon])
}
This gives: the error - Cannot invoke 'check' with argument list of type '([CLBeacon])'
The code in the case statements is irrelevant for now and not yet determined, but why the error on invocation?
The problem with your code is that you are calling check method statically while that function is not static at all. Also check function its not a mutating function so you dont need mutating keyword. To make this work make the follow change beaconArrayState = beaconArrayState.check(knownBeacons as [CLBeacon]) or if you want check method to mutate itself then change it like this :
mutating func check(beacons: [CLBeacon]) {
switch self {
case FirstObjectOnScreen:
self = .NoObjectOnScreen
case FirstObjectOffScreen:
self = .FirstObjectOffScreen
case NoObjectOnScreen:
if beacons.count > 0 {
println("push to screen associated with beacon \(beacons[0].minor)")
}
self = .NoObjectOnScreen
}
}
then just call beaconArrayState.check(knownBeacons as [CLBeacon]) and becaonArrayState will get its new value

Function declaration to return anything, also void?

Is there a way to declare a function such that I don't care about return value? For example I have this Array extension:
extension Array {
func forEach(function: (element: T) -> ()) {
for e in self {
function(element: e)
}
}
}
Now I want to do:
textFields.forEach{$0.resignFirstResponder()}
And I can't because the function is declared to return Void.
This would fix it:
textFields.forEach{$0.resignFirstResponder();return}
But is there a generic way to declare the function such that I can return any value or Void?
Thanks!
If you add a second generic parameter with no constraints, and type the function to return it, then any return value would be accepted:
extension Array {
func forEach<U>(function: (Element) -> U) {
for e in self {
function(e)
}
}
}
func f(i: Int)->Int {
return i * 2
}
func g(i: Int) -> Double {
return Double(0.0)
}
func h(i: Int) {
println("\(i)")
}
let a = [1,2,3]
a.forEach(g) // U will be an Int
a.forEach(f) // U will be a Double
a.forEach(h) // U will be a ()
However, I’d strongly suggest you not do this and use for…in instead.
The only purpose of running a function on an array but not using the return value is for side-effects. When writing in a more imperative style and using side-effects and external state (as opposed to a more declarative functional style) it’s much better to use for…in as a signal that this is what you’re doing.
There are also unpleasant gotchas involved in constructing your own pseudo-control structures. For example, think about this:
// function that does something side-effecty, but
// if it achieves some goal, exist early
func someFunc(a: [Int]) {
a.forEach { i -> () in
// goal achieved early,
// return from func
return
}
assert(false)
}
This is a common practice – cut out of a function early if some goal (or failure) is achieved. But with the forEach structure this is a bit misleading. It looks like a regular loop, but it’s actually a closure, and the return returns from that closure, ready for forEach to call the next one (essentially, it behaves like a continue in a regular loop).
Use map():
let textFields : [UITextField] = [] // or whatever
textFields.map{$0.resignFirstResponder()}
This way you don't have to specify the return type, and you don't need to reinvent map with your forEach extension.