“Complexity can be tamed, but it requires considerable effort to do it well. Decreasing the number of buttons and displays is not the solution. The solution is to understand the total system, to design it in a way that allows all the pieces fit nicely together, so that initial learning as well as usage are both optimal. Years ago, Larry Tesler, then a vice president of Apple, argued that the total complexity of a system is a constant: as you make the person's interaction simpler, the hidden complexity behind the scenes increases. Make one part of the system simpler, said Tesler, and the rest of the system gets more complex. This principle is known today as "Tesler's law of the conservation of complexity." Tesler described it as a tradeoff: making things easier for the user means making it more difficult for the designer or engineer.”
― Donald A. Norman, Living with Complexity
I'm not sure I agree that complexity is always conserved. When I design systems, I often find that there's intrinsic complexity that I can't seem to escape, but that my initial designs are often quite poor and also include incidental complexity. If I'm thoughtful, and I learn the domain well enough, I sometimes find I can remove that incidental complexity. Alan Perlis had a couple of epigrams that echo this, I think.
> 31. Simplicity does not precede complexity, but follows it.
> 58. Fools ignore complexity. Pragmatists suffer it. Some can avoid it. Geniuses remove it.
All that said, I've definitely seen cases where trying to insulate the user from the reality of what's happening behind the scenes often dramatically increases complexity. When it's done poorly, in increases complexity not only for the designer and programmer, but the user as well. One well-known example is the progress bar. After 30 years of lying to users about how long that file copy, download, or compile would take, many recent designs simply exclude it and include an animated spinner instead.
One implication of Tesler's law appears to be that it is impossible to increase the total complexity of a system. But this feels intuitively wrong to me after looking at the source code of any ERP project.
Maybe it only comes into play if you try to decrease over all complexity of a system. After a certain point complexity can't be reduced but can only be redistributed.
The Tesler conservation law is like first law of thermodynamics: you cannot destroy complexity, only change its form. Your observation is more like second law of thermodynamics: the complexity of a closed system always grows with time.
I don't know if there's context which might change my interpretation, but from the sound of it, I disagree. This is only true in a closed system. With many things (especially software), we encounter the same types of problems again and again, so we can re-use the same solutions, which allows us to reduce overall complexity.
A program in 1985 likely wrote its own routines for memory management, math, graphics, and so on. Those add complexity. A program in 2020 almost certainly doesn't. The complexity is hidden behind nice interfaces, and more importantly, it's shared among 1000 different programs on my computer.
We traded inline complexity in 1000 places for complexity in <math.h>. That's not the fair trade that "conservation" implies.
Let's say you have some physics problems to solve. Doesn't knowing Maxwell's Equations decrease overall complexity? I don't think anyone would claim you should only learn first principles, and any other formulation only uselessly pushes the complexity around.
It's one of my favourite books and I thought that it paired quite nicely when talking about software like Zapier or Tray.io that try to solve such a complex thing.
I can tell you from first hand experience that it is extremely difficult to ensure consistent, reliable ETL of JSON payloads between thousands of services.
APIs are unreliable. Schemas change with no warning. Data you expect might be missing and data you don’t expect might show up. You would be surprised how often things don’t work as you’d expect them to.
Zapier does have thousands of integrations, and some hundreds of them (the oldest or most widely used) are maintained internally for the best user experience.
These days though, many more are maintained by the API providers themselves, since it benefits them to provide a no-code solution for their users to link their API to thousands of others - a service provider can only build and maintain so many direct integrations themselves. https://zapier.com/platform
I have always thought it would be useful if API providers were able to provide the javascript bundle that Zapier runs under the hood on the dev platform alongside their API at a pre-defined route, so any runner (Zapier, Tray, MS Flow/Power Automate) could consume the API regardless of location (SaaS automation, desktop client, etc). I believe there's even an automation provider that allows you to "one-click" import the integration you've built from Zapier to their platform (the name escapes me at the moment, my apologies).
If the API provider is already maintaining the integration, it's a matter of automation providers moving towards a standard for how to express integrations as the ecosystem matures.
Not as hard as tedious. Here is a trivial example: your application generates a message that informs the user about the number of file copied. Most developers generate the message templated as this:
{N} file(s) copied.
Which kinda works, but not so user friendly because "0 file(s) copied" sounds non-human. It should be "No files copied". What a more UX-focused developer would it is write something like:
match N with
| 0 -> "No files copied"
| 1 -> "1 file copied"
| _ -> "{N} files copied"
The latter is not very hard. It's just tedious work that many people don't do.