author | Alan Dipert
<alan@dipert.org> 2023-12-09 00:59:23 UTC |
committer | Alan Dipert
<alan@dipert.org> 2023-12-09 00:59:23 UTC |
parent | 8799e04749ea6671803fd5bcf7ec954d5823686b |
{posts => drafts}/10-years-of-hoplon.md | +84 | -1 |
diff --git a/posts/10-years-of-hoplon.md b/drafts/10-years-of-hoplon.md similarity index 57% rename from posts/10-years-of-hoplon.md rename to drafts/10-years-of-hoplon.md index e4e4180..f8ec4a8 100644 --- a/posts/10-years-of-hoplon.md +++ b/drafts/10-years-of-hoplon.md @@ -7,7 +7,90 @@ abstract: | It's been 10 years since the Hoplon ClojureScript libraries were announced publicly on the Clojure Google Group. This is a retrospective. --- -It's been just about 10 years since Micha Niskin and I [publicly announced Hoplon](https://groups.google.com/g/clojure/c/gRFyzvRfPa8/m/YIjGA63N_XkJ) on the Clojure Google Group. I thought it would be fun to reflect a little on Hoplon's beginnings and history, and also to share some enthusiasm for the future of Hoplon and ClojureScript. +December 18th 2023 will mark a full 10 years since Micha Niskin and I [publicly announced Hoplon](https://groups.google.com/g/clojure/c/gRFyzvRfPa8/m/YIjGA63N_XkJ), a Clojure and ClojureScript framework for building Single-Page Applications (SPAs). + +I am pleased to report that while I've been almost totally uninvolved with Hoplon since 2017, the project is very much alive, and remains thoroughly defensible as a means to build SPAs in ClojureScript in 2023. + +I thought I would take the opportunity this month to write two short posts about Hoplon. This, the first, is a quick update and design retrospective. In the next, I'll try to capture some of the exciting things happening between Hoplon and [Scittle](https://babashka.org/scittle/) thanks to [Michiel Borkent](https://www.michielborkent.nl/) and [Marcelo Nomoto](https://github.com/mynomoto). + +## Hoplon Quickstart in 2023 + +Hoplon has changed some since we first released it. The biggest change is that it's no longer coupled in any way to the [Boot](https://boot-clj.github.io/) build tool. These days, Hoplon projects can be [quickly scaffolded](https://github.com/hoplon/hoplon#quickstart) and built with the excellent [shadow-cljs](https://github.com/thheller/shadow-cljs). + +If you want to understand Hoplon quickly, I recommend [Daniel Neal](https://twitter.com/DanielNeal2)'s [Reactive web apps with Hoplon and DataScript](https://skillsmatter.com/skillscasts/5380-reactive-web-apps-with-hoplon-and-datascript#video). This was the first public presentation of Hoplon's capabilities, and remains my personal favo**u**rite. Despite being given back in 2014, and aside from a few details, the talk remains a viable introduction to the ideas and mechanics of Hoplon. + +If you're thirsty for more, and curious in particular about how exactly Hoplon relates to React, I can recommend [Micha Niskin's Hoplon and Javelin, WebDev Alternate Reality](https://www.youtube.com/watch?v=UoZyyo2Bwr8) from 2015. + +OK, now on to the retrospective part. + +## Two Decent Ideas + +Before I get into what Hoplon got right, I must say that not everything about Hoplon is still relevant or has otherwise held up. Requiring use of a new build tool and promoting an XML syntax for ClojureScript are two ideas Hoplon has since set free. + +That said, I think we knocked these two things completely out of the park: + +1. Strict ("push") propagation of reactive values in Javelin (instead of lazy aka pull). +2. ClojureScript functions for HTML (HLisp). + +## Push Propagation + +The author of any FRP-spreadsheet-"reactive"-ish thing is confronted with a big decision up front: should updates to the dependency graph be processed immediately after new data is introduced, on write? Or, should the necessary computation happen on demand, when some value of the graph is read? + +The first kind of value propagation is variously called "strict" or "push", whereas the second kind is often called "lazy" or "pull". Each way offers a different set of tradeoffs. + +Push attributes: + +- Mostly static dependency graph +- No conditional dependencies +- Any side-effects occur on write + +Pull attributes: + +- Dynamic dependency graph +- Conditional dependencies are free +- Any side-effects occur on read +- Multiple writes on the same call stack are implicitly transactional + +Back in 2013, "pull" was the preferred approach in the JavaScript ecosystem. Both Meteor.js and Knockout used pull, and were highly influential. + +## HLisp + + + +## Dormant but not forgotten: Boot + +Hoplon required a build tool because we thought that XML syntax like JSX for ClojureScript was good to have, and even the best default. + +Of course, our XML syntax for ClojureScript wasn't JSX exactly, as we conceived of our "hlisp" syntax independently. However, we saw in XML syntax the ability to represent Hoplon programs using a syntax that cooperated with other web development tools, and that was hypothetically friendlier to designers. + +Ultimately, our effort to promote a new syntax served only to raise red flags with the Lisp faithful, while simultaneously not especially wowing the designers we worked with, as sizeable ClojureScript knowledge was still requisite to working with the XML. + +Thus, the build tool requirement was probably a net fail that dissuaded many potential early adopters. + +Post-separation, with Boot 2.0, Boot took on a life of its own independently of Hoplon, but now lacks a maintainer and has gone dormant. + +## Talking to the Server + +In our early Hoplon apps we struggled + + + +In my opinion, two particular design decisions held up remarkably well: + +1. Strict (not lazy) reactive value propagation + +FRP/spreadsheet/"reactive" library authors must choose between either strict or lazy propagation semantics. Strict propagation means that any computation needed to produce derivative values is performed when new values are written. Lazy propagation means that computation is performed "on demand", when an attempt is made to read values. A little work is still usually performed on write, such as marking root values "live". + +The vast majority of reactive libraries intended for use with UIs are lazy. I think this is for two reasons: + + a. Lazy systems are more tolerant of dynamic dependency graphs. Computation is never performed for subgraphs the values of which are never demanded by the consuming system. Since the consuming system is usually a UI framework with knowledge of what is and isn't visible to the user, lazy systems + + +2. Code (not data) for HTML + +The first decision, to separate data representation from DOM/UI concerns, + +I thought it would be fun to reflect a little on Hoplon's beginnings and history, and also to share some enthusiasm for the future of Hoplon and ClojureScript. # Setting the Stage: ClojureScript