Holy Dev Newsletter April 2022
Welcome to the Holy Dev newsletter, which brings you gems I found on the web, updates from my blog, and a few scattered thoughts. You can get the next one into your mailbox if you subscribe.
What is happening
I am busy helping folks with their Fulcro projects so I hadn’t much time for anything else. I am progressing occasionally with the Fulcro RAD Asami plugin but got delayed by having to work around some limitations of Asami. I am also helping to get the Clojure client for Wolfram to the finish line (we need a new repo, code cleanup, and updated docs).
Gems from the world wide web
👓 Tiny and Fast Docker image for Rust Application - AZZAMSA [rust, devops]
Tips: Use a builder image, improve caching and thus compile time with cargo chef, use scratch for the smallest image (here 8MB) or distroless for slightly bigger one (here 30) but with faster recompilation (here 2 vs 9 min).
👓 phronmophobic/viscous: pprint that respects your space and time [clojure, library, tool]
An interactive display for your data, similar to the browser' Console - display only a part of the data, page to see more, drill down,.. I haven't tried it but it looks pretty neat. From the site: A visual data inspector/explorer that runs in constant space, time, and screen space.
👓 Biff [clojure, webdev, library]
An interesting full-stack framework for creating web applications aimed primarily at the lone developer, with the tagline "Launch new projects quickly without getting bogged down in complexity later." There has been a major release now that, among others, significantly simplified the frontend by replacing React and Cljs with htmx. Htmx is an alternative to SPA, a JS library to easily add interactivity and load and replace parts of the web page from the server via htmx' magical HTML attributes. This is worth exploring as a counterbalance to the SPA craze :). The release also adds support for live dev in prod (transfering and auto-loading changes over rsync). Not for everyone but great for some. (Htmx makes it much easier than JS to add even more interactivity to the pages via its companion lib Hyperscript - see the comparison.) I guess that if your frontend needs are somewhat limited then HTMX may be a much more productive choice.
More on Biff - XTDB for persistent data (e.g. backed by Postgres in prod), Reitit for routing, Malli for enforcing schema, Rum with Tailwind CSS for server-rendering web pages, Chime for scheduled tasks.
👓 tech.v3.datatype.char-input documentation [clojure, library]
dtype-next: lightning fast JSON and CSV parsers
"Lighting fast json parsing without the jackson dependency hairball," included in dtype-next. It also includes a CSV parser as a faster alternative to clojure.data.csv. Reportedly:
(In both cases the performance gains stem from not using the pushback reader and writing tight loops in Java. The performance really comes down to how fast you can create maps.)
You can run the JSON parser with :profile :mutable for ± 30% speedup (-> arrays and Java HasMaps).
👓 cnuernber/charred: zero dependency efficient read/write of json and csv data. [clojure, library, data, performance]
Very fast json/ csv encode and decode, a drop-in replacement for clojure.data.csv and clojure.data.json. Same API, much better (5-10x) performance. You can eschew immutable data for additional perfomance boost (possibly 30%).
(Previously reported here in https://holyjak.tumblr.com/post/681241985785430016/techv3datatypechar-input-documentation but not extracted into a standalone library.)
👓 HealthSamurai/matcho: Simpliest pattern matching you've ever seen [clojure, library, testing]
A nice small library for checking that a structure is as expected (you can use simple values, RegExp, spec, predicates), optionally strict.
👓 nytimes/jsonlogic - encode rules in json for sharing, Clj impl [clojure, library, clojurescript, webdev]
Json Logic allows encoding rules in json so they can be shared between frontend and backend. This is a Clojure implementation. As custom operators with multimethods.
👓 You should be reading academic computer science papers - Stack Overflow Blog
Reading papers about programming may help you solve problems better and understand the ways we work more. Papers We Love (and their presentations) might help you with that.
👓 Navigating the Wide World of Data Visualization Libraries [webdev, data visualization, comparison] -
Almost everyone has heard of D3, but what about the others?
A useful overview (from 2020) of the space of data visualization / charting libraries, categorized by their "level of abstraction" and "API type" (framework specific x JSON x JS ...). Mentions Apache Echarts, Vega, D3, and a number of others.
👓 Designed for Digital | The MIT Press [book, company culture]
Designed for Digital offers practical advice on digital transformation, with examples that include Amazon, BNY Mellon, DBS Bank, LEGO, Philips, Schneider Electric, USAA, and many other global organizations. Drawing on five years of research and in-depth case studies. Reportedly a great book.
👓 Packaging Clojure for Production - Metosin [clojure, learning, devops]
A modern (2022) overview of how to packge Clojure apps for deployment, both frontend and back. Backend: uberjar, Docker, check out the git repo. Frontend: baked into the backend app vs. externally. Mostly general consideration that will help you to pick the options best for you but also concrete examples.
A great 3-part series introducing using refs in modern react, with the ref prop (with a Ref object or a callback, when to use which), useRef, wrapping a functional component with forwardRef to allow passing in a Ref holder (so that its parent can get hold of a dom ref to its child), useImperativeHandle & more. I knew little about this topic and hooks and this series did a good job of explaining it to me.
- useRef creates a generic Ref object that can hold a .current value and can be used for anything, not just dom node refs. useImperativeHandle can then be used to change its value so that you can pass back e.g. a map with multiple dom refs wrapped inside a name -> ref map. (Notice the parent passes in an empty Ref object, we pass back a value containing actual dom ref(s)).
- forwardRef is used because ref is a reserved property name used by React and not passed on to the underlying component so you could not pass it from the parent otherwise (but you could pass it instead via a custom property with a different name and not need forwardRef then).
- updating a ref is a side effect so it should be done only inside a useEffect (or useLayoutEffect) or inside an event handler (or, of course, useImperativeHandle)
Thank you for reading!