I love this, what do you think? :slightly_smiling_...
# stdlib
m
I love this, what do you think? 🙂
Copy code
inline fun <R> Boolean.thenTake(action: () -> R) =
    if (this) action() else null

val result = if (input) something() else null
->
val result = input.thenTake { something() }
g
I don’t like it because it completely non obvious that
then
returns
null
also if tomorrow someone decide to add default value you will get:
Copy code
val result = input.then { something() } ?: someDefault
Which is ridiculous replacement for if/else
m
What about a better name then?
mapTrueElseNull
?
I use it for making this more readable:
Copy code
override fun visitExtensions(type: KmExtensionType) =
		(type == JvmConstructorExtensionVisitor.TYPE).then {
			object : JvmConstructorExtensionVisitor() {

				override fun visit(desc: JvmMethodSignature?) {
					jvmSignature = desc
				}
			}
		}


	override fun visitExtensions(type: KmExtensionType) =
		if (type == JvmConstructorExtensionVisitor.TYPE) {
			object : JvmConstructorExtensionVisitor() {

				override fun visit(desc: JvmMethodSignature?) {
					jvmSignature = desc
				}
			}
		}
		else
			null
g
if you add to else
{}
second version is more readable for me
also I would rewreite it like this:
Copy code
override fun visitExtensions(type: KmExtensionType): JvmConstructorExtensionVisitor {
        if (type != JvmConstructorExtensionVisitor.TYPE) ?: return null
        return object : JvmConstructorExtensionVisitor() {
                override fun visit(desc: JvmMethodSignature?) {
                    jvmSignature = desc
                }
            }
}
e
something().takeIf{ input }
m
That's doing something different @elect
It always executes
something()
e
uh, right
m
@gildor I don't like that version because it gives up bodyless approach, requires me to invert the condition, add two returns and you have to state the return type.
g
anyway, IMO in this case
else
is the best
m
@elect but I can borrow the name here!
boolValue.thenTake { … }
which is basically the reverse of
{ … }.takeIf(boolValue)
except it's not evaluated unless
boolValue
is
true
m
R should be non-nullable:
inline fun <R : Any> Boolean.thenTake
Otherwise
?:
may lead to puzzlers.
m
hmm, isn't the same true then for the existing
.takeIf()
? Also allows
null
.
m
I think
takeIf
shouldn't allow nullable receiver. This makes
?:
ambiguous.
m
I think that's not a big problem and a rare case where you actually want to distinguish between the two cases. This would also affect a lot other functions like
let
for example.
Swift is a little different here as it would return a double optional in such cases, unless you
flatMap
the double-optional into one.
But that quickly adds overhead
m
functions like
let
let
has nothing to do with nullability.
m
mayBeNull.let { mayReturnNull() }
<- no distinguishing between which one is
null
mayBeNull.takeIf { false }
<- same Where is the difference when it comes to the nullable receiver problem you mention?
m
let
is not about nullability.
takeIf
is.
m
I'd say in both cases it depends on context and intention
a
I don't think the following should be in stdlib but what about
compute {something()} forCondition isReady
where compute is a function that takes in a lambda that returns an object with a forCondition infix method
m
Unreadable. And cannot be inline.
m
It pushes the important info to the end and causes an unnatural flow. Do all this. And that. Some more. Maybe a dozen more lines. And some database queries. . . . . Oh and BTW, do all of that above only if the following condition is met:... But +1 for creativity 👍
a
I prefer a simple if else. When is also an option
👍 1