6 ms·
Ask HN: Why is GUI programming so hard?
Some smart guy (may or may not be Rich Hickey) was allegedly heard to have said about GUI programming, "I don't do that kind of stuff."
Over the years, I have observed the fact that some /many things about GUI is/are just unnecessarily stupid.
See Jgoodies-binding, and more recently elm-lang and htmx for unexamples of this.
btw, rip
- aristofun 3y agoYou don’t usually have such a complex state on the backend. That’s why.
- tripleo1 3y agoI started thinking about this the other day because of this question at we-turned-everything-into-a-google-trap-and-now-it-has-ai-too-dot-com, with-a-subscription-business-model (https://www.quora.com/As-someone-who-does-some-programming-for-fun-why-is-making-even-basic-GUIs-difficult-compared-to-console-programming-Is-it-just-me-trying-to-learn-it-myself-or-is-windows-API-generally-difficult-to-deal-with https://www.quora.com/As-someone-who-does-some-programming-f...) One of the answers does mention FLTK, which I should have included above.
- smoldesu 3y agoI would argue it's a "give a mouse a cookie" situation. On the simplest side of things, stuff like Zenity exists for super-simple GUI dialogues and user input but isn't very customizable. You want a window model with a visually-distinct root window and identifiable dialogues and child processes. You also want async management between those windows, atomic data handling for both processes, signal handling for sending data between them, GPU-accelerated animations... what we really end up wanting is pretty much an entire OS. The best GUI toolkits I've used are either heavily abstracted (tkinter/pygame) or absurdly full-featured (GTK/Qt).
- PaulHoule 3y agoI don’t know if it is that GUIs hate tests or that tests hate UIs but either way it means UI code is hard to test. The trouble is that a UI element usually calls the framework and gets called by the framework so you wind up needing mocks and such. Or you have something like React which is just batshit crazy (e.g. do I wait until the component renders 7321 times or 7322 times before I can check that it is in the state it is supposed to be in?)
- cyanydeez 3y agoI've found arrivejs to be magic for all things html async. it triggers on any selector.
- mikewarot 3y agoVisual Basic 6, and Delphi 5 made GUI programming trivial. You drag/drop GUI elements in place, then hook up event handlers. These days, there's a lot more boilerplate in most languages. C# was a horrible downgrade. If you can put up with the documentation, Lazarus/Free Pascal works amazingly well, and is almost as easy as it used to be.
- bane 3y agoWas just discussing this with a younger colleague this past week. I think the conclusion we came to is that: a) GUI programming (for the web) is hard because the core technical stack that's made up of browsers, html, js, and css is abhorrent garbage (I'll get to what I'm comparing it to in a sec). It has incomprehensible standards and almost no compliant implementation that can make it all work together -- after decades, untold millions/billions of dollars, and unbelievable quantities of person-hours. b) the layer right above that (the frameworks and libraries) changes so often, are so buggy and fragile, and reinvent the same stuff over and over and over again, and a billion frameworks that all poorly do the same crap in slightly different ways get released every month -- usually built by bored engineering teams with nothing else to do or people who didn't exist in the "before times". c) My first job out of college in the "before times" was building Windows desktop software. With no real internet resources, a couple of books and whatever Microsoft called their C++ visual dev environment software back then I managed to build professional GUI software in a couple months that still runs, looks, and works exactly like it did back then and made out company quite a bit of money. Later on I applied basically the same ideas to some Linux desktop software using Qt and everything worked fine and was easy. Visual Basic, Delphi, heck even Microsoft Access demonstrated that it's so easy that even relatively inexpert people can create complex and reasonably attractive GUIs. Point is, we had the technology, it wasn't hard to use, and it worked pretty much flawlessly and the web is such a broken disaster of a mess that it's almost rewritten the brains of the entire industry to just Stockholm syndrome themselves into accepting that there must be something hard about GUIs.
- andrei_says_ 3y agoI use css and I think it’s pretty amazing. It requires understanding and thinking that goes along, not against the technology. It is hard to abstract and tailwindcss for example is an abstraction which goes against it for the sake of bypassing the deeper understanding. But css is powerful, elegant, and keeps moving in the right direction.
- 1attice 3y ago[context: frontend eng here, with a CS background and lots of experience on the backend] The reason frontend dev sucks so much, essentially, is humans. Have you met humans? They are opinionated, dogmatic, and hidebound; their habits and preferences are arbitrary, and, collectively, comprise their horison the way the bars of a cage do a bird's. A slight user preference for something inconsequential, like, say, a realtime indication of password strength, or an absence of loading delays, means that if your product does not "meet user expectations" for some some incredibly inane value of `$EXPECTATION`, you can reliably expect your competitors to consume not just some, but eventually, all of your sales, and is therefore strongly selected against. Recalling that you are yourself substrated upon a human, you know exactly what I'm talking about. Be honest. Are all of your preferences rational? What even is 'rational', anyway? I'm not just doing a lazy gesture to pseudo-philosophy here, I'm actively asking you to define practical rationality (not just logic, mind you) in a way that has no reference to common practice, intuition, or habit. Good luck :) (Note: I wasted my twenties in a philosophy PhD programme, so I know enough to advise you that this is a honeytrap that you can literally spend decades unsuccessfully trying to answer. I know I did.) Anyway, because of user expectations -- expectations like: bespoke widget sets, branding, performance, speed, similarity with native app, cross-browser compat, etc. -- we -- us engineers -- built elaborate tooling back in the day to accomplish all this, for 2008-ish values of 'back in the day'. Some of these, like jQuery, eventually crystallized into new browser APIs, but a lot of them involved various kinds of either stack lock-in, or conceptual lock-in. (React does both.) Remember how I said humans were creatures of habit? Well, horribly enough, engineers are humans too, and we can't get good (really good) at things until we've put in 10k hours or so. So, if you've put in 10k hours into React, you're going to be at a competitive disadvantage if you move everyone to a saner alternative, such as htmx. This, too, is strongly selected against. So, there you have it. Frontend development is terrible because it's the part that touches the most humans.
- 1attice 3y agoP.S. I note I only answered your question with regard to browser programming; for other GUI situations, things are similar, if not worse. E.g. GTK+, which is used to make some devastatingly effective and elegant Gnome apps these days, is, in my opinion, a Bad API. But good luck trying to reproduce every nuance of Gnome ex-nihilo with FLTK.
- gardenhedge 3y agoThe hard part about GUI programming is that it involves managing state. Managing state is hard.
- quickthrower2 3y agoWhy are elm/htmx considered stupid? And UI programming is hard because of the user you are interfacing with :-) and the fact you are not forcing them to have amazing working memory needed to deal with a CLI.
- proc0 3y agoIt's deceptively complex. What looks like buttons and sliders ends up having a lot of interactivity that is underestimated. Then there is the complexity of both the software and hardware stack, from different displays and devices to a rapidly evolving ecosystem of libraries, frameworks, and such. Add to this the complexity of the networking stack (at least for web apps) and it's not hard to see why even UIs with modest functionality become very large and complex. There is also something to be said about how organization structure their teams to build UIs and APIs, which is to scale productivity by adding and leveraging more people, as oppose to leveraging more powerful code. This is probably more true on the frontend as it is typically not as critical to the business as the backend, so it is not surprising to see UIs constantly break or lack any proper standardization.
- vfclists 3y agoGUI programming is hard because some industrialists realized that if they switched the whole world to web based applications they would be able to hoover up information for free and got everyman and his dog to jump onto the everything must be a web application bandwagon. As for web development frameworks, GUI and otherwise, they are like nuclear fusion, only in this case a new framework is announced every two weeks that is claimed will solve every development problem.
- tugberkk 3y agoWe can still use browsers as UI without using any cloud.
- jbverschoor 3y agoBecause every six months we start over again with new models, libraries, tools, compilers, transformers, names. Except stable APIs and documentation.
- dang 3y agoI think causality is probably the other way around, i.e. we keep starting over because the problem is hard. There's a back-and-forth lurch that happens when people discover that yet again, they're caught in a complexity net, have a strong it-shouldn't-have-to-be-this-complicated feeling, and set out to build tools that will make the problem easier in general. Often it's relatively new programmers running through this cycle, who perhaps don't realize (yet) how many times this lurch has already taken place, or how they may be repeating the approach of a previous 'generation'. (That's not a cricitism—it's the cycle of life of the software business, and has been going on since long before most of us showed up.) I do think there's something about UI that lends itself particularly to this phenomenon. Perhaps its statefulness, as someone else said already.
- jbverschoor 3y agoI don't think the problem is too hard. It's just that people don't seem to understand the different models and history of things. People have this not-invented-here syndrome. It also comes from the fact that they initially think a certain framework is too complex. Only to figure out later that they didn't understand why certain things were done in a specific way. Also, the fame and opportunity that comes with creating a framework cannot be denied. For example, The whole "MVC" term on the web is plain wrong (web2.0 times). It's a term from actual GUI programmer, bolted on a document presentation format. These days it's probably faster and easier to distribute an OS such as MenuetOS via web assembly, and simply run a GUI application inside which uses a simple JSON api. About statefulness... why are we introducing stateful applications which is then patched up with server side rendering when a simple html application would suffice? It makes no sense. It's stupid, costly, and has 0 benefits. For more complex applications, sure.. but tbh, where are those? Is a simple admin panel or login screen really 10x more difficult to create than VS Code, or for that matter Microsoft Access? "Engineers" in general like^H^H^Hlove^H^H^Hget off on complexity. That is where the problem lies. It's intellectual porn and toxic as hell. End of rant |] merry Christmas:)
- vismwasm 3y agoI always try getting into frontend frameworks but it's just overwhelming. For WebDev there are a trillion frameworks which you need to append with another framework as the each framework doesn't really solve the problem by itself. I looked into Flutter & Dart as it seems thatr everybody loves it. But then apparently even for Flutter you need another framework for state management. I thought state management is the core issues these frameworks want to solve? I would've thought game engines have solved the problem of complex state management though. There are games with reactive in-game browsers/websites which work better than most real websites! So far the easiest for me to grasp and getting started was actually react / nextjs: - Extremely well documented - Little boilerplate (especially compared to Flutter - I find that StatefulWidget really ugly) - Combined with a component library it's incredible easy to get started
- ganzuul 3y agoInterface is hard. Users are hard. Graphical is hard. Then you add three-way integration on top. There is just so much potential close at hand but out of reach. E.g. Steam Controller.
- viraptor 3y agoI'm sure there are many issues with GUIs. My main one is that lots of things can't be (easily) expressed in the API of common languages. For example you set the colour of something to red? Well, that thing renders in some specific way that calls a callback which in some cases will override the background, so setting the background colour will not do anything. You can't express that in objects, there's really no failure here beyond "you didn't consider every possible layer and combination of features". Yet, whenever I try to create some GUI, I run into an issue like that every few minutes.
- eternityforest 3y agoArmchair psychology warning! Try doing something in Vue, Flutter, or SvelteKit or something... it will probably be significantly easier than what you expect! The hardness comes from the fact that you're basically writing bookkeeping two way state sync code, and if you don't have a reactive framework you're doing it by hand. Plus, there are so many GUI libraries, and the easy ones are big. I suspect GUI haters choose low level stuff, then complain about how hard it is. Or, they might use language without that great of GUI bindings. They might also start out with a specific vision of how it should work, whereas people who find GUIs easy are picking a big popular framework and not really thinking of any ideas outside it's language. I generally don't even start thinking about architecture or code until after I've already chosen my tools, I want to do designs that fit the tools I'm using, not design something and than choose a language specifically for the design. Plus, you cannot build a nice GUI on top of a UNIXY backend without lots of work. For some reason I don't understand, programmers seem to think of computers as devices that take input and produce an output, and build stuff that looks like a compiler tool chain. With GUI, you're not computing an output, you're updating a state based on user input. You generally never want to be in a place where you do things in a sequence, and can't edit previous steps without starting all over. You also can't always have a logical model for what to include. Usually GUIs are not general purpose like raw code is. You're not using a blank canvas to build another blank canvas, which is what most devs seem to like, you're building a curated workflow. You might have "Edit this transaction" buttons and "Export report for the month" buttons. If you're used to thinking in logical layers that build on each other, you might not enjoy essentially recreating some illogical business process in code. It seems like programmers are really code-philosophers and code is like a meditation for a lot of them, and they seem to get depressed and discouraged working on things that don't have any beauty or logic or reason and are just reflections of some messy illogical real world process full of extra stuff to deal with untrained users.
- weare138 3y agoDevs were so preoccupied with whether they could, they didn't stop to think if they should. Our industry seems to have a problem with FOMO and leaving well enough alone. Most modern web GUI frameworks and modern software in general are engineered around buzzwords not usability. We can't seem to just stick with simple boring things that work and constantly reinvent the wheel because we didn't like the hubcaps.
- joeld42 3y agoBecause UI, like build systems, are really just huge state dependency graphs in disguise.
- renewiltord 3y agoIt’s because you need to bubble state through to all components. Implement a spreadsheet to get a grasp of the initial problem. Then consider that you need to partially update for performance. I rarely program GUIs but when I do I use React and it works quite well quite easily.
- tripleo1 3y agoscnr https://www.youtube.com/watch?v=rwt6QsLk06w&lc=UgzT-NnHNpXXQLK4hGh4AaABAg https://www.youtube.com/watch?v=rwt6QsLk06w&lc=UgzT-NnHNpXXQ...
- naruhodo 3y agoWhat exactly is "hard" about it? Decades ago, I used zApp, wxWidgets, Java Swing, Qt and Python GTK bindings. None of those were particularly hard. What blows my mind is how long it took the web to get flexbox (Java GridBagLayout, IIRC).
- firemelt 3y agoits not hard just full off hassle
- o11c 3y agoIt's a combination of 3 things: * Parts are fundamentally declarative and parts are fundamentally imperative. This applies both to the abstract problem, and the approach taken in particular toolkits, and the border is not in the same place. * The state involved is stored in at least 2 places which are distant from each other, and that opens all sorts of logic and timing problems. * The same GUI framework gets used both for "wait for an event" UIs and "update every frame" UIs. Abstraction is hard.
- marsven_422 3y ago[dead]
- dwaite 3y agoThe core of a GUI framework is nearly always written as asynchronous events and drawn responses, with the developer at that level responsible for the state machine in the middle and invalidation of the GUI in response. Coordinating large asynchronous systems by hand is challenging. There can be surprising interactions. For example, tapping a button again in the middle of an animation is an example of something where the complexity often leads to the program getting in a bad state or even crashing. This is one reason that structured concurrency and asynchronicity primitives have been added to many programming languages - to make reasoning about and managing such state machines easier. Some modern GUI frameworks attempt to simplify this by instead let you declare the UI and its relationship with your data, the interdependencies there, and may have sophisticated means to monitor data changes. This breaks you from having to maintain most GUI state within your program - you respond to user actions by updating your program state, and the GUI responds to those updates.
- cookiengineer 3y agoThe biggest issue with GUI programming is always "when to reflow" and "when to relayout". Take fading in sidebars, for example, which influence how the main content frame is rendered and are different in size on mobiles (e.g. icons, icons with labels, bigger icons, bigger labels or even a more nested structure on desktop, with a burger icon for fade-in and fade-out). This is almost impossible to implement if you only have horizontal and vertical box layouting at your disposal, which is the most common denominator among frameworks and their renderer concepts (GTK, Springs, QT, etc). Flexbox and tweenable properties like transparency, rounded corners, margins, paddings, colors and z-indexes are almost a hard requirement these days in terms of UI design. And those features are very hard to implement without a renderer pipeline that can influence both fragment and vertex shaders. And this is not talking about state management of the UI elements, which is a whole world of problems on its own. React Native's approach, for example, is utterly broken on older mobiles due to how they re-flush the whole state tree on every single frame (which makes old mobiles lag due to them not being able to keep up with the amount of FPS required). Getting the reflow right with e.g. calendar widgets and calendar popup views which are rendered by native APIs is a nightmare. As there is no unified way to do it across platforms, there eventually will be a lot of redundancies that are implemented, and a whole lot of quirky code behavior.
- rubymamis 3y agoFlexbox support in QML[1]. Plus, there are some wrappers that make seamless transition between desktop and mobile view like MauiKit[2] and Kirigami[3]. I don't think they're perfect or that they are doing it correctly even, but they're onto something with their main idea. [1] https://github.com/tripolskypetr/qml-flexbox https://github.com/tripolskypetr/qml-flexbox [2] https://mauikit.org/ https://mauikit.org/ [3] https://develop.kde.org/frameworks/kirigami// https://develop.kde.org/frameworks/kirigami//
- sorokod 3y agoThere is a big social component: everyone has an opinion, everyone is an expert. People who are indifferent and uninterested in non UI logic, will speak with confidence and criticize UI.
- bsaul 3y agoi think the nature of GUI programming hasn't been well enough characterized, and thus the tools we use for building them aren't adequate. it's a bit like trying to do DB programming before transaction, and relational algebra were invented. Gui has a lot of conceptually complex properties : - it has both synchronous and asynchronous behaviors ( drag vs trigger an animation or loading data for the next screen ) - it has i/o (the screen) - it is interactive (a user can click at any point in time, interrupting the process) - it has transactional properties (you sometimes want a whole set of changes to be performed atomically, with nothing interrupting it). -it is working both in diff mode ( change just the color of that button) and in whole state change (load a new screen) all of this make the problem quite challenging.
- spit2wind 3y agoGUIs are one giant state machine. Tracking all those states is unwieldy. The best notation I've seen is state charts, as described by Ian Horrock in Constructing the User Interface with Statecharts. Still, it's a ton of work. As a result, everyone I've ever seen just resorts to the 80% solution of coding it up without tracking the states and then playing whack-a-mole trying to make it consistent.
- softwaredoug 3y agoIt's not only stateful, its asynchronous. You have to be idle, to wait for user action, which can come at any time. You're also possibly waiting for other computing processes to finish, then you have to deal with the consequences of whatever state you're in based on what the user has done.
- DeepSeaTortoise 3y agoIMO GUI programming isn't difficult by default, e.g. have a look at LabVIEW. It's just that all of the tooling is beyond exceptionally bad.