https://kotlinlang.org logo
#compose
Title
# compose
z

Zach Klippenstein (he/him) [MOD]

07/28/2020, 9:23 PM
Pulling this out of the thread to avoid derailing it… What does this mean for
savedInstanceState
? Looks like it’s stuck around for now?
l

Leland Richardson [G]

07/28/2020, 9:33 PM
I think this is being discussed. Have any strong feelings yourself?
just a reminder that
state
:
savedInstanceState
::
remember
:
rememberSavedInstanceState
so the most consistent change would be to get rid of it and just have
rememberSavedInstanceState
which perhaps we could/should rename in that case
and the
rememberSavedInstanceState { mutableStateOf(0) }
would get an autosaver that would “just work”
b

brandonmcansh

07/28/2020, 9:37 PM
Makes sense to me
z

Zach Klippenstein (he/him) [MOD]

07/28/2020, 9:39 PM
rememberSavedInstanceState
is a little weird to me conceptually. Why would I care about saving an immutable value? The kdoc explanation about mutable values makes more sense, but for
rememberSavedInstanceState { mutableStateOf(0) }
, you’d need to always wrap your custom
Saver
in one that unwraps/wraps the
MutableState
value, right? That’s a bit awkward.
I think having an overload that specializes the type parameter upper bound to
State
or
MutableState
, and automatically wraps the
Saver
would solve that.
TBH, even
state
seems so common and small that I’m a little disappointed to see it go away, although I completely understand the desire to minimize the amount of magic and the API surface, and this is probably a lot simpler to educate.
3
l

Leland Richardson [G]

07/28/2020, 9:46 PM
i used to hold on to the short/simple/sweet
state
API so strongly that you’d have to pry it from my cold dead fingers
but not so much anymore after having thought about it and sitting with the idea for a while
i’ve seen a lot of people fundamentally misunderstand what the
state
API actually is
👍 3
and
remember
is the real fundamental API that people need to understand
and right now, even if they did understand
remember
, they might miss the fact that
state
is just a convenient call to remember
it makes demos and simple code slides more verbose, but i think in the long run its the right call. it stops conflating state with remember
people missed the fact that
mutableStateOf
can be used outside of composition
👍 1
and also we are seeing patterns emerge where people want to create @Composable convenience factory functions that create an object (maybe using some ambient values) and then remember it, simplifying the usage site
z

Zach Klippenstein (he/him) [MOD]

07/28/2020, 9:49 PM
It’s clever, but “i’ve seen a lot of people fundamentally misunderstand what the state API actually is” sure seems to suggest it’s too clever.
l

Leland Richardson [G]

07/28/2020, 9:49 PM
for instance you could have
@Composable fun SomeClass() = remember { SomeClass(SomeAmbient.current) }
this pattern, i think, is probably bad. but having a reusable convenience method isn’t necessarily bad
I’d like to push the convention of prefixing such methods with
remember
to hammer in the point
so instead,
@Composable fun rememberSomeClass() = …
because the problem is it is too hard to tell at the usage site if this is something you ought to remember or not
and even worse, you can’t do
@Composable fun SomeClass() = SomeClass(SomeAmbient.current)
because in that case, the caller can’t remember the result, because remember lambda blocks can’t have composable calls in them
anyway. it’s a complicated choice, but this is probably the right call i think. perhaps worth a blog post or something describing the decision and the anti-patterns we saw emerge
1
z

Zach Klippenstein (he/him) [MOD]

07/28/2020, 9:55 PM
makes perfect sense. I think it’s easy to over-index on the usefulness of cute little sugary things like this early on that just feel so good when writing samples and stuff, when they don’t actually provide much value in readability in real code and make the mental model you have to acquire so much bigger.
💯 1
l

Leland Richardson [G]

07/28/2020, 9:55 PM
yeah, exactly
i think for a composable function to be understandable, its somewhat important to be able to identify which objects are “remembered” across recompositions and which ones aren’t
2
this convention + API change will help move towards that
👍 1
t

Timo Drick

07/28/2020, 10:14 PM
Just one thought about naming. In Kotlin there is the delegate "lazy" which does more or less the same like remember. So maybe remember should be called lazy? Btw. LazyColumnItems/LazyRowItems are doing different things. So maybe not use Lazy as Prefix for this Recyclerview thing. I think this would make it much easier to understand.
Maybe just ColumnItems/RowItems
l

Leland Richardson [G]

07/28/2020, 10:40 PM
semantically lazy and remember are very different things
i don’t think
lazy
is the right term to use here. i’m actually quite happy with the name of
remember
but maybe others feel differently?
t

Timo Drick

07/28/2020, 11:40 PM
Ok than i still do not understand remember 😄
b

brandonmcansh

07/29/2020, 12:01 AM
Lazy*Items are prefixed that way because of how they handle recomposition wrt visible items
☝️ 1
z

Zach Klippenstein (he/him) [MOD]

07/29/2020, 12:09 AM
remember
initializes the value (invokes the lambda) eagerly/synchronously. The
lazy
delegate doesn’t initialize the value until it’s read (i.e., lazily). Like the
lazy
delegate,
Lazy*Items
doesn’t add its children to the composition until they’re scrolled into view.
👍 1
💯 1
t

Timo Drick

07/29/2020, 12:12 AM
OK yes that makes sense. Thank you for clarifying this.
b

brandonmcansh

07/29/2020, 12:19 AM
Wrt Lazy*Item is it expected behavior for a recomp to not occur until scroll even if its state.value updates?
a

andylamax

07/29/2020, 1:36 AM
Lazy*Items
has been bugging me so much. @Zach Klippenstein (he/him) [MOD]'s explanation has made it so clear to me. Thanks
z

Zach Klippenstein (he/him) [MOD]

07/29/2020, 1:38 AM
RecyclerView
is such a weird name, when you think about it – the main feature of
RecyclerView
is that it’s lazy. The fact that it recycles views is just an optimization to reduce memory usage and allocations. It doesn’t have anything to do with its core functionality. I like the
Lazy*Items
name a lot better, since it highlights the main feature/use case.
l

Leland Richardson [G]

07/29/2020, 1:54 AM
new idea: we just hire @Zach Klippenstein (he/him) [MOD] to write all of our documentation
👏 2
😄 1
z

Zach Klippenstein (he/him) [MOD]

07/29/2020, 1:58 AM

https://media.giphy.com/media/jUwpNzg9IcyrK/giphy.gif

l

Leland Richardson [G]

07/29/2020, 1:59 AM
you can write my slides and give my presentation while you’re at it 😬
a

andylamax

07/29/2020, 2:00 AM
😂😂😂😂😂😂
g

gildor

07/29/2020, 2:54 AM
I think the biggest problem with this, that eventually everyone will have own
state{}
function to get rid of boilerplate
z

Zach Klippenstein (he/him) [MOD]

07/29/2020, 3:13 AM
At least they’ll know how it works though 😅
g

gildor

07/29/2020, 3:16 AM
they will just select
remember { mutableStateOf(…) }
, alt + enter, extract to a function and forget about it next minute (or maybe it will remember only one developer in the project who introduced this extension)
even something like
rememberState { … }
would be probably better
l

Leland Richardson [G]

07/29/2020, 4:27 AM
yeah i think we might consider adding
rememberState
👍 1
we’re trying to be thoughtful here though. its a lot easier for us to add a convenience API later
much harder for us to remove an API, especially one which would see as high of usage as this one would
and it has become pretty clear to us that people are missing the fact that state is a convenience method
and instead thinking its doing some fundamental thing
so they miss the real fundamental APIs, which are
remember
and
mutableStateOf
g

gildor

07/29/2020, 5:44 AM
much harder for us to remove an API
Maybe use OptIn annotation, same as Kotlin stdlib does
a

andylamax

07/29/2020, 5:45 AM
They'll have to OptIn the whole lib then. Coz its experimental it okay if things are shaken here and there until a concrete decision is made
g

gildor

07/29/2020, 5:47 AM
Yes, but this looks as more fundamental decision, not only until Compose dev preview/alpha