https://kotlinlang.org logo
#announcements
Title
# announcements
j

jmfayard

11/05/2019, 10:43 AM
I have colleagues that use
.let { ... }
all the time and don't really understand the need for the others. I know there are multiple articles on when to use
let, also, with, apply, run, takeIf, ...
But which one did you find the most useful?
s

Stephan Schroeder

11/05/2019, 10:50 AM
each of them have different use cases. This video is a good introduction:

https://www.youtube.com/watch?v=YxOTU9F_YX4&t=1262

Personally, I started of using
let
a lot but by now it’s (in order of use) mostly:
apply
,
let
and
also
. I’m not sure
takeIf
belongs with the others though 🤔
m

maxmello

11/05/2019, 10:52 AM
For me, it often comes down to avoiding variable declaration, so I mostly use let, also (side effects) and apply (additional operations on created object that are not part of constructor).
j

jmfayard

11/05/2019, 10:54 AM
Shameless plug: one great use case for with is to extract constants in an object
with(ConfigObject) { ... }
https://pl.kotl.in/4I3H2kfPt https://dev.to/jmfayard/with-configobject-language-kotlin-issparkingjoy-ic4
@Stephan Schroeder to be honest I have never understood the use case for takeIf
s

Stephan Schroeder

11/05/2019, 11:20 AM
I can relate,
takeIf
seems a bit indulgent (/code golfing) to me https://medium.com/@elye.project/using-kotlin-takeif-or-takeunless-c9eeb7099c22
👍 1
j

jmfayard

11/05/2019, 11:31 AM
Oh really nice. My TLDR is that it make sense if you use the object in the conditionnal and you do a quick return after it.
?: error("Error")
or
?: return false
v

Vishnu Haridas

11/05/2019, 11:33 AM
I always use
?.let { ... }
to perform something when the receiver is not null. Example,
Copy code
val response = getResponse(url)
response?.data?.userId?.let { 
    PreferenceHelper.userId = it
}
s

streetsofboston

11/05/2019, 12:11 PM
Maybe you'll like my article 😀 “Let’s also apply a run with Kotlin on our minds” by Anton Spaans https://link.medium.com/wRHcV8OQm1
🎉 1
s

Stephan Schroeder

11/05/2019, 12:55 PM
@Vishnu Haridas that looks more like a sideeffect to me (you don’t use the return-value of let), so
also
would be more idiomatic:
Copy code
val response = getResponse(url)
response?.data?.userId?.also { 
    PreferenceHelper.userId = it
}
On the other hand assuming that
PreferenceHelper.userId
is
null
before you set it and therefore nullable, why not use a simple assignment?!
Copy code
PreferenceHelper.userId = response?.data?.userId
👍 1
v

Vishnu Haridas

11/05/2019, 1:02 PM
@Stephan Schroeder Oops! 🤦 My actual intent was to have a block of code (obviously with more lines of code) run only when the
userId
is not null. Anyway, curious to know why you said
.also
is more idiomatic than
.let
🤔
s

Stephan Schroeder

11/05/2019, 1:07 PM
because
let
returns the last expression it computes, which can mess up your code, if that’s not what you’re intending (because
if-else
is also an expression and suddenly starts complaining that you need an
else
as well). So if you’re not using the value returned by
let
, it’s better to use
also
(which returns
Unit
and is therefore safe(r)). I see
let
mostly as the “single value version of `map`“.
✔️ 1
m

maxmello

11/05/2019, 2:13 PM
@Stephan Schroeder Small correction, “also” returns the value it is called on, not Unit. Which is still safer than let, as you still produce no unintended effects by calling it to the surrounding code.
👍 1
j

jmfayard

11/05/2019, 2:15 PM
I like what
T.run { ... }
does differently than
T.let { ... }
but I don't like its name. I don't find it clear at all. Anybody has a better name?
l

louiscad

11/06/2019, 1:27 PM
In order, I like
also
,
with
,
let
and
apply
.
g

gildor

11/06/2019, 4:09 PM
Almost never use
with
, only when want to use member extension function Also think that local variable and if check is better than let for null check. A lot more explicit and more readable
Use also and apply for object configuration
run
as analogue of
map
, convert one type to another (or let, depends on use case) takeIf is quite different than other scope funxtiobs, but like to use it in some cases where I want to validate object (often use for files or strings)
l

louiscad

11/06/2019, 4:12 PM
After saying my message above, I just used
takeIf
😅
j

jmfayard

11/06/2019, 4:13 PM
T.run
as analogue of
map
... yes but I don't find the name
run
clear at all that it is doing this I would use it more if it had a better name Not that I have a better suggestion mind you.
m

maxmello

11/06/2019, 10:04 PM
Maybe mapSingle then? But to be consistent with the it vs this, let would have to be named that way.
j

jmfayard

11/07/2019, 3:33 AM
@Wiebe Elsinga Why not
T.mapIt { }
(copy of let) and
T.mapThis { }
(copy of run) ?
g

gildor

11/07/2019, 5:23 AM
It and this version are really strange. Also it's not like map, it also changes receiver scope
let is closer to map than run
j

jmfayard

11/07/2019, 7:35 AM
Really? My mental model was -
<T>.let
is map for a single value called
it
-
<T>.run { .. }
(not
run { ... }
) is like
let
but instead of the single value being
it
, it is
this
g

gildor

11/07/2019, 11:17 PM
I mean signature of let is closer to map, as you said both have receiver as argument
j

jmfayard

11/08/2019, 8:06 AM
that's correct yes
3 Views