Live data from Hacker News

SwiftUI After 7 Years

ykvm.com

201–210 of 343 posts

Re: SwiftUI After 7 Years

#201

Earlier quoted context omitted.

Thanks for those links! Some of it was great reading. What is your thesis then? What is UI?

"A view is a (visual) representation of its model. It would ordinarily highlight certain attributes of the model and suppress others. It is thus acting as a presentation filter." https://web.archive.org/web/20090424042645/http://heim.ifi.u... View and model are related , but neither is procedurally dominated by the other. The view is not a subroutine of the model, or vice versa. They are related entities that communi…

Isn't that the Controller part in MVC

Re: SwiftUI After 7 Years

#202
I liked the promise, but the reality has been disappointing.

SwiftUI is great for test harnesses and admin utilities, but I won't use it for shipping software. I have one app that I rewrote in SwiftUI, just so that I can say that I have shipped it, but I am still using UIKit for most of my apps.

I'm not thrilled with UIKit, but SwiftUI has kind of withered on the vine.

Re: SwiftUI After 7 Years

#203
post #186

Earlier quoted context omitted.

Imo the biggest issue with this functional model (at least in React), is that it handles things like virtualization, async, etc. poorly. Which is kinda ironic, because in a true functional language, it'd be feasible to provide 'a world model' - that is act as if the entire state is always available, and let the engine decide when to evaluate pieces of code - without any effort from the part of the programmer. Unfortu…

Stuff like virtualization (if we're talking about stuff like virtualized lists) is hard not because of React, but because there just isn't any support for it in browsers. React doesn't really help here, but in my experience, it's usually the browser that starts choking on high element counts, not React. Async is just difficult in general though. It's not really a surprise that most libraries/frameworks converged on s…

I am talking about virtualized lists. And it should be a framework feature. I used to use WPF on desktop, and it had pretty good virtualization support (though the framework in general was more like Angular) - most containers had virtualization support, and you only had to implement the logic on the data source, and they framework created and managed physical UI elements for you, and managed the mapping so it seemed seamless to the user.

React also operates on a virtual dom, there's no reason imo why couldn't they just fake that for you.

Re: SwiftUI After 7 Years

#204

Autolayout, while flawed like anything else, remains the pinnacle of UI across all platforms. SwiftUI is a laudable attempt to idiot-proof UI, but it sacrifices too much and ultimately fails.

Every time I have to structure UI anywhere else, I lament not having AutoLayout.

Re: SwiftUI After 7 Years

#205
post #116

Earlier quoted context omitted.

I see an M and a V in this description, but no C. Is the UI updating itself automatic or manual? Because if it’s manual, that’s precisely the error-prone part that you’re saying this approach somehow solves - you’ve done the “How to Draw an Owl” meme. If it’s automatic, that doesn’t seem especially different from the React/Redux/Elm/SwiftUI approach (as a sibling points out).

Yeah, M-V-C are all roles, not concrete objects. The C mediates between the input devices and the model, but in practice views can and often do fulfill that role as well. Cocoa views, for example, also fulfill the C role. Different formulations of M-V-C have the C deal with more complex interactions, with sequences of interactive prompts like wizards. The update is essentially automatic, and yes: MVC already solved t…

I like my Controller to be responsible for all the "business logic" so that its all in one place. It's the important part. The View layer is always fairly verbose and full of fluff. Especially if you have a lot of animation and formatting type code.

Re: SwiftUI After 7 Years

#206

Earlier quoted context omitted.

Are you saying the UI always updates its entire self whenever anything changes in the model?

Yes and no. Conceptually, the UI re-renders itself completely in order to always be an accurate reflection of the model. That is the #1 job of the view: be an accurate reflection of the model. And re-rendering itself completely is a safe way to implement that requirement. However, the UI can also look at the model in more detail and figure out what parts need to change, as long as the effect is the same as re-renderi…

Immediate mode UI ftw.

Re: SwiftUI After 7 Years

#207
my take is apple should've hired or worked more with external partners in terms of handling swift.

1. the language had all the right hook points to replace python - but then it was closed off in the apple ecosystem for a while. then it was made to be complex as C++ as time went on. if Swift had remained as simple as Go - and Apple had made a push for swift to go beyond apps in their ecosystem the language for data/ml would be swift

2. in regards to swiftUI - almost the same point as 1. react native took over cz it was a simpler more open ecosystem. then eventually most people stopped bothering with native apps (they're used to track you) - web apps are equally good. hence for most people they use native apps for maps, banking.

Re: SwiftUI After 7 Years

#208

Earlier quoted context omitted.

> Could Apple build MacOS X and Cocoa today if they didn't already exist? Apple got rid of all the NeXT people long ago, with Tim Cook stabbing Scott Forstall in the back, so the answer is No.

This is completely false, many NeXT people still work there.

So you think that they would be able to build MacOS X and Cocoa today if they didn't already exist?

Re: SwiftUI After 7 Years

#209

Earlier quoted context omitted.

Not if you actually do MVC, so solved around 50 years ago. 1. The UI tells the model to change. 2. The model does the change and possible related changes. 3. The model notifies the UI that something has changed. 4. The UI updates itself from the model. Alas almost nobody does MVC, despite calling what they do MVC.

MVC is not bad, but it is not a silver bullet. Calling MVC an ultimate solution to UI is oversimplification. Just looking at the steps you listed I can ask: How do you collect all notifications on step 2 to fire them on step 3 such that UI does not re-render itself too much? E.g. updating a title of each item in a list of 100 items should not trigger 100 renders. Or 100 layout calculations (which I think is harder to…

I can only say how I did this in the Azul GUI framework[1] (note: not production ready yet), which may be close to what you're describing. So in Azul, you do this:

  class DataModel:
    def __init__(self, counter):
        self.counter = counter

  def layout(data, info):
    return Dom.create_div()
             .with_child(Dom.create_text(str(data.counter)))
             .with_css("font-size: 32px;")

  def on_click(data, info):
    data.counter += 1
    return Update.RefreshDom

  model = DataModel(5)
  window = WindowCreateOptions.create(layout)
  app = App.create(model, AppConfig.create())
  app.run(window)
So, there's no "automatic" re-render, a callback has to return "Update.RefreshDom" or "Update.DoNothing" (default).

Now to your questions:

> How do you collect all notifications on step 2 to fire them on step 3 such that UI does not re-render itself too much?

Diffing, and then caching very aggressively. The click causes the model to re-call the layout() fn to return the entire DOM, however, there are ways to make this step very fast (arena allocation / no allocation). Then this gets diffed with the previous DOM state and the framework internally reuses everything it can (with user providing keys for list items, like React does).

> How do you deal with situations where on step 4 UI triggers an event that your model happens to listen and the cycle repeats while killing performance?

Azul has a "max recursion depth" of 5 and then just throws an error (infinite cycle). So, it will invoke all the relevant callbacks for a frame, then "sum up" all of the Update enums (i.e. one callback returned RefreshDom -> now we need to repaint).

> Sometimes it is scrolling or typing, sometimes it is parts of the model subscribed to each other bubbling events to UI.

Scrolling, selection, typing, etc. are handled by the framework. To make something editable, you need to set "contenteditable=true" on the Dom node (like on the web). Then, on text editing (which can also come from IME, a11y input, copy-paste), you get a "text changeset". The callback can then "reject" the changeset or allow it (default, since you already set contenteditable before).

Azul has a "dual update pattern" for performance here, i.e. the DOM itself is immutable until the next layout() call, however for "quick edits" like dragging a node you obviously don't want to call layout() again and construct an entire new DOM tree. So there, you just (conceptually, don't know the current API for this):

  def on_div_dragged(data, info):
    mouse = info.get_window_state().mouse_state
    info.set_css_property(info.get_hit_node(), "transform: translate(%s, %s)", mouse_state.x, mouse_state.y)
    # store in data model or node if necessary
    data.user_mouse_pos = mouse_state
    return Update.DoNothing # no re-render here
So, if another callback fires in between, the data model is still properly up to date. Azul also aggressively reconciles focus, scroll position, selection, text cursor position, etc. But Azul does not allow "one event auto-triggers another" like SolidJS does, it looks nice on a slide deck and then is a pain to debug Rube-Goldberg state machines.

This also works for text input or updating images (i.e. you don't need to call layout again on text input). Update.RefreshDom is for "larger / structural" changes, i.e. something like a route switch in a SPA-style app. Azul tracks the text cursor position by diffing the actual text, so the user code doesn't have to track the text cursor and state is preserved during a diff (it can also retain heavy elements).

For large lists, there is a native "virtualized view" DOM node with a callback that is being called "during" layout (after the size of the container has been determined, then the framework asks you to render your DOM, given the scroll position). So, that can be diffed, too. You never render in the DOM more than ends up on screen, so the perf is manageable.

Scrolling and retaining scroll positions inside a virtualized view is still an ongoing topic (not impossible, you just have to have functions to measure the DOM items before you return them, to estimate how much you need to render, and then do the math for "where are we right now, where is the scrollbar, how big is the virtualized view in relation to what we're rendering" - so the framework can set the right scrollbar size and position).

Again: please don't use or post Azul here on HN yet, docs are still slop and undergoing review, API is unstable until I have some apps going, but I just wanted to answer these questions.

[1] https://azul.rs/ui/

Re: SwiftUI After 7 Years

#210

Earlier quoted context omitted.

"A view is a (visual) representation of its model. It would ordinarily highlight certain attributes of the model and suppress others. It is thus acting as a presentation filter." https://web.archive.org/web/20090424042645/http://heim.ifi.u... View and model are related , but neither is procedurally dominated by the other. The view is not a subroutine of the model, or vice versa. They are related entities that communi…

Isn't that the Controller part in MVC

Common misconception, but nope.

The quote is from the original definition by Trygve Reenskaug, the inventor of MVC (see link above).

https://en.wikipedia.org/wiki/Trygve_Reenskaug

Here some more on that misconception:

https://blog.metaobject.com/2015/04/model-widget-controller-...

Post reply on HN