[HN Gopher] UIs are not pure functions of the model (2018)
       ___________________________________________________________________
        
       UIs are not pure functions of the model (2018)
        
       Author : b3morales
       Score  : 81 points
       Date   : 2022-07-04 17:07 UTC (5 hours ago)
        
 (HTM) web link (blog.metaobject.com)
 (TXT) w3m dump (blog.metaobject.com)
        
       | eurasiantiger wrote:
       | Funny, just yesterday I posted an in-depth comment concerning
       | this exact topic.
       | 
       | https://news.ycombinator.com/item?id=31968100
        
       | hitekker wrote:
       | > The idea of UI being a pure function of the model seems so
       | obviously incorrect, and leads to such a plethora of problems,
       | that it is a bit puzzling how one could come up with it in the
       | first place, and certainly how one would stick with it in face of
       | the avalanche of problems that just keeps coming.
       | 
       | Richard Harris takes the same tact. He describes "UIs as a
       | function of state" as an ideology:
       | https://docs.google.com/presentation/d/1PUvpXMBEDS45rd0wHu6t...
       | 
       | I think junior developers tend to invest in a single web
       | framework and let their identities get tied up in the
       | architecture of that framework.
        
       | hombre_fatal wrote:
       | > When I first saw React.js, I had a quick glance and thought
       | that it was cool, they finally figured out how to do a Cocoa-like
       | MVC UI framework in JavaScript.
       | 
       | So smug that it's hard to take seriously.
       | 
       | Especially when even Apple is switching to SwiftUI, something
       | that is the opposite of Cocoa and more similar to React.
       | 
       | Though I wonder how someone with both Cocoa and React experience
       | looks at React and goes "Oh, it's the old-school Cocoa way of
       | doing things!"
       | 
       | This blog post reminds me of HN four years ago when everyone had
       | their little smug epithet about Javascript and web developers,
       | those idiots who are too amateur to see the beauty of Cocoa and
       | winforms or whatever most of us are happy to swap with something
       | better.
        
         | atwood22 wrote:
         | For what it's worth, a lot of developers I know who work on
         | complex iOS applications have more or less abandoned SwiftUI
         | after trying it.
        
           | epicureanideal wrote:
           | Why are they abandoning it? Could you please share reasons in
           | as much detail as possible? Very interested to know.
        
             | ardit33 wrote:
             | It is fine for small toy apps (think the calculator), but
             | it is missing a lot of functionality to build a full
             | fledged app. Think collections, which is the backbone of
             | most apps.
             | 
             | UIKit is very mature and has evolved to a really good UI
             | platform. SwiftUI is not even close to unseat it. Maybe in
             | few years it will mature as well, but for now UIKit is the
             | way to go.
        
               | hbn wrote:
               | I only ever played around with making a toy app while
               | following along with Stanford's Swift UI course[1], and
               | even just the basic things I was doing there, I ran into
               | multiple frustrating/confusing bugs.
               | 
               | As if it wasn't difficult enough to wrap your head around
               | learning it in the first place, running into bugs makes
               | it even harder because you think you're doing something
               | wrong until you finally ask online and get told by people
               | more knowledgeable than you, "I don't know why that's
               | happening, wrap your view in a container and it'll work"
               | 
               | [1] https://youtube.com/playlist?list=PLpGHT1n4-mAsxuRxVP
               | v7kj4-d...
        
               | interactivecode wrote:
               | At Beam[0] we are building a web browser that uses
               | SwiftUI almost everywhere except for the text editor.
               | 
               | So far its been great to build UI and animations with.
               | Each release gives SwiftUI more apis and features, so
               | there are less and less older style apis to wrap in
               | SwiftUI ourselves.
               | 
               | [0] https://hellobeam.com
        
               | kecupochren wrote:
               | Those scroll effects are quite janky on iOS btw
        
           | rudedogg wrote:
           | It takes quite a bit to wrap your head around the SwiftUI way
           | of doing things. I think a lot of people get frustrated and
           | throw in the towel. I'm sure React is the same story.
           | 
           | And while you can't do _everything_ in SwiftUI, it 's pretty
           | solid and capable now. I only have a couple things using
           | AppKit in a large macOS project.
        
         | EGreg wrote:
         | And now four years later they accepted the web developers but
         | now are having smug epithets about Web3 developers, those
         | idiots who are too idealistic to accept the beauty of Web2's
         | centralized model
        
         | kkarimi wrote:
         | Agreed. If it was cocoa Apple wouldn't ditch their old ways to
         | create a clone of react approach
        
         | brundolf wrote:
         | Agree that it's phrased really smugly and that detracts from
         | the message, but important to note it's dated 2018, at which
         | time React was very different than it is today and SwiftUI
         | didn't exist yet
        
           | [deleted]
        
           | adzm wrote:
           | I'd argue that React is pretty much the same now as it always
           | has been. The ecosystem has matured and grown for sure but
           | even the basic API has remained pretty much stable.
        
             | brundolf wrote:
             | Hooks didn't exist yet, for one, as mentioned in the Dan
             | Abramov quote at the bottom:
             | 
             | > we're adding a stateful function API as a preferred
             | alternative to classes soon
             | 
             | Class components were the focus at the time, and are now
             | all-but-deprecated. Also, Redux was still very popular in
             | practice, which it isn't so much now (partly due to hooks)
             | 
             | That's a pretty big change in the way people use React,
             | which certainly informs a discussion like this
        
               | acemarke wrote:
               | I'd have to disagree with this on a couple levels.
               | 
               | Yes, hooks change the way we write React code in some
               | ways, but in a lot of other ways nothing has changed. We
               | still write components that accept props, have state, and
               | return UI descriptions as JSX elements, and those
               | components may cause side effects after a render is
               | completed. Conceptually, the core principles of React are
               | still exactly the same, and hooks didn't change that.
               | 
               | Additionally, Redux is still by far the most widely used
               | state management tool for React apps. My rough estimates
               | are that 45-50% of React apps use Redux, whereas Mobx and
               | XState are around 10-15%.
               | 
               | I'll agree that Redux is not as "popular" as it once was,
               | which is due to a number of factors. It was heavily
               | overused early on, and the ecosystem has expanded to
               | include a lot of other great tools that overlap with some
               | of the use cases for Redux. But, "modern Redux" with
               | Redux Toolkit is much easier to learn and use than the
               | legacy hand-written patterns, and we get highly positive
               | feedback on a daily basis from folks who tell us they
               | enjoy using RTK. (In fact, RTK by itself has more
               | downloads than Mobx, XState, or React Query.) So, that
               | tells me Redux will continue to be widely used for a long
               | time.
        
               | pcthrowaway wrote:
               | > My rough estimates are that 45-50% of React apps use
               | Redux, whereas Mobx and XState are around 10-15%
               | 
               | Curious how you arrive at these estimates? I would have
               | thought fewer than 30% of React apps started in the last
               | year or so use Redux, but of course, many still do,
               | perhaps a higher percentage of apps that were built >2
               | years ago do (you could argue these are more mature, so
               | they've "grown into" redux, though you could also say
               | they're legacy and preceded newer React capabilities and
               | tooling)
               | 
               | I don't have a strong inclination one way or the other,
               | and have been toying with introducing Redux (or some
               | other kind of state management) for the app I work with,
               | but my understanding from the general sentiment of the
               | threads/projects I follow is that market share of Redux
               | has fallen in the last year or 2.
        
               | azemetre wrote:
               | Just looking at download trends redux is literally in a
               | class of its own. What I do wonder is how often people
               | are abusing context, state, and reducers to make their
               | own terrible state managers rather than using redux? I
               | bet that number is higher haha.
               | 
               | https://npmtrends.com/mobx-vs-redux-vs-xstate
        
         | systemvoltage wrote:
         | > Especially when even Apple is switching to SwiftUI, something
         | that is the opposite of Cocoa and more similar to React.
         | 
         | Well, that's hardly a counter argument. The core argument
         | should be whether "SwiftUI is better than Cocoa", and _not_
         | whether a Big Tech company is switching to it unless we are in
         | a popularity contest.
        
         | hgsgm wrote:
         | It's not smug to observe that someone ported MVC to JavaScript.
         | It's a lot of work to build.
        
           | jonkoops wrote:
           | Except it's not MVC.
        
             | pier25 wrote:
             | React would be the V in MVC, no?
             | 
             | I mean, even Vue takes its name from that (pronounced
             | "view").
        
               | lmm wrote:
               | There are no controllers in the react way of doing
               | things, or at least no separation between view and
               | controller if that's your perspective.
        
           | dan-robertson wrote:
           | There were a lot of "MVC in JavaScript" frameworks before
           | react. I don't think that's really a useful description of
           | react or of the work or idea involved.
        
         | mpweiher wrote:
         | You might want to listen to Pete Hunt, one of the creators of
         | react.js:
         | 
         | https://futureofcoding.org/episodes/011
         | 
         | 17:30
         | 
         | "The core idea with react, and this is the only thing that
         | matters, so don't view components as a react innovation.
         | Components have been around forever. You build any sort of
         | native application on Windows or macOS or iOS and there's a
         | notion of component, some call it a view or whatever, but the
         | idea of composing components out of other components has been
         | around since the dawn of time.
         | 
         | I don't know why we weren't doing it on the web. I think we
         | were just, I don't know, being stubborn or something. But
         | that's not a new innovation."
         | 
         | Hmm...sounds just a bit like what they were trying to achieve
         | was something along the lines of "Cocoa for the Web".
         | 
         | But what does he know?
         | 
         | -\\_(tsu)_/-
         | 
         | Anyway, he does go on to say that the core innovation is having
         | the UI be a pure function of some state. But that's the part
         | that isn't actually true. It ain't a pure function. See Dan
         | Abramov's comment:
         | 
         |  _Support for local state and side effects is absolutely a core
         | feature of React components and not something we avoid for
         | "purity"._
         | 
         | So if it's not a "pure function" of the state, then it's some
         | mapping of the state. All UI is some sort of mapping of the
         | state, otherwise it's not really a UI.
         | 
         | Hmm...
         | 
         | So being a "pure function" of the state is not the innovation,
         | because it isn't true, and being some mapping of the state is
         | also not the innovation, because all UI is a mapping of the
         | state.
         | 
         | Hmm...
         | 
         | So what is the _actual_ innovation? It is more or less
         | _directly_ and _visibly_ expressing the UI in code. And since
         | all our languages are essentially procedural (functional, OO)
         | that means expressing the UI as a procedure (function /method).
         | 
         | And so the "pure function of the state" turns out not to be a
         | feature of this model, but a (squishy) requirement. Because in
         | order to make the UI definition a procedure, you have to re-run
         | that procedure at arbitrary times (and ideally also run it
         | partially). And so the requirement is "sufficiently pure that
         | we can re-run it".
         | 
         | And that is an innovation, and it's kinda cool. But it does
         | break down rather quickly, which is why all these frameworks
         | keep iterating, and iterating, and iterating.
        
           | zethraeus wrote:
           | > since all our languages are essentially procedural
           | (functional, OO) that means expressing the UI as a procedure
           | (function/method).
           | 
           | I understand 'functional' to be used as the direct contrast
           | to 'procedural'! Is that not your understanding?
           | 
           | > So what is the actual innovation? It is more or less
           | directly and visibly expressing the UI in code.
           | 
           | The 'visibly' part here doesn't really actually hold true,
           | does it? Once you've componentized your <swiftui/react/html/[
           | VFL](https://developer.apple.com/library/archive/documentatio
           | n/Us...>, it's probably not super visibly understandable.
           | 
           | The best definition i can think of for declarative UI
           | frameworks is probably something closer to 'frameworks that
           | optimize for your ability to make a pure function
           | representing state'.
           | 
           | (After all `[[UIViewController alloc] init]` does indeed
           | purely say 'you have view controller' -- that's just not
           | super granular!)
           | 
           | In this light, isn't SwiftUI just a setup _more_ optimized in
           | this direction
        
       | stillkicking wrote:
       | Thesis:
       | 
       | >The application event loop coalesces these damage rectangles and
       | initiates an optimized operation: it only redraws views whose
       | bounds intersect the damaged region, and also passes the
       | rectangle(s) to the drawRect:: method. (That's why it's called
       | drawRect::).
       | 
       | So, according to this, you need an explicit run-time mechanism to
       | optimize the interaction of parents with children, with some form
       | of coalescing.
       | 
       | Antithesis:
       | 
       | >This is another reason why it's advantageous to have a stable
       | hierarchy of stateful objects representing your UI. If you need
       | more context, you just ask around. Ask your parent, ask your
       | siblings, ask your children, they are all present. Again, no
       | special magic needed.
       | 
       | ...except here, where OP says you don't need any special magic to
       | deal with parent/child relationships: just reach
       | up/down/left/right and do your thing!
       | 
       | Synthesis:
       | 
       | The reason one-way data flow became so popular is exactly because
       | the second view is a trap, or at least, a local maximum. If you
       | are really doing complicated orchestration in your hierarchy,
       | then you will end up reinventing the first wheel, to avoid
       | expensive/inefficient parent/child/parent thrashing cascades.
       | 
       | React does in fact have a good solution for this, in the form of
       | contexts. These also allow you to reach up and go talk to
       | parents, in a controlled yet composable way. The way I describe
       | them is "singletons but with scope". An underappreciated benefit
       | is that you can extend a parent context and pass it down,
       | replicating some of the benefits of inheritance, without the
       | messyness of subclasses.
       | 
       | Where React falls short is that parents can't respond to children
       | without re-rendering themselves, which ironically makes
       | implementing e.g. nested tree widgets hard, even though the
       | result is all tree-shaped.
       | 
       | Functional effect systems which can re-join after forking, and
       | gather yielded values, do not have this issue, and I wish React
       | would explore this avenue instead of the all the React 18 stuff
       | they've been doing lately... it feels too much like they are
       | leaning into the same Facebook "dumb read-only UI" style that the
       | article correctly laments. They are straying away from React's
       | original appeal, which was that it was "just the V in MVC", and
       | instead becoming very opinionated on how server side and client
       | side should be combined. Meanwhile the challenges of how to
       | replicate complex legacy desktop UIs remain mostly unaddressed,
       | with the official advice about event handlers, state and effects
       | falling short by a mile.
        
       | thurn wrote:
       | Every non-trivial (>10k lines) Cocoa/iOS/Android application I've
       | ever seen or worked on has re-implemented at least some parts of
       | React's data flow model. It's surprising to me that the author
       | glosses over handling lists, which is a huge challenge with this
       | approach, and one that forces you to do some React-like stuff
       | (UITableView cell recycling identifiers!) even if you don't want
       | to.
       | 
       | However, there are definitely _some_ problem domains that don 't
       | map very well to the React model. Real time games, for example,
       | have very different requirements.
        
         | chowells wrote:
         | Even real-time games are often best implemented as a pure
         | function of state. This has a lot of advantages for keeping
         | track of everything, especially in games with a network
         | component. Of course, it doesn't mean the function from state
         | to UI doesn't get to use mutable state - that's often critical
         | for performance. What's important is logically separating the
         | game state from the UI, such that any game state can be
         | isolated, serialized, and de-serialized at will.
        
           | crooked-v wrote:
           | I've had a very silly project in progress for a while along
           | those lines to implement a Game Boy emulator entirely in
           | Redux (state) and React (screen output, with pixels mapped to
           | the appropriate bits). If I ever finish I imagine it will be
           | incredibly slow, but it would allow for 'time traveling' the
           | entire emulator state.
        
           | elwell wrote:
           | I explored a little what it would mean to use pure functions
           | to generate state for a game that has a little physics: https
           | ://github.com/celwell/wordsmith/blob/master/src/cljs/wo...
        
         | madeofpalk wrote:
         | on the other hand, AppKit/UIKit has UITableView/CollectionView
         | view recycling just built into the framework, whereas everyone
         | on web (including React libraries) is trying to reimplement it
         | in userland
        
         | manmal wrote:
         | Lists are IMO the only area where imperative style has the
         | upper hand - you can build truly endless lists because items
         | are loaded lazily. UITableViewCell identifiers are cell _type_
         | ids, not cell ids btw, so they pose no overlap with React.
         | 
         | If you need a very long list in React, you need to use a
         | library with quite weird API.
        
       | the_gipsy wrote:
       | The author could really benefit from trying out Elm.
        
       | zethraeus wrote:
       | I spent a while trying to approach this post with an open mind.
       | In the end I was disappointed.
       | 
       | rel/to title: yes. (just say scroll position. fine.) But also I
       | think this is pretty well understood! (No?)
       | 
       | - In declarative UI / FRP / whatever, you model your basic UI
       | state through a pure mapping from your business logic 'model'.
       | 
       | - But (as in procedural programming) the UI has its own state --
       | that's not necessarily part of your initial
       | business/domain/model.
       | 
       | If you want to model it, you'll have to understand it, read it,
       | and add it to you model. That can be annoying--especially if the
       | APIs for getting or setting the state are bad.
       | 
       | This doesn't really sound like a fundamental flaw conceptually to
       | me. It's just an API with defaults you don't have to deal with
       | unless you _need_ to.
       | 
       | - don't care what your color is? fine. system default for you.
       | 
       | - don't care what tab a link opens in? fine. user default.
       | 
       | - don't care how scroll position is managed? fine. system
       | default.
       | 
       | - _want to handle any of them? cool. you can._
       | 
       | It sounds like progressive disclosure of API complexity to me.
       | Great.
        
         | zethraeus wrote:
         | (And of course FRP setups have to iterate! They're refining the
         | model to declaratively represent 20 years worth of UI
         | convention!)
        
       | brundolf wrote:
       | Needs a (2018)
        
       | Latty wrote:
       | > We do not make the (unwarranted) assumption that this
       | transformation can or should be expressed as a pure function.
       | While that would be nice, there are many reasons why this is not
       | a good idea, some pretty obvious.
       | 
       | So obvious they are left as an exercise for the reader?
       | 
       | This whole article seems to be based on the idea that pure
       | functional programming is absurd and impossible, and this is just
       | obvious and doesn't need to be shown. For someone who has written
       | a decent amount of Elm, it certainly isn't obvious to me.
        
         | mpweiher wrote:
         | > This whole article seems to be based on the idea that pure
         | functional programming is absurd and impossible
         | 
         | Huh? Where?
        
         | origin_path wrote:
         | The article is explaining those reasons, which the author feels
         | are obvious but he spells out nonetheless. The gist of his
         | argument is that because UI is not a pure function of a little
         | pile of centrally defined state, React has to come up with lots
         | of new concepts and mechanisms to wallpaper over the conceptual
         | gap. Hence his table which by the end is boiling down to "OOP
         | toolkits don't need this" alongside explanations of very
         | complex FP approaches.
        
       | zosima wrote:
       | This is interesting, mostly because to me it reads as a typical
       | blub paradox type response to react.
       | 
       | http://weblog.raganwald.com/2006/10/are-we-blub-programmers....
        
       | draw_down wrote:
       | No indeed. However the UI does emit changes to the model as the
       | user interacts with it. These can be modeled as a series of
       | values over time, aka a stream.
        
       | dsego wrote:
       | > A UI is NOT simply a replication of server / business logic
       | state.
       | 
       | I don't think that was ever the claim, the rest of the article is
       | similarly misguided. UI as a function of state doesn't mean "UI
       | is a function of business logic state". It means we define the UI
       | in a declarative way based on the view state.
        
         | ridiculous_fish wrote:
         | Yes, the article makes that assertion on behalf of both React
         | and Cocoa and explores the different way they address that
         | problem. It uses "scroll position" as an example: scroll
         | position is typically not tracked in the React state, so how
         | does it work?
         | 
         | In Cocoa, scroll position is part of the view's state, a mere
         | property of the view. This is simple because the UI itself is
         | stateful.
         | 
         | In React, scroll position is typically not part of the state
         | from which we project the view. Instead this state is attached
         | to the projection itself (e.g. a HTML node) and we are
         | dependent on the "Memoization Map" to preserve it. So this
         | memoization is now required for the correct functioning of the
         | app. The "pure function" abstraction is leaking.
        
       | mwcampbell wrote:
       | > A core premise of Cocoa, and MVC in general, is that UIs are a
       | projection of data into a different form of data, specifically
       | bits on a screen.
       | 
       | This is a tangent, but the implicit assumption that the UI is
       | visual is just begging for a response from an accessibility
       | perspective, so here goes.
       | 
       | Accessibility is very much an afterthought in native GUIs, not
       | only in Cocoa, but also in Windows with the UI Automation API,
       | and AFAIK with other native accessibility APIs as well. With
       | these APIs, the assistive technology (e.g. screen reader) pulls
       | information from the application (usually via the GUI toolkit),
       | through repeated calls to methods defined by the accessibility
       | API. Often the AT has to do several such calls in a row (and
       | those often translate to multiple IPC round trips, making things
       | slow). And the UI might change between such calls; there's no
       | guaranteed way to get a consistent snapshot of the whole thing,
       | as there is with a visual frame. On the application/toolkit side,
       | these methods may return different responses from one call to the
       | next, and the application or toolkit has to fire the right events
       | when things change.
       | 
       | The web improves on this, in that accessibility information is
       | conveyed through HTML tags and attributes. And yes, this is
       | included in the output of a React component's render function. So
       | while in practice, implementing accessibility may still be an
       | afterthought, it's not an architectural afterthought as it is in
       | native platforms.
       | 
       | One of my goals in AccessKit [1] is to work around this
       | shortcoming of native accessibility APIs, particularly for
       | developers of cross-platform non-web GUI toolkits. In AccessKit,
       | the toolkit pushes a full or incremental accessibility tree
       | update to the AccessKit platform adapter, which maintains the
       | full tree in memory and uses that to implement the platform
       | accessibility API. This even works for immediate-mode GUIs, as
       | one can see in my proof-of-concept integration with the Rust egui
       | toolkit [2].
       | 
       | [1]: https://github.com/AccessKit/accesskit
       | 
       | [2]: https://github.com/mwcampbell/egui/tree/accesskit
        
         | paulryanrogers wrote:
         | React components built as div soup may actually be worse for
         | accessibility than thoughtfully written no-JS HTML.
        
           | wonnage wrote:
           | This statement is practically a tautology
        
           | andrewingram wrote:
           | And no-JS HTML built as div soup is likely worse for
           | accessibility than thoughtfully written React. So React
           | itself has no bearing on it.
           | 
           | My take is that it's the growing complexity of web
           | development (yes, React has some responsibility here),
           | combined with the constant influx of new developers, that's
           | largely to blame for any overall proportional loss in the
           | practice of accessible markup.
        
             | ksbrooksjr wrote:
             | I agree. Another thing to consider is that React makes it
             | frictionless to import custom components, instead of
             | attempting to re-write common UI patterns from scratch.
             | 
             | If a React dev leans on an accessible UI framework like
             | Chakra, or Headless UI, or React-Aria, they're probably
             | better off from an accessibility perspective than a dev
             | that tries to implement WAI guidelines from scratch.
        
           | saulrh wrote:
           | And? The point of the parent was that _either_ of those are
           | better than native - doesn 't matter how much div soup you
           | have, at least the information exists, unlike the bucket of
           | raw pixels that're all you get from native UIs sometimes.
        
             | paulryanrogers wrote:
             | Desktop UI frameworks are a bit of a mess. Though truly OS
             | native should be the most accessible of all.
        
       | origin_path wrote:
       | This is a good counter-argument to the React proposition. It's 5
       | years on, and both Apple and Google are now adopting the model
       | for themselves via SwiftUI and JetPack Compose, but, is it
       | actually the best way to do things?
       | 
       | If you're used to toolkits that give you a basically fixed set of
       | components, in which creating new components is considered an
       | advanced operation and there's no assistance with data binding,
       | then something like React seems like a breath of fresh air. I've
       | done a bit of JetPack Compose, and also some JavaFX and of course
       | HTML5 stuff. On the web React is an upgrade simply because the
       | DOM isn't meant for UI and HTML has no notion of components at
       | all. On Android, well, the classical Android UI toolkit was never
       | that great. It's a Java Swing era API with three different clock
       | classes in it! I can't comment on UIKit, never used it.
       | 
       | Maybe a better comparison would be to something like JavaFX,
       | which pre-dates the crazy for functional programming but
       | benefited from the years of experience with classical toolkits
       | like Swing/GTK etc. And here, it gets hard to really get excited
       | by React. The blog post isn't wrong - the React model requires a
       | ton of concepts, abstractions, and complicated infrastructures to
       | try and recreate things that come for free in OOP toolkits.
       | JavaFX supports data flow and binding because every property is
       | both observable and bindable via lazy dataflow graphs. So your UI
       | can indeed be a pure function of the model, but instead of re-
       | execute/cache/memoize/diff, you assemble the computation graph
       | for whatever needs to be reactive. Most of the time, you don't
       | actually need to do anything complicated here and can write code
       | as a straightforward imperative calculation.
       | 
       | Creating components is likewise pretty easy, albeit JavaFX is
       | currently in a sorry state where the open source community around
       | it doesn't maintain the documentation properly, so it's hard to
       | link to a tutorial that demonstrates this. But basically you get
       | a pay-as-you-go approach in which you can just group some widgets
       | in a class, or you can be a bit more ambitious and inherit from
       | Control which gives you things like proper focus/tab order
       | management, the ability to control properties using CSS and so
       | on.
       | 
       | When I read code written with JetPack Compose, the feeling it
       | gives isn't really that great compared to the OOP style. The way
       | it totally changes the core programming model of the language
       | looks like an absolute nightmare to teach to new programmers. The
       | most fundamental rules of the programming language are suddenly
       | up for grabs - what looks like straight line imperative code
       | actually isn't, variables might retain their state beyond the
       | scope of a function call ... or might not ... and it seems like
       | React/Compose codebases invariably degrade into tons of tiny
       | functions passing giant amounts of stuff around on the stack,
       | with lots of obscure performance problems that come from the game
       | playing with the core execution model and all the
       | diffing/patching going on behind the scenes.
       | 
       | In the end I find I agree with the author. Good UI is not in fact
       | a pure function and the FP model is a poor fit. There is too much
       | implicit state that is best encapsulated in the UI framework, and
       | with an actually well designed OOP framework data binding just
       | isn't painful enough to justify the costs.
        
       | revskill wrote:
       | Of course, we can put a launchMissiles inside useEffect, so of
       | course UI is not pure function of model in React. That's why
       | there's PureComponent in React which disallowed state or effects.
        
         | ridiculous_fish wrote:
         | It's not about useEffect. If a Component renders a text field,
         | that text field has additional state (e.g. cursor position)
         | which is not part of the model. That's one reason why the UI is
         | not a pure function.
        
           | ptx wrote:
           | Couldn't this be solved by acknowledging that there is
           | application-domain state (such as the value of the text
           | field) and UI state (such as the cursor position and
           | selection), which can be represented by an application-domain
           | model and view model respectively, rather than trying to
           | pretend that the latter doesn't exist?
           | 
           | Although if you model all the UI state, maybe you just end up
           | with the DOM?
        
             | ridiculous_fish wrote:
             | Yes, this is known as MVVM.
             | https://en.wikipedia.org/wiki/Model-view-viewmodel
        
           | Kaze404 wrote:
           | This feels like saying Haskell doesn't have pure functions
           | because they don't account for cosmic ray bit flips.
        
             | ridiculous_fish wrote:
             | No, this implicit state is a very practical concern in
             | React. For example see this highly upvoted SO post. Text
             | fields lose focus on re-render; the solution is to use a
             | unique key so that the view gets re-used and the implicit
             | state is preserved.
             | 
             | https://stackoverflow.com/questions/22573494/react-js-
             | input-...
        
       | jarjoura wrote:
       | In my experience, object oriented view systems like Cocoa (UIKit
       | or AppKit) work great for small teams with deep domain knowledge
       | of their code base. However, they constantly require refactoring
       | as teams grow and systems become more complex. This leads to
       | overly complex UI code over time that become brittle.
       | 
       | UI through composition, building UI through assembling components
       | from other components, has done away with those issues. The
       | enforced encapsulation is frustrating that I agree is a trade
       | off, but refactors become simple find and replace to point to new
       | components instead of having to rewrite entire chunks of
       | previously working code.
        
         | andrekandre wrote:
         | > UI through composition, building UI through assembling
         | components from other components, has done away with those
         | issues.
         | 
         | it should be noted, you can do this just fine in cocoa/uikit
         | with delegation/message forwarding etc. but most people dont
         | know about that ime
         | 
         | lots of subclassing and overriding is much harder to avoid with
         | view controllers but view-level subclassing is usually an anti-
         | pattern _(if i got a dollar for every time i found a
         | "RedButton" class id be a millionaire)_ but like most things
         | people aren't either experienced or educated enough in these
         | frameworks                 > However, they constantly require
         | refactoring as teams grow and systems become more complex. This
         | leads to overly complex UI code over time that become brittle.
         | 
         | i think this becomes true with any system, but subclass-heavy
         | code makes it definitely harder imo                 > ...is
         | frustrating that I agree is a trade off, but refactors become
         | simple find and replace to point to new components instead of
         | having to rewrite entire chunks of previously working code.
         | 
         | if done well it is easier in swiftui for sure, but the way i
         | see people write "in the real world" swiftui is used in a much
         | more monolithic fashion and hard to pull-apart... (personally i
         | love swiftui) but i think real-world usage will still he
         | mudballs in a large portion of codebases (there is no silver
         | bullet)
        
           | lmm wrote:
           | > lots of subclassing and overriding is much harder to avoid
           | with view controllers but view-level subclassing is usually
           | an anti-pattern (if i got a dollar for every time i found a
           | "RedButton" class id be a millionaire) but like most things
           | people aren't either experienced or educated enough in these
           | frameworks
           | 
           | At some point if the system guides everyone into doing it the
           | wrong way, it's a problem with the wrong system. Subclassing
           | is rarely the right solution, one of the things that's really
           | refreshing about React is that most people tend to naturally
           | avoid subclassing when using it.
        
         | origin_path wrote:
        
       | nemothekid wrote:
       | > _Except for games, UIs are actually very stable, more stable
       | than the model. You have chrome, viewers, tools etc._
       | 
       | I think the author's analogy breaks down here. Almost every point
       | after this is "You don't need this because React started from
       | this faulty assumption that UIs aren't stable".
       | 
       | The hand rails frameworks like React gives you is because this
       | assumption isn't true. If your UI is stable enough where this
       | complexity isn't needed, then _don 't use React_.
        
       | adamnemecek wrote:
       | I have been thinking about this a bunch lately and I think that
       | the main problem with all these approaches is that it's all built
       | on top of a DOM and as a result it gets us to a local optimum and
       | prevent us from reaching a global optimum.
       | 
       | The thing that these approaches don't account for is the
       | rendering aspect which should ideally be done on the GPU.
       | 
       | There's this duality between Array of Structs and Struct of
       | Arrays [0]. People find programming with Array of Structs easier
       | but GPUs work with Struct of Arrays. I think that a language is
       | needed that fundamentally compiles AoS to SoA.
       | 
       | Another advantage is that repainting the whole scene is much
       | cheaper do you can be a lot more aggressive with repainting
       | everything.
       | 
       | [0] https://en.wikipedia.org/wiki/AoS_and_SoA
        
       | Marazan wrote:
       | Takes me back to the time when MVC zealots absolutely lost heir
       | shit when React came out.
       | 
       | React obliterated their world view and they simply could not
       | cope.
       | 
       | I am using hyperbolic language but the "Anti-React" 'backlash'
       | was truly mind boggling.
        
         | vbezhenar wrote:
         | I'm not computer theorist. But to me React seems like a perfect
         | implementation of MVC. Model is state. View is virtual-dom
         | chunks. And controller is an actual function implementation
         | which maps state to view.
        
           | [deleted]
        
           | elanning wrote:
           | This is typically a good way to organize React projects, in
           | my experience. A few top-level components which hold state
           | with a useReducer and have a few functions to make backend
           | calls, as needed. You could consider the reducer the model
           | and the top-level component the controller. All components
           | that sit below the top-level are pure view components. Props
           | in, view out. They at most hold a minor amount of UI state.
           | They don't make API calls or update state themselves, that
           | must be done with a callback to the top-level component.
           | 
           | This makes testing simple as you can test the reducer without
           | rendering any UI. The pure view components are also easy to
           | test. Then a few end to end tests to tie everything together.
           | 
           | https://www.reactguide.dev/#mc-v-trees Has more info on how
           | to scale the pattern for larger apps.
        
         | My104thaccount wrote:
        
         | FinalBriefing wrote:
         | I'm still one of those people. Separation of concerns is a big
         | concern for me.
         | 
         | In my experience with React, it's a lot harder to keep things
         | separated, and developers who I've worked with who have more
         | React experience aren't always up on the concept.
        
       | Jakobeha wrote:
       | A UI can be represented as a set of concurrent/asynchronous
       | prompts. UI takes the model and possible next actions, presents
       | this to the user, gets a response, and returns this as an action
       | which is then applied to update the model.
       | 
       | Alerts and login forms are clearly prompts. But so is an complex
       | editor: it constantly prompts the user for the next action, e.g.
       | enter text or change existing text's formatting. Or a social-
       | media site: possible actions are "login", "view post", "create
       | post", and so on.
       | 
       | Even an FPS can be warped into a prompt-based UI, where the model
       | is the game state (or what the player sees of it), and the
       | prompts are "move, turn, shoot". But you probably shouldn't do
       | that. Asp bad examples: a weather or stock viewer where your
       | options are null, and the model is the weather or stock which you
       | can't change.
       | 
       | Nonetheless prompt-based UI is really useful for many otherwise-
       | ordinary cases. It lets you write a UI like a CLI and automate
       | your UI very easily; it tells you which state is truly part of
       | the "model" and which is just part of the UI; it's composable
       | spatially (more elements) and temporarily (series of steps). I
       | don't know if it's been explored much.
       | 
       | In prompt-based UI, the UI is _sort of_ a pure function of the
       | model. It's an asynchronous function which takes the model and
       | returns a stream or future of the next action(s).
        
       | projektfu wrote:
       | I think there are a lot of specious comparisons. In Cocoa, all
       | parts of the UI can theoretically participate in the app and be
       | wired in the same way. In the web, you don't get your own text
       | field, etc, so you will have to make do with what's there. Thus
       | there will be parts that have to be handled differently.
       | 
       | I think Marcel brings up a valid point about composition, if I
       | understood it correctly. The composition of interfaces in Dolphin
       | Smalltalk, for example, is super easy with the MVP paradigm. You
       | can build and test a particular feature and immediately drop it
       | into another, larger composite presenter. You just make its model
       | a field on its owner. Other properties can be connected to where
       | they need to be during the initialization of the component.
       | 
       | I'm not sure if wiring up react components is as easy, because
       | you have to think about stuff that is not directly in your data
       | flow. But I honestly don't have enough experience to say. I have
       | more experience with Elm and found it a little less easy.
       | 
       | At that point, the big difference between MVx and reactive is the
       | bidirectional data flow in MVx. Parts need to be bound so that
       | they update the real world, and updates need to be observable so
       | the UI can change. Reactive UI coordinates a filtration of that
       | state through the view painting.
       | 
       | In Elm (old Elm, not sure what it's like now) when you embed a
       | component your top level needs to understand its messages to pass
       | them down/up appropriately. The type system helps you not forget
       | things, but there was a good bit of retyping.
       | 
       | That, and the way that html bits fit into other bits breaks the
       | abstraction. Perhaps using a reactive approach to run Web
       | Components is the best way to get the same sort of composability
       | currently, I haven't tried it.
        
       ___________________________________________________________________
       (page generated 2022-07-04 23:00 UTC)