I'm on a campaign to find a solution to the web:
One of the great things about very robust and powerful abstractions is that they can give you tremendous leverage. The leverage can be so great that you can build something much greater than the sum of its parts. However, I worry that the web is an end to this kind of abstraction. I'd like to explore why that is and what we can do about it.
Bootstrapping
In the 19th Century, Charles Sanders Peirce, the father of Pragmatism and Semiotics, was struggling with some very deep questions in the philosophy of mind. Two of those questions were: How can a flawed/limited mind make itself smarter? And how can a spoken language be developed that refers to abstract concepts when the language doesn't have words for it yet??
Peirce's answer to both of these questions was that we can bootstrap. For example, if we have basic literacy, we can read books just beyond our current level and pick up new vocabulary and concepts. We use those new vocabulary to read more books, ad infinitum. Similarly, given enough concrete icons and indices (which are easily learned), we can define abstract concepts with them and assign arbitrary symbols. Thus we can invent new words, explain them to others, and use them to speak abstractly.
We start with a limited set of capabilities and, building with those, construct an expanded set of capabilities. I call this the Bootstrapping Mindset. One of the reasons I like Lisp is that it is a manifestation of the Bootstrapping Mindset. It's not unique to Lisp, but that's where I first saw its application in programming.
To summarize the last linked article briefly, Lisp starts with a few primitives easily defined in machine code. You construct an interpreter using those primitives. And now you have an executable lambda calculus. The leverage from that process is amazing.
Let me put it another way. Let's say you could write some algorithm in 10,000 lines of machine code. Great! You could also write a small Lisp implementation in 1,000 lines of machine code. Then you can write your algorithm in 10 lines of Lisp. Given a big enough project, you should build your own tools. Investment in tools will pay for itself many times over.
You also see this phenomenon in FORTH (build a small set of words and a way to define new words) and Smalltalk (build a small set of message interpreters and a way to define new interpreters).
In all of these examples, we have a "vocabulary" that is expanded by using the vocabulary itself. A great example and explanation is Growing a Language. Guy Steele explores the idea of how we can make a language that is not limited by our current understanding. The future potential of the language is limitless.
To my mind, Turing Machines are bootstrapping engines. Once you've got Turing-completeness, you can interpret any language. The differentiator is expressivity. Which bootstrapping steps get you to where your problem is trivial?
In all of these examples, we find a huge leap in expressiveness. We want to build something powerful enough and robust enough to very rarely (if ever) deal with the lower levels. I can write Clojure code all day and never think about the JVM bytecode, let alone the machine code that is actually running. When was the last time you debugged your code's NAND gates?
Here are my two requirements for bootstrapping. I call them:
- Leverage: Quantum leap in expressivity.
- Robustness: Rarely deal with the lower level.
If you don't have these two things, it might be very useful, but it's not bootstrapping.
The Web
So here's my original concern: can we bootstrap on top of the web? I believe we desperately need it. We are spending billions of dollars each year on the silliest problems of our own invention. And I'm tired of the tedium of working at such a low level. Yes, the web is a great economic force for good in the world, but the amount of crap work it generates is staggering.
Let me give an example of the "crap work" I'm talking about. We have at our disposal very powerful graphic design tools like Adobe Illustrator and Sketch. We can draw freely and make things as beautiful as humans can. Even if we limit our work to only what is possible on the web, we then manually compile that design into angle brackets. It is a specialized skill, with conferences, books, trade magazines, and training, to be able to turn a design into something that your browser can use. I respect the people who do it, because it's very hard. But I cannot respect the need for people to waste their time learning the magic incantations that make your design work in browsers. The fact that we do not see a great tool that outputs HTML + CSS directly is a bad sign.
Let me dig into this even more, because I don't want to give the wrong impression. Making stuff work in browsers is important. But actually getting it to work is way more work than discovering how it should work, which is the actual work of design. We can't focus on what's important: turning pixels into an expression of our humanity. Why not? Because we can't get it to render correctly. We're talking about unimportant minutiae like the best way to select an element in CSS. Should you add a new class? Or use nested selectors? There is no good answer because they all suck, and so we fight over it and call it "philosophy". Or we wait for committees to add yet more stuff to the standards which still doesn't solve the problem.
Let me put it another way: people have written custom layout engines in fewer lines of code than your average PHP page. We lob wrapper divs and CSS rules in our fight against the browser.
I'm not complaining that writing HTML, CSS, and JavaScript is a drag. Machine code can be a drag, too. But I can escape machine code by bootstrapping. The problem I'm talking about is: I don't believe we know how to bootstrap out of the web. If we could, we would make it more alive and infused with our values.
Now that I'm totally bummed out and have sufficiently defined the problem and what I'm looking for, I think it would be useful to likeminded searchers if I go over what I've found in my search.
Obvious non-solutions
These projects are great, they're just not what I'm looking for.
Flexbox
Flexbox is great, but it's not the last thing I need to finally stop writing CSS because I have abstracted over it. Instead, it just makes living with CSS more comfortable.
Bootstrap
Yes, what a fitting name! Bootstrap promises something: use their HTML and the CSS just works. I'll also throw in all of the similar frameworks under this heading since the analysis is the same.
It's not quite the total solution I'm looking for. It's a bit like giving someone a tent to solve their home mortgage problem. You're still dealing with HTML, URLs, and all the rest. For quick web projects, I still turn to it, though.
Ruby on Rails
I remember when I first saw that build a blog in 15 minutes video. Wow! I was so excited. Back then, 15 minutes was unheard of.
But 10 years later, I overhear what Rails programmers complain about: how to write their templates, how to write their CSS, how to set up their routes, etc. In other words, they're using powerful tools to make the web more comfortable. They have not escaped it. Throw in some other well-known frameworks here, including Pedestal, Luminus, and Yada.
Garden
Several people have responded to my search with tweets about Garden, a library for generating CSS with Clojure. While it does give you the ability to use powerful logic to output CSS (high leverage), I don't see it giving you any ability to bootstrap out of CSS (low robustness). For example, could you give me a general solution to centering a div using Garden? You're still dealing with the difficult semantics of CSS.
Hopeful partial solutions
Hoplon
Hoplon is a ClojureScript web framework. It does several interesting things.
- It makes DOM elements into functions so they can be used in code like regular functions.
- It makes your elements reactive to changes like spreadsheets.
- It makes your client-server communication look like function calls.
It turns out that these three features together help a lot. And it gives a good foundation to build on. Let's see where this project goes.
Hoplon UI
I'm keeping my eye on this project. The premise is simple: if you just wrap all of your divs in two more divs (which you're probably doing a lot of anyway with wrapper
and container
and inner
divs), you can "solve" layout with a bit of JavaScript. And those wrapper divs can be made automatically with a few more lines of code. It turns out that this is fewer divs than you would write if you did it by hand! I don't quite understand it yet but it's kind of exciting. I'm proud that this comes right out of the ClojureScript community.
Grid Style Sheets
Solve layout with a Cassowary constraint solver. It's a custom layout engine that is more expressive than CSS for layout. And it's got a declarative language for building the constraints. It definitely has the Bootstrap Mindset. You're still living in HTML + CSS, but it acts much more like you think it should.
Pollen
I am awestruck by this project. It produced Practical Typography, a beautiful online book. The pages look like hand-tuned HTML by a seasoned professional web designer. The author wrote his own authoring format using Racket (a Lisp) that outputs to HTML + CSS. It definitely has the Bootstrap Mindset. It highlights the value of writing your own tools and that maybe the problem is that we haven't peeled back enough layers of the stack.
React
I mention React here for its philosophy and its potential. It managed to find a high-leverage abstraction to bootstrap out of error-prone DOM manipulations. That was a serious pain point of the web. And the same abstraction is being used on "native" platforms like phones and desktops. With React on the web, you're still living in HTML and CSS land, but it's way better than setting innerHTML
by hand.
From REST to CQRS with Clojure, Kafka, & Datomic
This is just a talk at Clojure/conj in 2015. He's talking about the stack he's using, but there's an important bootstrap embedded in it. He's bootstrapping on the web as a communication protocol. He defines a single endpoint that accepts POSTs and a Server Sent Events endpoint. The POST endpoint is for sending commands (capturing the intent of the user) and the Server Sent Events endpoint is for updates from the server. That's it. No more fiddling around with URLs and "routes". This is a true bootstrap. High-leverage and high-robustness.
Conclusions, a glimmer of hope, and a plea
Bootstrapping is a beautiful phenomenon. We can transcend our current limitations using nothing but our currently limited abilities. It is a wonderful expression of our humanity. However, are we investing our web apps with humanity? Or are we toiling away in the bracket mines, fixing our CSS, choosing how to name our wrapper divs, and solving problems, yet again, that we created?
The purpose of bootstrapping is to solve that problem once and for all, so that we can focus on what's important. We can take a long walk, or we can "fill [our creations] with ideas, and emotions, and humor, and warmth." (quoted from Reversing the Tide of Declining Expectations, Matthew Butterick, TYPO Berlin 2012.) We need to do that more than ever, for the world and for ourselves.
We live in an interesting time. I've been waiting for a long time to see how Clojure (or any Lisp, really) is going to transcend the web. It has so many great tools! And the community understands the Bootstrapping Mindset. Yet I haven't seen the bootstrapping happen. Can we make it happen? Can we peel back the layers and build an engine for expressing our humanity? What kind of expressivity do we want? Our imagination is the only limitation.
If you're interested in the Bootstrapping Mindset, the big ideas in Computer Science, or Lisp, you should check out the PurelyFunctional.tv Newsletter. It's a weekly romp through the history, present, and future of Lisp and functional programming.
Top comments (17)
I think Elm in general and elm-style-elements in particular is a solid and hopeful partial solution. Elm-style-elements abstracts away selectors and provides a cleaner interface to the rest of CSS (notably completely ignoring some parts of CSS).
👍
I am using Hoplon + Hoplon UI. I found it (and Clojurescript), coming from front end design, after years of searching for a way out of the tarpit of css (minimal graphical semantics, buggy incomplete browser implementations, object declarations redundant with html structure).
Hoplon provides all the normal semantics of HTML + CSS, but unified in a responsive evaluation environment with javascript/clojurescript. So for example, you can use any programming logic or page state to modify your css, real-time (kind of like SASS, but instead of the SASS DSL, you have the full language power of clojurescript, and it's also available in the runtime state of page). Thus CSS is liberated from a static design declaration, off to the side, to a finely-grained design semantic that can be woven more directly into your living page.
With the walls between CSS/HTML/JS broken down, you are free to build up your own abstractions that leverage any or all of these pillars... And your abstractions will likely carry the semantics of their purpose, rather than their implementation in said CSS/HTML/JS. So per the article, you have bootsrapped a LISP onto the browser, which allows more articulate and robust languages for design.
Hoplon UI takes the Hoplon (Clojurescript-DOM) platform, and starts building more sane design components on top. It is a palette of logical design primitives, that goes as far as developing a custom box-model to ensure that these primitives perform as expected. You can tune DOM elements directly with a full suite of attributes that currently include most of the CSS and Jquery properties. This makes it trivial, for example, to do rather sophisticated conditional styling (for responsive design, etc). It further encourages you to regard CSS as an assembly under-layer, and speak design experimentation in a richer, higher-level markup.
Hoplon UI is not the end of the road. It aims to merely provide better design primitives. Those primitives will be used, along with other clojurescript code to do things like gss cassowary constraint solving (clojure has some neat logic-programming libraries), and bootstrap (built-out libraries of opinionated ui components).
Sorry for the longish rant, but this article echoed a deep resentment I also felt, about the punishing and castrating nature of browser-based web designed I experienced since the IE6 debacle, having come from a print-based graphic design background where the tools mostly just worked, and you could get on with your creativity without becoming a heroic hacker. Clojure and Hoplon still have some sharp edges, but after a long search and trial phase, I found them to promise salvation for me as a creatively minded web designer.
Awesome, Ryan!
I don't know if this is exactly what you had in mind, and in hindsight I realize it's a little React-y but I made a quick demo of a thing that takes in a single object and produces an HTML view
In the future I want to research and see if I can use a Proxy to build in data binding off of having the user code manipulate the master object.
I agree with you that CSS is broken. 14 years ago I was told to stop using tables for layout, then given a partial replacement, and now 14 years later we have Flexbox which finally provides similar layout control.
However, I would also say that modern dev is more akin to system integration than bootstrapping.
Yeah, as Alan Kay has said, there hasn't been a new computing invention since 1980. We're not bootstrapping anymore, just piling rocks.
stackoverflow.com/questions/432922...
The CSS-in-JS projects are exploring a very different approach to CSS: medium.com/seek-blog/a-unified-sty...
This has a number of interesting properties that aren't available in normal CSS, such as proper namespacing.
you cant fix css! css is human by design. humanity is subject to a very strangely unpredictable but deterministic way of things evolving over time. the best you can do is find something that works in a small, not-universal scope, such as what people are doing with LESS, SASS, css-in-js, jsx, whatever.
if you "fix" css, youre essentially applying subjective standards to about 20 years of work. think of all that time people spent, trying to determine who to subjectively make facts
Maybe I'm missing something but doesn't CSS Grid Layout solve your problem?
I'm not sure. Does it mean that one day I won't have to write CSS the way I don't have to write machine code?
It depends, CSS isn't going away.
If you combine the CSS layout grids (or any other CSS) with web components you're effectively creating a reusable object, you can pass values to it programmatically or directly, you can even generate the entire WC programmatically.
Semantically, everything has more meaning and it's completely modular.
Nice article!
This is a good article un many ways!
Great article, but I can not stop thinking about GWT. Where does it play in all of this?