RSSAmplifier

Blog

dosync

swannodette.github.ioRSS feed ↗49 posts

Latest posts

Not Slop

Year in Review A list of things that didn’t qualify as slop in 2025. There’s a loose thread of conviviality running through some of the things here that I would like to explore further in 2026. Not Tech Books The Last Samurai I can’t say that I’ve ever read anything quite like it. Both stunningly beautiful, laugh out loud funny, and full of fresh formal hijinks. Benito Cereno Melville saw clearly…

Aimless

I’ve been doing Clojure long enough that I remember when Clojure was just a JAR provided in a ZIP file. As I much as I benefit from all the work around modern Clojure tooling, it was less ceremonious in the old days to play around without big plans in mind. During the 2025 Conj Clojure Tooling Working Group meetup (coordinated by the awesome Christoph Neumann), Rich Hickey said that Clojure should…

Bury Buffer

I’ve been spending a lot more time recently with Emacs. While I never gave up on org-mode , my Emacs usage had otherwise been in decline. A few months ago, I started experimenting with some “new” affordances: vertico , marginalia , orderless , consult and embark . The combined UX of these tools was impressive, and unlike similar functionality in, say, IntelliJ, could be used in far more contexts.…

A Tool For Thought

As ClojureScript nears its fifth birthday I find myself reflecting on its suitability as a “tool for thought” . Certainly reading the Structure and Interpretation of Computer Programs nearly thirteen years ago painted an ideal image of Lisp as a truly interactive and tangible approach to computing. That experience eventually lead me to Clojure and later ClojureScript. Now that I use both for the…

ClojureScript Year In Review

It’s been a very exciting year for ClojureScript. It’s clear that things have been accelerating and here is a personal selection of highlights: CLJSJS While technically it appeared in late 2014, CLJSJS took off when ClojureScript landed enhanced and standardized support for foreign dependencies in January. Thanks to the tireless work of many contributors, the wider community of ClojureScript users…

ClojureScript Next

I’ve been enamoured with languages in the Lisp family ever since I first encountered The Structure and Interpretation of Computer Programs now more than a decade ago. At the time I was disappointed that such beautiful systems found so little use in day to day programming. Lisp seemed both deeply pragmatic (Objects!) and deeply sophisticated (Meta-circular Interpreters!). But Java, bless its heart,…

In Stillness, Movement

A while back I wrote about Google Closure Modules , and talked a little bit about code motion . A few days ago I tried dog-fooding the discussed ClojureScript :modules functionality on Mori , which exports ClojureScript’s standard library for JavaScript usage. To my surprise attempting to split Mori into base and extras modules resulted in a fairly large base (~36K gzipped) and surprisingly small…

Optimizing ClojureScript Function Invocation

For all the available abstractions, the #1 tool of any Clojure and ClojureScript programmer is the humble function. This being true it becomes extremely important to optimize this common operation. This is not quite as straightforward as it may seem when compiling to JavaScript due to the fact that many Clojure and thus ClojureScript functions leverage multiple arities. On the JVM this is handled…

Scripting ClojureScript with JavaScript

The following code demonstrates how to script the ClojureScript compiler with the Nashorn JavaScript engine that ships with Java 8. Create a file called build.js with the following contents: // Use the Java interop clojure.lang.RT namespace to get at // Clojure vars var ArrayList = java . util . ArrayList , RT = Packages . clojure . lang . RT , seq = RT . var ( " clojure.core " , " seq " ); //…

Lessons in the Fundamentals

ClojureScript 0.0-3058 is a series of lessons in the fundamentals. Read-Eval-Print-Loop For the very first time ClojureScript ships with REPLs that deliver the functionality people have long ago come to expect from Clojure: :reload , :reload-all , doc , source , find-doc , apropos , dir , and pst are all there. All REPLs ship with source mapping support enabled. Whether you’re in a REPL hooked up…

Hello Google Closure Modules

By now you may have heard some buzz about webpack , a tool for managing web application assets. webpack can manage images and stylesheets, but only the facilities for managing JavaScript sources and more specifically the facilities for code-splitting are of interest to us in this post. We’ll briefly look at webpack’s support for splitting and compare it to a little known feature of the Google…

Transit-js Caching

One of the nicest features of Transit and thus transit-js is the standard caching mechanism. Query results often contain an incredible amount of data duplication in the map keys and Transit largely eliminates this problem for you. Periodically users have requested that the caching mechanism be extended beyond just map keys to richer data structures. It turns out this feature has existed within…

Lazy Contracts in 30 lines

Instance Level Interface (Typeclass) Extension Once again continuing previous lines of thought let’s consider validations beyond :pre and :post conditions. This time we’ll see how ClojureScript’s specify construct allows us to trivially build a form of lazy contracts similar to those described by Findler et al. . Note: the following approach can be duplicated with deftype or reify on Clojure JVM,…

Faster Validation Through Immutability

Continuing the line of the thought from the previous post let’s see how immutability can help us reduce the cost of validation at runtime. While :pre condition elision is nice we would prefer that the runtime behavior of our program during development not be so divergent from our production builds. Immutable data coupled with innocuous mutation can give us what we want. All Clojure and…

Life with Dynamic Typing

As with many things in the realm of Computer, some choices involve big tradeoffs. One of these is choosing to write software with a dynamic programming language. Having built some interesting and impactful user facing applications for many interesting companies over the years I can say with confidence that I personally enjoy and in many cases prefer the flexibility afforded by dynamic typing.…

JavaScript Modularity Shaming

Pete Hunt of React fame recently got into an online discussion about the pros and cons of Webpack vs. Browserify . In the discussion he inadvertently coins a hilarious term for a form of rhetoric in some circles of the JavaScript community - “Modularity Shaming”. React itself has been on the receiving end of “Modularity Shaming” due to its relatively large size for a JavaScript dependency, ~37K…

The Essence of ClojureScript Redux

UPDATE: This post now contains obsolete information. Please read the new ClojureScript Quick Start instead My previous post demonstrated a very manual series of steps for getting a sensible ClojureScript REPL setup going. This post covers the easy way using the shiny 0.0-2665 release of ClojureScript. The only thing you need to go through this is to have Node.js and rlwrap (under OS X easily…

The Old Way, The New Way

UPDATE: This post now contains obsolete information. Please read the new ClojureScript Quick Start instead This post will walk you through using ClojureScript from master, using a contrib SNAPSHOT release, and getting a productive fast REPL setup using the new Node.js REPL support. Imagine that you want to try out the new ClojureScript support in test.check 0.6.3-SNAPSHOT . You would really like…

The Node.js REPL of My Dreams

UPDATE: This post now contains obsolete information. Please read the new ClojureScript Quick Start instead Clojure has always been about embracing existing mature platforms. Being on the JVM means tapping into untold person years poured into battle-tested libraries and access to a vast ecosystem with powerful IDEs , incredible profiling tools , and answers to nearly any question imaginable .…

Waitin'

UPDATE: This post now contains obsolete information. Please read the new ClojureScript Quick Start instead When I first started programming Clojure circa 2008 startup time was a legitimate annoyance. Now, on modern hardware starting a bare Clojure REPL is in subsecond territory - not as snappy as irb or python , but no longer slow enough for me to care much. Folks who rely primarily on Leiningen…

Browserless ClojureScript

UPDATE: This post now contains obsolete information. Please read the new ClojureScript Quick Start instead As of ClojureScript 0.0-2505 support for Node.js has improved to the point where a browserless workflow is now quite productive. I now prefer this approach when developing libraries where dealing with the browser is a distraction. To show how fun and easy it is I’ve updated my mies-node…

What's in a Var?

There are many features that set Clojure apart from other programming languages but two pretty remarkable ones that don’t get much airplay are vars and metadata . I suspect the reason is two-fold: there are more obvious benefits and these features don’t have analogous counterparts in popular programming languages rendering them illegible to many people. However once you have them their absence in…

Hello Chestnut

UPDATE: This post now contains obsolete information. Please read the new ClojureScript Quick Start instead Chestnut is one of the coolest bits of ClojureScript tech I’ve encountered in a very long time. Rather than wax poetic I’m just going to show a short video of Chestnut in action. In the following you’ll see several novel things including a very stable ClojureScript REPL based on WebSockets -…

Immutable JSON

Facebook just released immutable-js a persistent data structure library for JavaScript. Given the performance benefit immutable data can bring to React , it’s little surprise Facebook is investing in them. However the question remains how to deliver immutable data to clients given the prevalence of JSON . In this post I’m going to demonstrate consuming plain JSON with transit-js and producing…

Transit, JSON & ClojureScript

If you’re a ClojureScript user transit-cljs offers nearly all the benefits of EDN while delivering performance comparable to native JSON . And since the Transit JSON encoding is truly just JSON, transit-cljs also provides a better story when communicating with existing JSON services. The Problem ClojureScript launched more than 3 years ago with cljs.reader/read-string . This allowed Clojure and…

A Closer Look at Transit

Disclaimer: I am an employee of Cognitect and I worked on the transit-js implementation. The opinions found herein are my own and do not necessarily reflect the recommendations or views of Cognitect. By now you may have heard of something called Transit , a new format for conveying values between heterogenous systems. Transit seemed to generate a lot of interest, but given many of the comments on…

Externs Got You Down?

Update : This post was written nearly a year ago. A lot of things can change in a year. People start using React and third party JavaScript packaging stories for ClojureScript can appear out of nowhere. This post describes a quick hack when you are in a bind but I would not use it in production setting. Use a CLJSJS package instead. While ClojureScript’s strategy of generating and leveraging code…

Taking Off the Blindfold

Here is a simple user interface component: Here is the exact same interface component again peeking under the blindfold: Clicking on the checkboxes should convince you that they are backed by the same data. Note that in the second case you can edit the EDN representation of the user interface and see corresponding changes. It bears repeating that both examples are actually exactly the same: (defn…

KTC Code Salon

I normally don’t make geographically specific announcements on this blog, but for this once I am making an exception. While the New York technology meetup scene is quite vibrant, for me personally there’s something missing and with the help of Kitchen Table Coders , we’ve decided to actually do something about it - KTC Code Salon . If you don’t know, Kitchen Table Coders is a loose collective of…

ClojureScript for Light Table Users

I’m putting together an interactive ClojureScript tutorial for Light Table users . You can go through the tutorial by directly evaluating forms in the file via the Light Table UI Connection. I hope this can be a collaborative wiki for those people who want to extend their editor with an extremely capable and powerful programming language.

ClojureScript Analysis and Compilation

Without a doubt Light Table is now one of the most popular ClojureScript applications in the world. It’s also likely one of the most complex at around 11,000 lines of ClojureScript. I think Light Tablers looking to extend their shiny new environment might first consider reaching for JavaScript. I challenge them to give ClojureScript a very serious consideration before doing so. To encourage users…

Time Travel

In my previous post I claimed it was trivial to implement undo in Om . You can see it in action here . I added the following 13 lines of code: (def app-history (atom [@app-state])) (add-watch app-state :history (fn [_ _ _ n] (when-not (= (last @app-history) n) (swap! app-history conj n)) (set! (.-innerHTML (.getElementById js/document "message")) (let [c (count @app-history)] (str c " Saved "…

The Future of JavaScript MVC Frameworks

Introducing Om often devs still approach performance of JS code as if they are riding a horse cart but the horse had long been replaced with fusion reactor — Vyacheslav Egorov (@mraleph) December 13, 2013 We’ve known this for some time over here in the ClojureScript corner of the world - all of our collections are immutable and modeled directly on the original Clojure versions written in…

ClojureScript 101

While none of the ideas in core.async are new, understanding how to solve problems with CSP is simply not as well documented as using plain callbacks or Promises . My previous posts have mostly explored fairly sophisticated uses of core.async , this post instead takes the form of a very basic tutorial on using core.async with ClojureScript . We’re going to demonstrate all the steps required to…

The Essence of ClojureScript

UPDATE: This post now contains obsolete information. Please read the new ClojureScript Quick Start instead Recently a couple of people have communicated that getting up and running with ClojureScript is challenging. While there’s a book and a number of excellent tutorials , none emphasize what I consider an absolutely minimal setup with a tight feedback loop and a good debugging experience. This…

ClojureScript Source Maps

UPDATE : This is now an outdated post. For more accurate information on enabling source maps please refer to the ClojureScript Wiki entry . ClojureScript has had experimental source map support for some time. Unlike other transpile to JavaScript languages, ClojureScript source maps actually map all the way through Google Closure advanced compilation! However this support suffered from inaccuracies…

Asynchronous Error Handling

This blog post came to be after some great discussions with James Long about the best way to handle errors if CSP is your concurrency model. He showed some neat JavaScript sketches for converting channel errors into exceptions that I tweaked for core.async In order for JavaScript Promise implementations to be useful they must provide some mechanism for handling and propagating errors. But the…

ES6 Generators Deliver Go Style Concurrency

Last night I expressed some frustration about the state and future of concurrency in JavaScript. I ended up having a little bit of back and forth with David Herman and he pointed out that ES6 Generators can express Go and core.async’s flavor of CSP . Now I had thought about this in the past but I could not see how . Part of this was that I’d never seen how a CSP system works under the hood (now I…

Make No Promises

Promises are all the rage in the JavaScript world even though they don’t actually eliminate callback hell and their design emphasizes coarse grained asychronous operations leaving much to be desired for the vast universe of possible interactive applications ( cough , user interfaces). Here is a simple benchmark using one of the fastest promise implementations, when.js . function goWhen() { var…

Comparative Literate Programming

core.async and systems like it have an unmatched level of power when it comes to programming user interfaces. I’ve spent about a week using core.async to build the long promised autocompleter in about two hundred lines of ClojureScript. This post is a doozy so I’ve decided to present it in the format of comparative literate code . I’ll be documenting every part of the autocompleter and showing how…

10,000 Processes

UPDATE : I got too enthusiastic from the last post, this 10,000 not 100,000 go blocks. 10,000 independent go blocks all running at the same time. (ns blog.processes.core (:require [cljs.core.async :as async :refer [<! >! chan put! timeout]] [blog.utils.dom :refer [by-id set-html! set-class!]]) (:require-macros [cljs.core.async.macros :refer [go]])) (def width 100) (def height 100) (defn gen-ui []…

100,000 DOM Updates

Click the table of zeroes once. Note that the text input field remains responsive even as we run 100,000 updates on the DOM. The colors of the table show the render batching boundaries. Note, I would not try this on a mobile device ;) The following is all the code we need to write a batching render with a flush in milliseconds set by rate . We’ve intentionally set a relatively small buffer size,…

CSP is Responsive Design

When architecting user interface components programmers usually engage in copious amounts of complecting . However we shouldn’t be blamed as traditional approaches do not make the boundaries clear. In the last post I alluded to the possibility that CSP provides opportunities to pull things apart and that there might be real value in such a separation of concerns. I believe there are three main…

Communicating Sequential Processes

With the arrival of core.async , ClojureScript provides a powerful advantage over other popular compile to JavaScript languages like CoffeeScript , Dart , and TypeScript . These languages fail to address the single largest source of incidental complexity for any sizeable client side application - concurrency. In my experience no amount of simple syntactic sugar, class abstraction, or type…

Functional Programming Is A Scam!

I apologize for not wrapping up my series of posts on nominal logic programming , I’ll return to that bit of fun soon enough. But lets take leave of theoretical computer science and turn to something more “pragmatic”. In this post I want to talk about my port of Notch ’s beautiful Minecraft JavaScript demo to ClojureScript . When I say beautiful I’m not referring to the code - frankly it’s ugly.…

STLC Redux: Part II

Clojure/West was a blast and I’m happy that Michael Fogus’s joke became a reality with 140+ attendees. All the presentations were great, in particular I enjoyed Adam Foltzer’s talk on implementing a logic programming system in Haskell, Ryan Senior’s tutorial on the new finite domain functionality in core.logic, and of course Dan Friedman and Will Byrd’s relational CESK machine . Nada Amin’s talk…

Logic Programming is Underrated

Mark Engelberg wrote a very interesting post titled Logic Programming is Overrated . I take issue with a quite a few points made in that post and I would like to address a couple of them here. First off, yes, list comprehensions are an excellent concise, readable way to do search when the search is reasonably small and when you don’t really care about performance. That said making any judgements…

The Simply Typed Lambda Calculus in 20 Lines Redux

Some time ago on my old blog I showed the simply typed lambda calculus in core.logic with no explanation based on some Prolog code I found on StackOverflow. I’d like to revisit that meager post with a much more detailed exposition of the ideas behind that code. I recommend setting up core.logic with Clojure or $\alpha$Kanren with your favorite Scheme or Scheme-like (I like Petite Chez and Racket )…

A New Blog

I’ve decided to move my blog over to GitHub. Expect more frequest posts on Lisp, Logic and JavaScript in the future.