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

ursus

03/10/2020, 3:22 AM
tbh thats some BS code -- all the nested copying, or returning identity in map. I must be missing something. So I was wondering, is kotlin missing some sugar for this, or are immutable models at UI level irrelevant if we can enforce only main thread can touch them? Or maybe I think I've read redux/react people denormalize their states?
1
a

Adam Powell

03/10/2020, 3:28 AM
Yep, the team has been thinking about this. 🙂 I'm curious if you've checked out Arrow's optics/lenses feature in this regard, it seems to address a similar problem space
1
u

ursus

03/10/2020, 3:38 AM
Not yet, I'll take a look thanks!
nice -- javascript guys really have this 'client' thing figured out already
😄 1
btw what do you think about this? https://redux.js.org/recipes/structuring-reducers/normalizing-state-shape/ . To me it feels like the same crime as sql table denormalization
a

Adam Powell

03/10/2020, 1:43 PM
I think it can be a source of complexity
Compose takes more inspiration from mobx than redux in many ways
c

codeslubber

03/12/2020, 2:40 AM
Redux I guess by JS standards has had some staying power but even Dan Abrams is off that train, and its spawned a lot of stupid stuff, I do love the immutable model thinking but let’s get real, the book Purely Functional Data Structures is what > 20 years old?
will have to lookup mobx
u

ursus

03/14/2020, 12:31 AM
@codeslubber Im not familiar with that book, what are you getting at?
c

codeslubber

03/14/2020, 12:53 AM
The idea of immutable data models is a couple decades old. You can find that book online for free. I bought the kindle version.
u

ursus

03/15/2020, 2:24 PM
Right but what about it has not kept up?
c

codeslubber

03/15/2020, 4:02 PM
What about what has not kept up? I agree with your original sentiment on this thread, that people adopt elm/redux approaches and then end up with a lot of epicycle nonsense in their code. I am just saying attempts to do immutable models go back decades, and some are more serious than the latest half-baked JS idea…
u

ursus

03/15/2020, 4:21 PM
right, and I mostly understood the immutability as protection against multithreaded mutation, but since all UI frameworks require main thread, isnt it a moot point?
a

Adam Powell

03/15/2020, 4:34 PM
not really. any time you store a reference to data, if something can mutate it before you access it again the usual issues arise. Any sort of async/concurrent/reentrant situations can bring you there, none of which require multithreading to encounter.
1
u

ursus

03/15/2020, 4:45 PM
On that topic: say one would need to synchronize new database data with a current view model State (so current State is needed, its not just a one way T -> R mapping). Would you a) switch the db data to main thread, and do synchronization with State on main thread (and hope it wont take long) b) keep it on the db thread, and read the current State there, and do synchronization still on the db/off thread
a potentially blocks the main thread, b potentially syncs with stale data, since during the sync somebody might change the State synchronously (whereas this synch change would be enqueued after the synchronization if it were all on main thread only) (c) synchronize mutex access to the State
example
Copy code
ViewModel {
	
	var state: State

	init {
		db.foosObservable()
			.map { foos -> foos.map { Item(it.title, expandedOrCollapsed = false) }}
			.subscribe {
				sync(state.items, it)
			}
	}

	private fun sync(currentItems: List<Item>, newItems: List<Item>) {
		// update the titles, but preserve the expandedOrCollapsed of current items
	}

	data class State(val items: List<Item>)

	data class Item(val title: String, val expandedOrCollapsed: Boolean)
}
tldr; db has observable, but you want to preserve the viewmodel level data (expandedOrCollapsed -- which command if a recycler view item is expanded or collapsed), not just apriori overwrite it. should the
sync
happen on main or offthread?
c

codeslubber

03/15/2020, 5:34 PM
Yeah threading is a symptomatic additional branch of this, but the main reason for these models is that just overwriting model data anonymously invites a pirate culture where no one really knows how or why things are in the state they are.
a

Adam Powell

03/15/2020, 5:37 PM
Basically this. ☝️ Mutation access control and ensuring consistency of reads for complex object graphs are two different concerns. Compose's frames system (
@Model
and
MutableState<T>
) help with the latter but you're still responsible for the former.
Standard kotlin language mechanisms can address it though
u

ursus

03/15/2020, 5:40 PM
Yea I sort of "forgot" you can mutate the returned object across interface boundaries, since Im so used to the immutables. Ignore me
a

Adam Powell

03/15/2020, 5:40 PM
so in the case of a background data sync, if you open a frame (currently kind of cumbersome; nicer scoped api for this coming) it's a transaction that will either commit or fail. If it fails due to conflicts you can try the sync again against the updated data. If a composition is in progress looking at slightly stale data that's ok, since it will be updated as soon as the sync completes and it's looking at consistently stale data, not half-updated objects.
This is part of why redux trees get so much fun to manage. Frames keep all of the framed objects in your process consistent within a single snapshot without having to create a big object tree/graph out of them with a single atomic reference to it that changes when any part of the tree changes.
1
2 Views