Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

React is the most interesting GUI approach to me in this regard, as while you can use inheritance if you use the class-based component approach, functional components are, well, functions and can be built by rules of composition. I tend to do a lot of UI in the form of "component with a dozen parameters that almost nobody wants to use every day" that is wrapped by "specialization of the general component that has a few parameters and then uses the general component by wiring those parameters and some logic together."

Any type of "hot patching" is a bit more difficult (I can't easily just reach down a component's tree and mutate it from outside, not unless I've pre-wired the component to allow for that, and the semi-artificial limitation of the use of the tree model as a single `children` property means that such odd wiring gets weird fast if I want to get fancy). But it's a perfectly serviceable UI toolkit framework that is free of requiring inheritance.

ETA: deferring to nu11ptr's taxonomy, React is not a widget toolkit by any means by itself. I find https://react.semantic-ui.com to be perfectly serviceable in that regard as a base, easy-to-modify widget toolkit.



React type APIs (e.g. Jetpack Compose too) are interesting but actually I find myself wishing for OOP and inheritance back again. I'd probably quite like a combined approach. Raw functions calling each other have a bunch of weaknesses:

• They aren't really stateless because UI is full of implicit state. So the whole functional UI thing isn't really true. You just end up with odd alternative syntax for what would be object properties, but declared as magical local variables that retain their values across calls.

• No inheritance, interfaces or object identity means no way to write generic code! Want to write a function that locates every button in a UI and applies some behavior to it? Tough, you can't! (in react of course you can drop down to the DOM but in Compose there's no DOM to drop down to). I found this comes up a lot even in simple cases and is a serious limitation.

• "Design systems" (themes) are all custom widgets. There's not really any concept of an underlying widget toolkit with flexible visual styling. Combined with inability to write generic code, it means if you want to port to a different theme or customize anything beyond trivial aspects of the existing theme like font or colors, you have to actually rewrite your code.

• Composition for everything yields enormous amounts of boilerplate. You can't say "define a button that's the same as a regular button except with one additional aspect" and have it automatically stay up to date as the underlying button widget evolves. Instead you have to duplicate the entire API of the button and clone it into your own API, propagating the values by hand.

The annoying thing is that Kotlin already has some features for managing composition, but it requires you to use classes and interfaces. The "everything is a function" philosophy means you lose all those features. Composition also bloats up APIs because there's no longer any distinction between something that's relevant only to people customizing a control (i.e. a protected method) and something that's meant for the user of the control (i.e. a public method or property).

So I'm definitely feeling like sticking my neck out and defending OOP here. Probably there'll be a swing back towards OOP or a similar-but-rebranded form of it in future, as people realize that things like inheritance, subtyping etc were invented for valid reasons.


Ineritance and subtyping are great for when you want a lot of the code to be "This thing, but a little bit different," and that's a problem that I see come up a lot in GUIs. I'm inclined to agree with the idea that GUIs are one of the better applications for an OOP approach.


Since you mentioned Kotlin, you might be interested in the recent gtk-kn effort which provides OOP bindings to GTK in Kotlin Native. (Early preview, not production ready at all)

https://gitlab.com/gtk-kn/gtk-kn




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: