
Flux is the new WndProc - gecko
http://bitquabit.com/post/the-more-things-change/
======
Todd
I've also observed this similarity. The msg is like the actionType, the wParam
and/or lParam are like the polymorphic objects that you pass with your action.

The dispatcher is also not the most efficient model, where every store is
registered to listen to every event. This is a bit like multiple windows on an
event loop. The difference is that in Windows, messages are almost always
targeted to a particular window's handle (hwnd). This doesn't make sense in
Flux, since it's more of an observer pattern. The logic of interpreting the
meaning of an action is left to each store, which is really just a cache.

The biggest problem I have with Flux relates to this polymophism. I use
TypeScript where possible and this is the one place where it always breaks
down. I understand the appeal of JS objects but the only way to ensure your
Flux based system is stable is to have lots of unit tests around your actions
and stores.

Redux is a more straightforward take on caching. I can also use type
annotations on the reducers and associated store structure, so this helps
ensure structural consistency. It also solves the isomorphism problem of
server side rendering because each request can get its own state. There is no
out of the box solution for this with Flux, since stores are singletons by
default.

Minor nit: stores are just caches with observers. I'm not sure why they
weren't just called caches.

~~~
tracker1
I like how Redux is a pretty simple distillation of some flux concepts... In
the end, I think it comes down to application scale. The "new" way of mutating
models based on OO classes that tend to contain any given amount of logic
tends to be much harder to reason with as you add features. More features
means a linear to exponential growth in complexity and risk of side effects.

With one-way workflows combined with immutable state, and idempotent
components, it's much easier to log/replay/test any given scenario.

------
unoti
The big idea from old school windows that is shared with Flux is the idea of
little views that render themselves and manage their own state. In Windows we
called those Controls or Window Classes. It is a good idea, and one worthy of
preserving.

~~~
Too
I haven't used a single GUI framework that _doesn 't_ have the concept of User
Controls. It's not a big idea, it's the obvious thing to do.

~~~
unoti
If you've ever created a user interface in HTML, you've used something that
does not have the concept of user controls. Let's say that I want to make a
numeric entry user control for entering numbers on a touch screen. This
control will be made up of a collection of built-in UI controls that will work
together to do what I need: let's say a text field, a couple of up and down
buttons, an always-visible keypad, and a little slider that lets us move
between min and max.

In most HTML-based systems, it's not a built-in or natural thing to have such
a self-contained "User Control" that I can just plop in to my user interface
in 25 different places and have it manage itself, and the interaction between
its own sub-components. Django, for example, completely lacks such a concept
(although TurboGears does have it). This is a first class concept in classic
Windows programming, and also in Flux-- although it's missing from most web-
based systems.

~~~
Too
Hehe, i was suspected someone would bring up HTML. Plain HTML is a markup
language designed for documents, not a GUI framework. It hardly even has the
concept of any interaction at all in the first place, how can it then have the
concept of reusable and encapsulated interaction? (jquery is not a GUI
framework either btw, its a DOM manipulation tool). I would say HTML is too
low level to be called GUI framework. There are other low level graphic
frameworks that also lack this, OpenGL for example which is designed for
graphics only, if you want widgets you will have to build that yourself on top
of the low level framework or find someone else who already did.

But yes, you are right that it's quite lacking in this area on it's own.
Although it's easy to find frameworks on top of html that adds this feature.
Google for "HTML datepicker" and i bet you will find thousands of results.
Other frameworks on top of html that does have this concept baked in are
asp.net and anuglar.

------
mpweiher
A couple of corrections:

1) Mac OS X does not store a bitmap for every widget, that's iOS's
architecture. It stores a bitmap for every window. Having a layer (GPU-stored
bitmap) was only introduced once CoreAnimation was ported to OS X. It was and
is optional.

2) OS X Views also have a -drawRect: method that works the same way.

3) In fact that's how MVC works. See
[http://blog.metaobject.com/2015/04/model-widget-
controller-m...](http://blog.metaobject.com/2015/04/model-widget-controller-
mwc-aka-apple.html)

And react and frameworks like it just duplicated this, see
[http://blog.metaobject.com/2015/04/reactnative-
isn.html](http://blog.metaobject.com/2015/04/reactnative-isn.html) In fact,
when I first read about react (non-native), my first thought was "hey, finally
they came up with a good equivalent of NSView + drawRect:

~~~
mwcampbell
Isn't drawRect: working at a different level of abstraction than React? In
React, the view function constructs a virtual DOM tree, which can contain
links, buttons, form fields, tables, etc. The equivalent on OS X would
construct NSControls or NSCells, or objects that ultimately got translated
into those, rather than just drawing on a canvas.

~~~
mpweiher
I saw this as react choosing the obvious way to implement drawRect: inside a
browser: painting with HTML.

You could easily have a "graphics context" that accepts high-level objects, or
a variant of drawRect: that creates subviews and then tells those subviews to
draw themselves.

I don't see this as being fundamentally/structurally different, though there
is a slight difference in the implementation.

------
jowiar
As someone who has written several things with Flux and Flux-esque
architecture, I see it as a step in the middle, rather than where things are
ending. It's not a large step from Flux (Stores update themselves in response
to actions) to Redux (Model the entire application as reducers on a sequence
of Actions) to RxJS Observables.

What's shared in there is the idea that unidirectional data flow is a whole
lot easier to reason about, model, and simulate than 2-way data flow.
Everything else is semantics.

~~~
marknutter
> What's shared in there is the idea that unidirectional data flow is a whole
> lot easier to reason about

It makes _some_ things a whole lot "easier to reason about" (so sick of that
phrase), but other things not so "easy to reason about", like, for instance,
error handling. Getting my head wrapped around the fact that asynchronous
errors had to live in their own stores and be handled in the same way as all
other data passed to the view was certainly not "easy" to reason about and
still doesn't sit right with me to this day. You make concessions with every
pattern and there is no silver bullet.

~~~
jowiar
I'm not saying easy to reason about in the sense of "easy to learn because it
isn't a change from how we used to do things", but rather, in that it allows
one to easily answer:

\- What is the current state of things? \- How did we arrive at the current
state of things? \- What should the UI look like given the current state of
things?

It means that we can say: "Thing A happened, then Thing B happened, then Thing
C happened". And then conceptualize "what should things look like after that
chain of events". I've found this to make errors a whole lot easier about,
because I don't need to piece together the state when an error happens -- just
fire an action that says "An Error happened", then the stores figure out how
to act accordingly. It's just another action.

------
ajsharp
There are some great things going on in React / Flux, but the part that needs
to be emphasized about Flux, that Facebook doesn't address explicitly
anywhere, and that most people eager to always be on the cutting edge will
never admit, is that this stuff was designed to solve problems for _very_
complex applications. Complexity is relative, and the solutions that reduce
complexity and friction in the development process for Facebook may increase
it for another organization. That is to say, Flux / React et al is by no means
simple. Not even a little bit. But it probably simplified __a lot __of things
for the Facebook team. However, YMMV for your 6 person startup engineering
team.

~~~
davidrusu
I'm convinced the complexity comes from the language,

Flux/React are actually quite simple and I can put the core architecture
together in under 50 loc of Elm.

~~~
marknutter
The complexity comes from stitching everything together. You choose your
router, your flux library, your build tools, whether or not to use JSX,
whether or not to write your CSS with Javascript, which fancy new React
specific testing and mocking library you need to use, how to organize your
project, what best practices you should follow, what gotchas you will
encounter because of Reacts relative young age as an OOP library, etc.

You will always have to deal with complexity, it just depends on what kind of
complexity you are willing to stomach. Some people prefer to deal with the
complexity of stitching things together, other people prefer to have things
stitched together for them and deal with the complexity of many abstractions.
Both are fine choices, and we will debate endlessly with each other over which
approach is the best approach. (hint: neither are).

------
estefan
...and so for those of us who aren't Windows developers, what learnings can we
apply to flux to make it better?

~~~
gecko
Well, first, I'd note that React and Flux are already learning from the past.
For example, I absolutely think there are tons of similarities between
WM_PAINT and React's DOM diffing, but there are also major, major differences.
A really key one being that React effectively handles the rendering tree
directly, and can therefore do high-level manipulation and performance work on
it, whereas Windows paint messages forced the windows themselves to handle all
of their state diffing and painting issues. This makes the React part of Flux
a lot closer to things like WPF, or retained-mode 3D graphics. (In fact, it
wouldn't shock me if that were the actual inspiration for React's DOM work,
and that the rest of this is more covergent evolution.)

I'd also note that we know that this style of design scales amazingly well.
You can build and maintain applications as complex as Word, Myst, Netscape,
and so on indefinitely. So we definitely know that this design has some
historical precedent of working really well, and we're probably not way off
track.

That in turn means I think we can answer the "what learning can we apply" by
looking at what worked well historically.

For example, one of the things you have to do is to hide the low-level event
loop. That's what frameworks like OWL and MFC did very early on, and I think
what frameworks like Reflux are trying to do now. You even have some of that
in the form of observers and so on in Flux itself. But I think that getting
those types of things standardized, and a bit higher-level, will help a lot. I
suspect, although I don't know, that ES5 was a bit of a blocker on getting
that in Flux earlier, and suspect that Babel's pervasiveness will let that
situation start changing, but that's entirely a guess.

We also know that, for the overwhelming majority of apps that are actually
written, having a GUI designer building on the underlying framework (e.g.
Interface Builder, VisualAge's form designer, etc.) can both decrease
development time and reduce bugs, and we know that such tools work best with
certain patterns in how callbacks work in the underlying framework.
Specifically, you want one-to-many observers, strongly typed events that can
be exposed and described via reflection, etc. So I'd hope that implementing
that kind of thing in Flux can be done in a forward-looking way from the
beginning, rather than getting bolted on later. More generically, designing
the framework with an eye towards making it tooling-friendly is probably a
really good way to future-proof things from the beginning.

I guess we'll see as we move forward. Each situation is a little different, so
while there are parallels, it's hardly a slam-dunk that things will go exactly
the same. But I do think that keeping an eye towards tooling is a really
logical way to look forward and learn from the past.

~~~
estefan
OK cool. It's not all bad news then.

I think once we see react components converge across web + native we'll start
to see more cross-platform tooling and designers springing up. I think things
are looking pretty bright. Arguably the key insight the react team had was to
treat the browser as a dumb output... and then realise that the DOM could just
be one of many outputs.

I did just wonder whether in the GUI world there was a major pattern that
people were using today that Flux should be using instead. But apparently not.

------
jxm262
This was an awesome read. We use React and Flux daily at work so I'm going to
share this with coworkers. I'm a little confused on what the author's concern
is though.

> I’ve just felt…well, weird. Something seemed off

Is there anything substantively wrong with the flux pattern or drawbacks?

~~~
gecko
_EDIT: I changed that paragraph; thanks for pointing out it no longer fit with
the rest of the post._

 _Original comment_ :

The weakness of typing in the switch blocks. I'll alter that sentence a bit;
it's a leftover from an earlier version of that article where I was going to
focus very narrowly on how uMsg/wParam/lParam, like the way actions are
usually done in Flux apps, are decoupled to the point where it's very easy to
make typing errors. Then I described why I thought they were similar to begin
with, and then axed most of the original post when the entire thing switched
to showing how Flux is an old pattern we've done before. I'll see if I can
tweak that sentence in a way that keeps the flow going.

~~~
DougBTX
Using TypeScript's user defined type guards instead of a switch looks
promising here, inside the 'if' the actions are type checked.

~~~
masklinn
Or better, use Elm (or something similar) and tagged unions. That way you get
type-checking and exhaustive-checking of your message types. You still have a
big match (~switch/case) but now the compiler yells at you if you've forgotten
to handle a message tag or if you're not unpacking the right types from it.

------
narrator
So what is Angular then? Angular seems to me to be more like an ORM for the
view where there's dirty checking of the model and then update events are
dispatched to the external system which is the DOM instead of the DB. Is there
something similar in the GUI toolkit world?

~~~
wmeddie
Angular is very similar to the MVVM style of GUI programming that's popular in
Microsoft's XAML-based libraries (e.g. WPF, Silverlight, WinRT and now UWP).
Which I think is interesting because that's where they ended up. Modern
windows programming doesn't involve writing WndProc functions anymore.

------
arijun
Stemmed from this comment chain:

[https://news.ycombinator.com/item?id=10379199&goto=item%3Fid...](https://news.ycombinator.com/item?id=10379199&goto=item%3Fid%3D10378684)

------
pducks32
See I think Flux is too low-level. I think it's too hard to reason about from
the top level. Not that the architecture is inherently bad—people are using it
a ton–but that things get out of hand way to fast. Regardless I can't wait to
see web development in a year!

~~~
avodonosov
Let's try to predict what it will look like?

My guess: Borland Delphi.

~~~
porker
I really hope so.

~~~
TimJYoung
Our product, Elevate Web Builder, is essentially that: Delphi for web
development.

[http://www.elevatesoft.com/products?category=ewb&type=web](http://www.elevatesoft.com/products?category=ewb&type=web)

------
danellis
I share the author's feeling of déjà vu. I feel like I've seen this article
already. It was a comment posted on HN earlier today. It's kind of fascinating
how someone's comment can get promoted to someone else's blog post in a few
hours.

~~~
jessep
Just to note, it is the original commenter's blog, not stolen. @gecko wrote
"And the comment is now a blog post with more context for those who were lucky
enough never to write raw Windows code"

[https://news.ycombinator.com/item?id=10380508](https://news.ycombinator.com/item?id=10380508)

------
jsprogrammer
And Node is essentially the Windows message loop [0].

[0]
[https://en.wikipedia.org/wiki/Message_loop_in_Microsoft_Wind...](https://en.wikipedia.org/wiki/Message_loop_in_Microsoft_Windows)

~~~
amelius
Yes, phrased differently, asynchronous programming is like non-preemptive
(cooperative) multitasking from the Windows 3.1 era.

------
hoprocker
I love the correlation between modern in-browser development and programming
early personal computers. It's akin to how digital logic abstracts away the
tyranny of E&M physics, but several layers higher, and this time just between
instruction sets/runtimes.

ChromeOS is _kind_ of making this leap, but I really wonder when web browser
ASICs (or equivalent) will start popping up.

------
dustingetz
The author does not understand React :(

> React by itself doesn’t actually solve how to propagate changes

It does actually - you update the state, then React propogates the changes for
you through it's props mechanism. Flux is an extra layer of indirection over
state changes _if you need it_ :
[https://twitter.com/floydophone/status/649786438330945536](https://twitter.com/floydophone/status/649786438330945536)
(edit: I regret my tone here, there is clearly ongoing work in this area and
no widely accepted best practice yet)

Flux is not message passing, React components do not redraw themselves, React
components do not pass messages to each other, Flux only superficially looks
like winapi because of the switch statement in that particular example.

React provides the view as a function of state. winapi is nothing like that.

React is a giant step towards functional programming. winapi is _definitely_
nothing like that.

edit: Windows -> winapi

~~~
Aleman360
> React is a giant step towards functional programming. Windows is definitely
> nothing like that.

Err, that's not entirely true for MVVM apps, where views are just declarative
markup that are rendered (retained mode) based on logical state provided by
data bindings. It's been like that ever since XAML was introduced in 2006.

~~~
dustingetz
MVVM makes ubiquitous use of mutable state which means model change listeners,
callbacks calling callbacks etc, FP/React is about using immutable state to
dodge all these problems by design.

[http://www.dustingetz.com/2013/09/12/comparison-knockout-
ang...](http://www.dustingetz.com/2013/09/12/comparison-knockout-angular-
react.html)

~~~
Aleman360
The point is that in both React and XAML apps, you (usually) don't write code
to mutate the View. In your code, the View is just a declarative construct.

There's nothing stopping you from making immutable ViewModels in MVVM, other
than bad perf (which React would presumably also suffer from on larger apps).

~~~
tracker1
Facebook doesn't seem to perform so badly in terms of a larger app. More
varied components on a page than most applications in general. Most of the
quirkiness I see in FB tends to come from how they deal with eventual
consistency with their backend in order to scale to millions of simultaneous
users.

Most applications don't have the latter problem.

~~~
Aleman360
I bet they do a lot of shouldComponentUpdate, which kills the functional
purity.

XAML control properties do the equivalent of shouldComponentUpdate by default.
Same ideas, just doing diffs in different places.

~~~
dustingetz
> I bet they do a lot of shouldComponentUpdate, which kills the functional
> purity.

functional purity _enables_ shouldComponentUpdate

------
pducks32
Does anyone know of a good place to learn about these different approaches. I
find this so fascinating.

------
amelius
Stated more simply, React is just like "rebooting" your computer after you
have changed the config files. It is, in this respect, quite ancient
technology, except that the framework hits the "reset" button for you.

------
geowa4
I've never liked the comparison of Flux to functional reactive programming.
It's really just good ol' object-oriented design. Actions are akin to the
Command pattern and the Dispatcher feels like a Mediator. Passing callbacks
instead of objects and making a mostly directed graph does not yield FRP.

In my latest project, I used React with rx-react
([https://github.com/fdecampredon/rx-
react](https://github.com/fdecampredon/rx-react)) and RxJS. That combination
definitely made for some FRP fun.

------
sovande
The big dispatcher switch in Flux is eerily reminiscent of how we used to
program AWT widgets back in Java 1.0 days. This architecture was improved
greatly in Java 1.1 with a delegation model. If the history is to repeat
itself, as the OP so eloquent argues for, then, if you want to see where flux
will be going in the next couple of years, start using knockout.js now and for
once stay ahead of the curve.

------
antoaravinth
What a great article. I was asking in my previous thread, what framework
should I use React/Angular :
[https://news.ycombinator.com/item?id=10359497](https://news.ycombinator.com/item?id=10359497)

Clearly from what I have heard from HN and from this blog post is React with
Flux is just the old of doing web development today! Thats great!

------
thewarrior
Which is the best model to date for complex UI ?

Cocoa + Interface Builder or XAML/WPF ?

Have used Cocoa + Interface Builder and its quite a joy compared to web dev.

EDIT :

Has some thoughts on this : [http://stackoverflow.com/questions/2442340/how-
does-cocoa-co...](http://stackoverflow.com/questions/2442340/how-does-cocoa-
compare-to-microsoft-qt)

~~~
gecko
I mean, both of those get things right. XAML/WPF tries to make the interface
cleanly human editable in code, but is incredibly verbose, and the "can be
human editable" constraint ends up being "is only human editable" pretty
quickly. Interface Builder is a lot more intuitive and powerful, but it's more
of an all-or-nothing affair, in my opinion.

Beyond that, though, they have way more in common than they do different. I'm
not sure it makes sense to talk of one of them as a better _model_ than the
other, versus maybe a better _implementation_ of the same workflow.

~~~
thewarrior
According to

[http://stackoverflow.com/questions/2442340/how-does-cocoa-
co...](http://stackoverflow.com/questions/2442340/how-does-cocoa-compare-to-
microsoft-qt)

WPF is better.

~~~
kybernetyk
Well, as there's no Cocoa on Windows and no WPF on OS X it doesn't really
matter.

Also that SO post reads a lot like "I can't stand Interface Builder" (which is
understandable if you aren't prepare to embrace it).

I find the Cocoa model of not having to do anything with XML far better for my
sanity. But then again I guess there are people who prefer XML artistry to
drawRect overriding. :)

------
avodonosov
In this line of reinventing the wheel of UI programming in web dev, I am
waiting for Borland Delphi reincarnation.

------
iMark
I've only looked into iOS programming a little, but is this not similar to how
views are handled there too?

------
jesstaa
Also, Ruby on Rails is Flux.

------
whatever_dude
The writer really likes the word "idempotent".

~~~
tobr
And uses it incorrectly. Idempotence is when f(f(x)) == f(x). React views take
some props and/or state and return a component, so applying the view to its
output would just give an error.

I think the word he's looking for is "pure".

EDIT: I was wrong - apparently "idempotent" can also describe a consistent
relationship between the input and some state. In that sense, it's actually a
very good description of how the input to a React view affects the DOM.

~~~
kgen
Well, even in Wikipedia, the definition is quoted as being different for CS vs
the unary operation you describe.

"In computer science, the term idempotent is used more comprehensively to
describe an operation that will produce the same results if executed once or
multiple times."

Which is more that f(x) == f(x) == f(x) for the state affected by f.

~~~
tobr
Thank you for pointing this out, I was not aware that the word could be used
this way. They are really quite different concepts.

~~~
matchu
I'm not sure that they are. You just need to model the concept of state as the
function's input/output, as functional programmers are eager to do :)

If we start in state x, then apply operation f, the resulting state is f(x).
If we apply operation f again, we'll be in state f(f(x)). If f is idempotent,
then state f(x) and state f(f(x)) are identical.

------
underwater
WndProc is how the windows manager communicates with Windows UI code. Flux is
how the UI communicates actions back to the data layer of the application.
They're completely different.

