danbee / persephone

macOS MPD client written in Swift.
https://persephone.fm
MIT License
215 stars 18 forks source link

Redux pattern #23

Closed danbee closed 5 years ago

danbee commented 5 years ago

Refactor the app using ReSwift to provide a unidirectional data flow pattern.

danbee commented 5 years ago

@sharplet Regarding the decision to return a new state tree rather than using inout, this is because the state is immutable, therefore each reducer function must return a new state tree with the changes incorporated in it.

https://redux.js.org/faq/immutable-data

sharplet commented 5 years ago

@danbee It’s true that reducers should be totally immutable, but Swift has a feature that JS doesn’t: pervasive value semantics. Take an example struct FooState, and two versions of a reducer updateFoo() — provided the type doesn’t violate value semantics, these are equivalent:

var state = FooState()

// 1) Returning the new state

func updateFoo(_ foo: FooState, action: FooAction) -> FooState

state = updateFoo(state, action: FooAction())

// 2) State passed via `inout`

func updateFoo(_ foo: inout FooState, action: FooAction)

updateFoo(&state, action: FooAction())

Even if the inout version passed the state it received somewhere else (storing it in a global, capturing it by value in a closure), that reference cannot be shared (it will be copied), and thus is “immutable” to any other code that uses it.

I think this is a really fascinating topic, happy to chat with you about it any time!

danbee commented 5 years ago

@sharplet Ah, interesting! So what's the advantage of doing it the inout way as opposed to having the function return new state?

sharplet commented 5 years ago

@danbee One advantage is that it reduces boilerplate, because you no longer have to manually make a copy of the inout value in order to modify it. Another is that it can improve performance be opening up the potential to modify the value in place, or to avoid triggering copy-on-write if the underlying storage of a value is uniquely referenced.