News for hackers. Stuff that matters.
Re:How UI-driven state increases accidental complexity by wruza on Wednesday March 25, 2020 @03:49AM (#22682725)
Controller. You need a controller. Or a smart model, in this simple case.

That’s what react/redux has done to you, selling this ‘immutable functional’ flavoured thing. While it is immutable at the programming surface, it is actually a series of complex updates with little to no help from the ‘store’ for convenient access. In pure js, when you want project.tasks, you just:

  class Project {
    get tasks() {
      return db.tasks.filter(x => x.project_id == this.id && !x.deleted)
    }
  }

  class Task {
    get project() {
      return db.projects.find(x => x.id == this.project_id)
    }
    del() {this.deleted=true}
  }

  db.tasks = [].map(Task)
  db.projects = [].map(Project)

  ... in a view:
  h(button, {bind:[cr, 'add_task']}, '+')
  cr.project.tasks.map(task =>
    ...
    h(check, {bind:[task, 'done']})
    h(button, {bind:[task, 'del']}, 'x')

  ... in a controller:
  add_task(project) {
    db.tasks.push(new Task({project}))
  }
In “immutable functional state transformer based on async-dispatched store”, which these re-whatever buzzwords are, you cannot have neither smart data items, nor a good controller that could join unrelated objects together, nor recombinable data sources, nor nice testable api boundaries. And when someone whispers MVC, you think about web 1.0 patterns, with it’s “MC in MVC is backend roundtrip” meaning.

This particular example is a set of five dead-simple classes (DB, Project, Task, TaskListController and TaskListView), almost all orthogonal and useful/testable on their own. Easy for imperative thinking and managing^, cause UI is suddenly imperative. You constantly battle with immutability, lack of control, state copy-transfer and tons of boilerplate for a simple action, can’t you see? You’re doing a monad bind operation by hand, because there is no do-notation in your language, and where there is, it exists and is called “do” for a reason. How did they miss that completely? /rant

^ e.g. want to see deleted tasks? Write a getter in a controller or a db (depending on locality requirements) and use it in a view as if it was a pojo array. Reimplement on demand to leave your tests and logic intact.

Re:How UI-driven state increases accidental complexity by dgb23 on Wednesday March 25, 2020 @07:02AM (#22683454)
You may want to have a look at how re-frame[0] (ClojureScript) does this or redux-toolkit[1]. The issues you mention are discussed there and solved well.

There is a controller in the sense you are describing, but the reads and writes are clearly decoupled as separate, functional steps, while the data is just a plain composition of maps and lists.

Putting these operations into classes is a regression from this point of view. You suddenly get these artificial objects (models) that get harder to extend, reuse and change, because you have relations between objects that you somehow need to model and synchronize as well.

Imagine if databases worked this way. Gladly they don't. They have a uniform, declarative language that you use to interact with them and the data is just data, no matter if it is a Person, Cat or w/e.

So in a sense these libraries are re-inventing databases to handle GUI state in the browser, which is a good thing.

[0] https://github.com/Day8/re-frame

[1] https://redux-toolkit.js.org/

Re:How UI-driven state increases accidental complexity by nyanpasu64 on Wednesday March 25, 2020 @09:08AM (#22684146)
Immutable data makes updates hard and undo easy. It's especially painful in C++.

Mutable data makes mutation easy and undo hard.

I don't know if there's a good solution. The command pattern is based off mutable data, and works, but has lots of boilerplate and implementation (to mutate the document forwards and backwards).

Re:How UI-driven state increases accidental complexity by jamil7 on Wednesday March 25, 2020 @07:19AM (#22683552)
Isn't this what selectors are for?
Re:How UI-driven state increases accidental complexity by iaml on Wednesday March 25, 2020 @07:37AM (#22683632)
It is, gp is talking about the tech they don’t grok.
Re:How UI-driven state increases accidental complexity by wruza on Thursday March 26, 2020 @01:30PM (#22695853)
Maybe.

I don’t grok how one can write 100+ ceremony loc to filter a todo by a “.completed” flag and still think it is okay to burn a barrel of cash and half a day to implement that [1]. I also don’t grok how this approach can work any “faster“ or battery/memory-saving or be used sanely in apps slightly bigger than my generic todolist. It is both millions of dollars of bootstraps, boilerplates and learning curves for what supposed to be a simple logic.

Maybe I’m wrong, but it feels almost like a conspiracy to justify 6.5-figure contracts and nothing more. And the rest of developers just rationalizing around this phenomenon.

[1] https://redux.js.org/recipes/computing-derived-data