stevebmark's comment got me thinking about UI technology in general and computer science.

The thing about UI ... it's just, plain, _hard_.

There's not much more to it then that. "UI is hard". User interfaces, no matter if they're text based or graphical, are perhaps the most frustrating field of computer science. They look simple. "Oh, this is just a bunch of boxes and text. I can bang that out in an hour!" three weeks later. Sound familiar? It's that illusion of simplicity that drives programmers crazy. UI has, as far as I can tell, the highest ratio of perceived simplicity to actual difficulty of any other computer science field.

So here we are. We have several decades worth of computer science under our collective belts. Over the plethora of decades that our field has existed we've: invented the transistor, made it the size of a handful of atoms, flew to the moon and back, beat humans at chess and Go, can make video calls half way around the planet, and have crammed unthinkable amounts of technology into our pockets in the form of smart phones. My house bends to my very _voice_ thanks to modern computer science.

But in all that time ... UI is still hard.

I don't think a lot of programmers stop to think about that. Maybe, just maybe, all this thrashing about with UI libraries has more to do with the fact that UI, as a computer science problem, is perhaps one of the most complicated, impenetrable problems we've come across. The perceived simplicity of the problem so often blinds us to that fact.

I believe it stems from a shared "ancestor" with multi-threading: concurrency. Every programmer knows and fears the problem of multi-threading, but they don't fear UI in the same way. Yet, these two problems are more alike than not. A UI is a system that is filled with concurrent, unpredictable, events and threads that could happen in any order. That's a multi-threaded system.

So it's no surprise when viewed like this that UI is hard. It's very difficult for us to reason about a multi-threaded system. Even the best engineers in the world make "obvious" (in hindsight) mistakes when they build concurrent systems. Look at all the bugs that pop up when researchers attempt to do formal verification of concurrent primitives implementations.

So if it's impossible for us to reason about UI, as a concurrent system, then what do we do?

My time spent with Rust, the programming language, has given me some theories. Rust is most popularly known for its memory safety, but its true power lies in its type system. Rust is the first language I've encountered to expose to the user an advanced type system in a practical way. Languages like Haskell et al have of course had these advanced type systems for _decades_. But Rust offers them in a way that is digestible and ergonomic. For us common folk at least. It's perhaps the first chance that we as an industry will have at a widely used programming language with advanced typing and static analysis.

That advanced typing system is what gives Rust its true power. Most salient to this discussion is its usage of the traits Send and Sync. These two traits allow us to communicate to other engineers and the compiler that "this type is safe in these concurrent scenarios." Suddenly the frightening world of concurrency blows apart. Instead of being afraid, you can be fearless. Write whatever code you want and then the compiler will check it and prove (in a limited sense) that your program is correct and safe.

It's an incredible shift for programmers to have this power. Send and Sync are a small step in a new direction: being able to leverage static analysis by the compiler to assist programmers in designing their systems. Before, in e.g. C, it was up to the programmer to think about all the state of their program in their head. At best we suck at that, especially in complex scenarios like concurrent systems (and UI!).

Now we have tools that can augment our mental facilities. In the same way you don't have to think as hard about memory in Rust as you do in its ancestors, you don't have to think as hard about concurrent systems because the compiler and the libraries and types we build alleviate the number of problems we need to think about.

I believe that it's possible this road that is leading to a brighter story for concurrent programming is also leading to a brighter story for UI. Rather then having to think about _all_ the states that a UI and its backing state machines can be in, we instead build type systems that allow us to describe how we believe the system should look in our heads. And then the compiler will do the dirty work of proving our assumptions correct. Our compilers will be 1000x better then us at considering an exponential number of states that a UI could be in given its concurrent and unpredictable nature.

So just imagine a UI framework built on top of an advanced typing system. We could do insane things like using the typing system to say that certain View elements should only be visible given certain states in our model. For example, the Logout view should never be visible when the user isn't in the LoggedIn state. And the advanced typing system, combined with the compiler's static analysis, checks all of our state machines to prove that Logout will never be visible unless the LoggedIn state is active.

It's crazy, right? But I think it's possible. Just like Rust's lifetime analysis can prove when certain objects will be alive so that the borrow checker can check all your references are alive and safe. I don't think it's so crazy to imagine a future where the compiler can determine the lifetimes of a View and make sure they aren't referenced in certain states.

Anyway, the most important thing I wanted to communicate is that UI is hard. Really hard. And we shouldn't forget that. We should approach UI with the same caution and respect that we do multi-threaded programming. Perhaps with that mindset less programmers will fall into the trap of frustration. That trap that has led so many to believe that it is our libraries and frameworks that are broken, and to go off and build yet-another-framework in the vain attempt to "solve" UI without making any real attempts to innovate on the core computer science problem that is UI.

P.S. I'm not terribly good at communicating the strength of Rust's type system and underlying compiler. There's just something magical about Rust that makes it easy to write an API where A) it's obvious to users how to use it, and B) it's a compiler error to use it wrong. It's not any one thing and it's easy to compare Rust to other languages. So I'm not people will reply with "but language X has feature Y just like Rust; how dare you argue that Rust is some kind of revolution!" Oh well.

I'm also sure some will come along and take issue with my assertion that Rust makes memory management easier. Rust makes memory management easier only if you take the time to consider the full story. That is to say, it's quite easy to manage memory efficiently in, say, C. But to do it _without_ bugs? It takes _decades_ to write a C program with no memory bugs. Yet I can write the same program in Rust and the compiler will _ensure_ memory is managed correctly. (Within certain limits, it's possible to leak memory, etc, etc.)