<No one actually wants simplicity> &gt; The reaso...
# linking-together
e
No one actually wants simplicity
The reason that modern web development is swamped with complexity is that no one really wants things to be simple. We just think we do, while our choices prove otherwise.
later, continuing…
The same is often true of complexity. The real test is the question “what are you willing to sacrifice to achieve simplicity?” If the answer is “nothing”, then you don’t actually love simplicity at all, it’s your lowest priority.
When I say “sacrifice”, I don’t mean that choosing simplicity will mean you are worse off overall – simplicity brings massive benefits. But it does mean that there will be some things that tempt you to believe you are missing out.
Looking beyond the inflammatory fun title, how do ya’ll think this relates to the future of coding? Is a reason that visual programming is often just around the corner because folks aren’t willing to shed some of the complexity (read also as “power” or “flexibility”) of existing programming systems?
g
IMO, you can have both. It’s not either/or. You need the complexity of full solutions, you just don’t want to ingest all of the complexity in one big gulp. UNIX’ hierarchical file systems overcame the complexity issues of DOS’ flat file system. Lisp overcame the complexity issues of very long lists (lists are defined recursively). Hardware people learned early on that PIC - relative addressing - was a better way to express branching. Much of what we see in modern PLs inhibits layering, eg. inheritance with method overriding, functions that name other functions, etc., etc.
m
There was an alan kay quote something along the lines of “simplicity” can arise from slightly more sophisticated building blocks. I see a lot of replies to this article advocating for absolute simplicity - simpler building blocks, and less code etc. But we don’t have many great examples of good building blocks in mainstream application development. Designing good building blocks is very hard, so many people reject them all together. I think this is a marketing issue, better building blocks obviously exist given the examples Paul gave. But FoC projects need to effectively show how your new building blocks are 1 - simple to understand, implement & use, & 2 - implications on existing hard problems and how classes of complexity just disappear from the POV of the new building blocks. Most people just see a structural editor and think “that must be super complex” and don’t see the beautiful simple underlying abstraction & implications on simpler plugin development & tooling.
g
The idea of snapping building blocks together is easier when only one simple type is used. LEGO == “round peg” into “round hole”. The UNIX idea of a simple inter-command type - characters delimited by newlines - is already too complicated (!). Workarounds to handle binary data instead of 7-bit ASCII bytes were invented, and, then, came Unicode. It is possible to build up more complex types using layers of types. Types in networks are layered this way. Types in PLs are not layered in the same manner. IMO, the concepts espoused in something like the OSI 7-layer model need to be applied to programming. My feeling at this time, is that a software Message for coupling software components is (1) a Tag and (2) Data. One can complexify on the way up and simplify on the way down. Type checking and type stripping can be done by software components, but, the components need to be isolated from one another, e.g. free from hidden and visible dependencies (aka “0D”, anti-CALL/RETURN). The premature-optimization crowd can be mollified by allowing some components to be optimized out at “compile time”. We have all of the tools, we just don’t bother to organize this way. In the same way that we wrote spaghetti code when everything looked like a GOTO.
w
Speaking of spaghetti... As tangled cords prove, simple doesn't not mean easy or natural.
s
Is simplicity an objective property of a system that is just hard to define? Or is simplicity somehow wrapped up — at least partially — with our subjective experience of it and is that why we have a hard time agreeing on it? The article picks up on this issue, but then concludes that if it is partially subjective, we still just have to agree on how to deal with it — but that is the problem, not the solution. There is an aspect of legibility to a system where different people might fundamentally disagree and no agreement seems possible (Emacs vs. Vim, Lisp vs. Forth, tabs vs. spaces, etc.). It often looks like it’s just an agreement issue and one side (of course, usually the other) is somehow confused and can’t see the “truth”. But what if that is a flawed perspective to begin with? What if there are emergent properties that are only ever clearly defined by their current context and not fully generalizable? Similar to how many organisms are well adapted to their environment, but it means different things for different organisms in different environments. If you drop a shark, a well adapted deadly predator at a fairly high spot in the aquatic food chain, into the middle of Sahara desert, it’ll be dead within seconds. Maybe when a system appears simple to us, we are just like a shark in water. Everything looks just fine over here. But try to teach that to a camel in the desert…
k
My unproven and probably unprovable hypothesis is that much of complexity in software comes from believing that "software" is a useful category to think about, independent of context. From an engineering (as opposed to philosophical-mathematical) point of view, an embedded computer in a washing machine has pretty much nothing in common with a Web browser, and a climate simulation has nothing in common with Dungeons & Dragons.
m
Thinking about this again. I think another angle to look at this is maybe not simple-complex, but learnability. 2 sides to learnability 1 - Learning Curve • One of the most powerful learning tools is analogy because it gives us a sense of safety (oh its the same, but X has shifted). ◦ Going from C -> Haskell is hard, but C -> C# -> F# -> Haskell is doable. 2 - Automated Learnability • If my language could statically analyze changes in my library or maybe even the core language, breaking changes wouldn't be a big deal because it could automate most of the refactoring and leave holes for manual work. Makes it feel like a git merge instead of rewrite it from scratch. • What if libraries shipped with onboarding tools to make a sample app • What if libraries shipped with static analysis tools to assist you in what's the wrong path vs right path It's very hard to make a judgement call of complexity to a new system without deeply learning it, so if we can't learn it, the simple-complex debate just becomes "how familiar am I with this"
s
Yes, I think you’re on to something here. “Learnability” is beautifully merging the objective and subjective parts of legibility or intelligibility. There is stuff that can be done that makes it objectively easier to grasp. But then there is also a lot of experience you already have, and dependent on what your experience is, you might find it easy to learn, or you might find it “doesn’t really make sense” — and that’s how you often end up in a polarized situation I described above.
k
@Marcelle Rusu (they/them) Automatic refactoring upon breaking changes is supported by a framework in Pharo Smalltalk. I find it a mixed blessing. It's nice to see uninteresting dependencies being taken care of automatically, but when it rewrites my own code, that's somewhat disconcerting.
More generally, your comment reminds me of

Rich Hickey's talk "simple made easy"

. He insists (rightly, in my opinion) on the difference between "simple", which is an objective (though hard to measure) characteristic of a system, and "easy", which is relative to someone's personal experience. I find that today, "easy" is overvalued by adopters and underestimated by revolutionaries (which I think most of us here are to some degree). I hope that at some point, technologists will actively try to strike a balance between "new, better, but unfamiliar" and "learnable by a large part of my audience". My impression is that today, most technologists clearly value one above the other.
m
Sometimes I use the term "accidental simplicity", when I've designed something well enough that I find power I didn't know existed, when pieces fit together in unexpected ways. I'll try to think of some examples.
One example from my programming language, Kopi: Many languages have string interpolation such as
"Hello, ${name}, how are you?"
. I like to keep things as simple as possible and look for opportunities, so I used function application (via juxtaposition) to concatenate strings. The previous example would be
"Hello " name ", how are you?"
. It doesn't require any special syntax or even a change in the language grammar. There's always a possibility of going too far, though, and abusing the language or writing odd/counter-intuitive code.
m
@Mike Austin I was shocked at how good
str
in
clojure
felt for this. I have removed need for comma in my language & found many similar moments. Tiny things like this really bring me joy 🙂