https://kotlinlang.org logo
d

dave08

04/08/2021, 10:09 AM
Is this the best way to return
true
only if all functions return
true
? (without putting them all on the same line... there's some code in between them)
Copy code
var success = func1()
success = success && func2()
success = success && func3()

return success
b

Big Chungus

04/08/2021, 10:11 AM
Why not just chain them? return func1() && func2() && func3()
d

dave08

04/08/2021, 10:12 AM
I added a comment to the question that there's code in between them, and sometimes conditionals, etc...
I was expecting a
=&&
... but there isn't any.
b

Big Chungus

04/08/2021, 10:13 AM
Ah, right. Then this seems to be optimal. Alternatively you could terminate early with false value and only return true if you reach the end
d

dave08

04/08/2021, 10:15 AM
Yeah, but I do need the function to complete in this case. But true, that is another option in some cases. But I'd have to do something like
func1().takeUnless { it } ?: return false
😛
m

Michael Böiers

04/08/2021, 11:12 AM
Performance-wise, the code seems optimal. But it doesn’t look nice. This might be an alternative, but at the expense of creating a list. It also would be better if the allTrue() was already there in the standard library 🙂
Copy code
fun List<Boolean>.allTrue() = all { it }

fun foo() = true
fun bar() = false
fun baz() = true

val results = mutableListOf<Boolean>()

results += foo()

results += bar()

results += baz()

val endResult = results.allTrue()
d

dave08

04/08/2021, 11:20 AM
Actually that gave me an idea 🙂, a pity that value classes can't use vars though...
Copy code
class CompoundSuccessResult(var result: Boolean) {
		operator fun plusAssign(other: Boolean) { result = result && other }
	}
	
	fun Boolean.toCompoundSuccess() = CompoundSuccessResult(this)
Then:
Copy code
val results = foo().toCompoundSuccess()
results += bar()
results += baz()

return results.result
m

Michael Böiers

04/08/2021, 12:19 PM
I had the same idea, but let’s just assume the starting value as true:
Copy code
class Results {
    var allOk: Boolean = true
        private set

    operator fun plusAssign(execution: Boolean) {
        allOk = allOk && execution
    }
}

fun foo() = true
fun bar() = false
fun baz() = true

val results = Results()

results += foo() 

results += bar()

results += baz()

val endResult = results.allOk
d

dave08

04/08/2021, 12:29 PM
Yeah, that might look better, and the naming is also better 🙂
m

Michael Böiers

04/08/2021, 12:41 PM
Could be done in a more generic way with a list of booleans, so that it could offer some useful evaluations like allTrue, anyTrue, allFalse, anyFalse, allTrueButOne etc..
r

Roukanken

04/08/2021, 1:18 PM
imho, in terms of code readability, the best way is to just assign the return values to vals and and them at the end - this way, whoever reads the
return
of the function or
if
that uses em, knows exactly what is required for it to pass/return true eg
Copy code
val isFeature1 = func1()
val isFeature2 = func2()
val isFeature3 = func3()

return isFeature1 && isFeature2 && isFeature3
ofc, this is not optimal in terms of performance, as all would need to be executed everytime and does not work if the function calls are variable amount
d

dave08

04/08/2021, 1:24 PM
Yup, that was my problem... sometimes certain calls won't be made, and then it becomes a mess to put the vars in the beginning and
isFeature.takeUnless { it } ?: true
in that return statement...
m

Michael Böiers

04/08/2021, 1:51 PM
Here’s another solution:
Copy code
class Runner {
    var allOk: Boolean = true
        private set

    fun check(task: () -> Boolean) = also { allOk = allOk && task() } 
}

fun foo() = true
fun bar() = false
fun baz() = true


fun main() {

    val endResult = Runner()
        .also {
            // arbitrary code
        }
        .check { foo() }
        .also {
            // arbitrary code
        }
        .check { bar() }
        .also {
            // arbitrary code
        }
        .check { baz() }
        .also {
            // arbitrary code
        }
        .allOk

}
3 Views