The Hallway Track: Clojure/Conj 2024 in Alexandria

This year I had the privilege of attending Clojure/Conj in Alexandria, VA. Alexandria is a beautiful city, with a museum seemingly on every corner, and abundant trees just starting to turn yellow for the fall. It has an efficient metro system and a safe, welcoming atmosphere.


The conference was held in the unique George Washington Masonic Memorial. The venue has an impressive theater with quirky side rooms and hallways. The walls and alcoves were adorned with historical artifacts. The unusual and segmented layout leant itself to longer breakout discussions, with perhaps a little less broad social mixing as people were more spread out in clusters. The conference started with a buzz of energy, and settled into something of a serene atmosphere as most attendees settled into the proceedings - happy to be there, meet up, and enjoy the experience.





Some themes were: Visualization, tooling, collaboration, and quick responses to issues raised in libraries, as exemplified by Borkdude is everywhere! And it was revealed that Babashka is used by 90% of Clojure survey responders. Many discussions revolved around Portal, Cursive, Calva, and whitespace formatting. Many tool makers were taking the opportunity to brainstorm and collaborate closely.


Rich Hickey’s welcome address set a positive, thoughtful tone for the conference. All of the talks were excellent. If you only have time for one talk, I highly recommend watching "Science in Clojure: A Bird's Eye View" by Thomas – an engaging talk on scientific discovery and systematic innovation presented with a generous splash of humor. Make sure to catch them on ClojureTV.


The games night was a hit as always, with plenty of socializing, fun, and competitive strategies employed.


Conversations ranged from whitespace management in code formatting to the potential of brainwave interfaces. The Clojure community's diversity and creativity were on full display. I received lots of encouragement for Hummi.app, many people voiced their hope for a better diagramming app and were really interested in the details of what it does, and had great suggestions.


A big thank you to NuBank and the organizers for making this fantastic event possible.



What follows are my notes about the people I met and the things they were working on:


James Afterglow algorithmic light shows in Clojure.


Chase self taught Clojure as his first programming language. He chose Clojure to go straight to the good stuff. Previously an English literature teacher.


Samuel at Kevel working on advertisement serving. Glad to be working in Clojure as it is a much more enjoyable challenge to previous work in mechatronics hardware. Eager to see technology move forward and hopes that we can be more ambitious about creating amazing things.


Jeaye building Jank. Finding a lot of community support, and even more interest from outside the Clojure community.


Hanna coding Clojure 6 years at Nubank, enjoys the work and the team.


Francis is in Datom heaven at Nubank with more data than ever.


Tim S had a great take on the legend of bigfoot and why it was so popular on the west coast. 


Hadil, long time Clojure user, first time Conj attendee looking forward to meeting David Nolan and Rich Hickey. Building a react native app in ClojureScript for matching yard work providers with customers. Starting to contribute to the Jank project.


Michael has been enjoying the Microsoft automatic graph layout. Search and replace would be great in a diagram app. Clerk style file based editing of a graph. Should the file be GraphQL or SVG, or maybe another source of truth? Observed astutely that Stu is a man of many disguises, he looks different every time he appears.


Anonymously overheard: “Borkdude just fixed my issue, I only submitted an issue 20 min ago” x2

> I heard several comments about library maintainers being responsive, and libraries being generally stable.


Chris O managing whitespace conflicts is not your job, let’s all move on.

> I’d love to not have to deal with whitespace when collaborating. It’s a pain, and unproductive.


Chris B meeting with many users of Portal. Would love to appear inline with Cursive's new inline evaluation output.

> I’d love to be able to display HTML inline, hopefully kindly visualizations as well.


Chris H has a book project underway.

> Joy of Clojure is a popular recommendation as a book that makes you think. Maybe a new edition is on the way?


Ivan on raising kids in the big city. My daughter on vacation asks “where are the tall buildings?”


Osei and Eli were deep in consultation with the Datomic team.


Toby is looking forward to a trip to Italy in April.


Lauren recently completed a GraphQL from REST refactoring.


Paul is solving sleep apnea at sovaSage. Their team and customer base is growing.


Kelvin works with Milt on a military training system.

> I remember meeting Milt at a Conj nearly a decade ago when he recommended I look into SVG when I was first thinking of making diagrams.


Colin inline Cursive evaluation and separate prompting plugin. Intellij code formatting is a constraint solver, is rule (3) a problem? Cljfmt kind of breaks it. Would like to standardize, but will need to re-implement according to the constraint solver. I hope Claude can help him get that done.

> Such a large impact on so many programmers


Pez is enjoying replicant and portfolio. postscript was the most dynamic LiSP. He hopes that Clojure formatting can standardize, and that he can promote a default in Calva.

> Great to see Pez and Colin together discussing how to implement rule 3. Both wanting to improve the compatibility of default formatting across editors.


David N is now at DRW, sifting through layers of Clojure archaeology. Oh that was popular, then this, then that. Seeing slices of history of when certain patterns were in favor.

> Nothing ever truly goes out of style in Clojure it seems.


Brandon is leveraging machine learning and making mindful investments.


Rich importance of ideas, fun, planting seeds of community outside the current borders. Go there and share. Enable creative people, optimists. Retired from Nubank, but still working on Clojure with the core team.

> Having the opportunity to shake Rich’s hand and hear his thoughts on community building was inspiring.


Aaron has a graph layout constraint system. Working on compute services at Equinix. Looking forward to visiting the Smithsonian National Air and Space Museum.


Dustin is building Electric Clojure with his team. They are available for consulting work to help companies develop applications using their technology to drastically reduce the code for client/server functionality.

> It’s amazing what they have achieved with Electric Clojure, I wish I had a commercial application to try it on. Such a principled approach focused on delivering value without incidental complexity.


Joe gave some insights on dealing with scale at Nubank, and the advantages of being able to preload data for queries.


Nacho is engineering manager at Splash addressing student debt and marginal loans.

> Nacho has a lot of empathy for those in need, this seems like a great fit.


Thomas’ talk - entertaining, informative and engaging, new testable knowledge, discovery, systematic exploration. Wolframite. Undeclared dependency on prayer. What quantum mechanics tells us about distributed systems. Dead plots, and the role Clay has in solving that. The trend of native Clojure libraries replacing python interop. Order vs Chaos - voluntary cooperation. Science in a nutshell. Emmy for symbolic math. Responsiveness of the community, generate me added Ince on request.

Designing experiments with mirrors and lasers. The laser connects everything. Can split the beam. Arrangement usually doesn’t matter except when refracting or polarizing. Similar to electric circuits?





Wesley commented on the absence of graph libraries in Clojure.

> Loom (no longer maintained) and Ubergraph are good, but many algorithms only have reference implementations in C and JavaScript.


Kira at Broadpeak (commodities trading) working with a heap of data. Building a grammar of graphics for ggplot style visualizations. Sits between very specific charts and basic rendering like SVG. Good for combining visualizations.

> ggplot uses functions that build data as a concise way to express visualizations.


Adam interested in using kindly-render as a way to embed visualizations in badspreadsheet.





Andrew thing.geom needs a new maintainer!


Lucas transpiling and resurrecting out of circulation games, job hunting for junior roles is difficult when your current job title is senior.


Cam is looking forward to Halloween. Had 700 trick or treaters last year, and now has a giant spider attraction set up in anticipation. When we find a bug in HoneySQL, Sean has already fixed it by the time we report it.


Sean recommended reading The Socratic Method (Ward Farnsworth). Rich recommended it in his talk last year Design in Practice, and Sean has found it useful for organizing thinking.


Sofia had read Socrates, going into a masters program human computer interaction through brainwaves, looking to improve the isolation of wave patterns.

> I hope somebody proposes a talk on the Socratic method next Conj


Quetzaly interested in joining Clojure Camp (https://clojure.camp/). This was the first time I’d heard of Clojure Camp so Sofia showed us how it works. It’s based around pairing mentors and mentees. You can choose how many times you’ll be paired, what times work for you, and what topics you are interested in. You opt in every week that you’d like to continue.

> So great to have this as a way for people to pair up and work together on something productive.


Torstein fish feed management and automation. Norway has 2 written languages Bokmål and Nynorsk, and overlaps languages with Swedish and Danish. There are many dialects. The Sámi people live in Norway, Sweden and Russia and have yet another language. Right now they cannot cross the Russian border. Learning more languages is a good thing, you learn to express more, be more creative. Nationalism and a drive to have one language has had the opposite, divisive effect.

> I am astonished at how complex the interactions of language and culture can be.


David Y building a tax accounting startup.

> Datascript with Firebase backend remains a popular stack, but relies on custom implementations.


Carin had a book recommendation “Slow Horses”. LLMs can help us think. She hopes the next generation uses them to improve thinking instead of replacing thinking.

> The next generation is growing up in such a different learning environment, I hope they can think better than we ever could.





Jay is working at Viasat on DHCP network management.






Clojure/Conj 2024 left me inspired and grateful for the connections I made. The conference highlighted the language's evolution, its vibrant community, and its potential to shape the future of technology. I'm excited to see where the Clojure journey leads us next!


Clojure REPL tip: Setting up a retry key binding

One thing that I love about Clojure is that the Read-Eval-Print-Loop (REPL) enables me to redefine functions on the fly, without restarting anything. This makes trying things, making changes, and trying them again very fluid. Trying stuff, changing it, and trying it again pretty much sums up how I write code.

If at first you don’t succeed, dust yourself off and try again.

– Aaliyah

Today I’m going to share with you my favorite “try it again” tip, which is to bind keys to try something and try it again.




REPL usage

Let’s recap basic REPL usage. I can type stuff into the REPL input window and evaluate some code. Generally I don’t do that though. I’m not usually in the REPL, I’m in my source code sending forms to the REPL. To achieve that requires some essential key bindings.

BindingAction
alt-tEvaluate the expression before the cursor
cmd-tEvaluate top-level expression at the cursor
ctrl-cRun test under cursor
shift-ctrl-cRun all tests in namespace
ctrl-cRe-run last test action

The Problem 😢

A common scenario I find myself in is that I set up a little bit of code to try something. Then I make some changes, and need to retry the same snippet or test. In the meantime I have navigated away and I need to either go back to the form I am interested in, or navigate to the REPL and use history to try it again. Both of these strategies work, but there is a better way!

The Solution 💡

The idea is to create a REPL command that creates a function in the user namespace. Then we can make a keybinding like “send form before caret to REPL”, and another keybinding to execute the saved function. That way even if we send other forms to the REPL, we can conveniently retry the snippet we are focused on.

Here is how I set the “try” command up: img

I use Cursive Clojure (IntelliJ). If you use a different editor, you can find instructions for creating key bound commands in the Clay setup documentation.

~form-before-caret gets replaced with code.

So if my cursor is at the end of an expression (cursor shown as _):

(+ 1 2)_

My editor will send the following code to the REPL:

(do (intern 'user 'retry (fn retry []
                           (+ 1 2)))
    (user/retry))

This creates the retry var in the user namespace (user/retry), and assigns it to a function that will run the code I am interested in.

It is worth considering a few questions about namespaces at this point. Which namespace will the command execute in? How can user/retry “see” variables in the currently edited namespace?

The command will execute in the namespace of the file I am editing, because I configured the command to do so through Cursive. The function is created in the current namespace, because (fn retry [] (+ 1 2)) is eagerly evaluated as an argument to intern. Because the function is created in the current namespace, x is resolved correctly. user/retry can be invoked from any namespace by the fully qualified name of the var user/retry.

Here is how I set the “retry” command which simply invokes (user/retry): img

And here are the keybindings for the commands I use: img

I’ve bound alt-z to “try form before caret” and ctrl-z to “retry”.

Now let’s take it for a spin. Here is some code I’ve been working on; I’m drawing a heart shape.

(def heart-path
  "M 12.0 7.2 C 10.5 5.6 8.1 5.2 6.3 6.7 C 4.5 8.1 4.2 10.6 5.7 12.4 L 12.0 18.3 L 18.3 12.4 C 19.7 10.6 19.5 8.1 17.7 6.7 C 15.8 5.2 13.4 5.6 12.0 7.2 Z")
"#'blog.try-again/heart-path"

This shape comes from svg-paths by @nandafyi.

I’ll visualize it in an SVG image:

(defn svg [& body]
  (into ^{:kindly/kind :kind/hiccup}
        [:svg {:width   256
               :height  256
               :viewBox [0 0 24 24]
               :xmlns   "http://www.w3.org/2000/svg"}]
        body))
"#'blog.try-again/svg"

The heart path goes into an SVG element:

(defn heart []
  [:path {:fill "green"
          :d    heart-path}])
"#'blog.try-again/heart"

And to see what it looks like I’ll make a “rich comment block”:

(comment
  (svg (heart)))

The comment block allows me to conveniently send the expression (svg (heart)) to the REPL, and of course we’ll use my new “try form before caret” on it.

(svg (heart))

Now I can navigate throughout my code base, making changes and fixes, and seeing the effect is just one keystroke away with “retry”:

(defn heart []
  [:path {:fill "red"
          :d    heart-path}])
"#'blog.try-again/heart"
(svg (heart))

Setting up the command to sync all changes before executing makes it easy to test changes as I go, often I can rely on syncing instead of sending updates to the REPL individually.

Special thanks to @chrishouser and @IPmonger@hachyderm.io for dedicating a session of LiSP reading group to improving my workflow with try/retry.

The Hallway Track: Clojure/Conj 2023 in Durham

These are my notes and impressions from the hallway conversations during Clojure/Conj 2023 conference. I'm sharing them in the hope of capturing some of the atmosphere and provide a peek into what people in the Clojure community are up to and what companies are using Clojure.

General observations

  • Database announcements:
  • Several non-JVM dialects of Clojure are appearing:
  • Attendance:
    • Everyone was excited to be able to mingle and chat.
    • Mostly returning Conj’rs.
    • Lots of people, my guess is more than 500.
    • Rich’s keynote was packed to capacity.
  • Hiring
    • There was a conspicuous absence of “we are hiring” pitches. Attendees and sponsors were recruiting customers and clients rather than employees this year.
  • Swag
    • Metosin had an awesome black “programmer” t-shirt, bag, and chocolate!
    • The Conj trucker hat is cool
  • Themes
    • Appreciation of community the opportunity to congregate
    • High adoption of Malli and Reitit
  • Talks
    • All of the talks were excellent, I highly recommend watching them on ClojureTV
  • Travel
    • Passing over the magnificent snow-capped mountains of America is an inspiring thing to experience.

Conversations


  • Toby (Shortcut)

    • House construction

    • Hiking destinations

    • Dr Wolf chess app

    • Wishes there was a mid-priced support tier for Datomic; will the free tier be less responsive now?

  • Jon

    • Thinking about how to mine his own data

  • Mark (Metabase)

    • The importance of asking “what’s the problem?”

  • Francis (Shortcut)

    • We decanted our Datomic DB

    • Constant time lookup was crucial to decanting

    • Reading the TX log, running transformations

      • Throwing stuff away: attributes we don’t use, entities like VCS data (we don’t need to replicate git)

      • Large strings

    • Precompute the changes we need in a database

    • SQLite is fast but not fast enough for billions of entities. We used an on-disk hash table. Perfect hash, immutable

    • We now have less work per TX, more storage runway, and 20% speedups

    • Backups are 7x faster

    • Don’t use full text index

    • Thinking about how to optimize blobs and working on the GraphQL API

  • Dan (Metabase)

    • Great to see a fellow member of the LiSP reading group

  • Paul (sovaSage)

    • Solving sleep apnea

    • It would have been nice to have more time to discuss Rich’s keynote

  • Daniel (Shortcut)

    • Made a Clojure dialect PiLisp 

    • Pipe can be used for concatenative style

    • Dart is a good target, it’s fast

  • Evan (Shortcut)

    • Concerned about the rise of the unnecessary use of Kerbenutes

  • Denise (Viasat)

    • Starting a new project Java -> Clojure rewrite

    • Challenges of managing teams, and the value of hearing when people feel that it’s working

    • Launching rockets; launch delays are costly

    • Suggested a templates gallery of diagrams for Hummi.app would help new users figure out what they can make. Editable examples.

  • Aaron (Viasat)

    • Theory of constraints, Flying logic is awesome for diagrams, but expensive

    • Causal reasoning is interesting and applicable to medical/ethical questions

  • George (Cognitect/NuBank)

    • Love the Clojure community

      • Learning new things

      • Tight knit

      • Everyone is interested in what other people are doing

      • Less competition.

      • Approachability

      • More personal and intimate that big tech conferences

      • Contactable

      • Niche in numbers, but still able to have Clojurists together

    • Embracing change, things change, we evolve

    • I like Onyx. I used it for Climate data analysis

  • Jeremy Taylor (Juxt)

    • I’ve dedicated my life to building the cathedral of a DB XTDB, and it’s really good

  • Arni (Gaiwan)

    • New project: Ornament for styling. Particularly helpful when debugging to be able to connect named classes to your code.

    • BI and reporting for Datomic incoming

  • Dave (Kevel)

    • Created a music language Alda

    • Interested in diagrams, mostly using PlantUML, knows the → longer arrow trick.

  • Finn (Juxt)

    • Working on XTDB Cloud

  • Josh (RoamResearch)

  • Connor (RoamResearch)

    • It’s all about interface: data entry widgets and connections

    • We are doing everything all at once, experimenting on ideas to make the future tool for thought.

  • Ivan (Shortcut)

    • Data driven test scenario evaluator that creates and binds entities

  • Eli (Shortcut)

    • Strategy in the bird game is to gather eggs

  • Nathan

    • Mining PDF data

    • SQL

    • Lambda Island

    • Institutional research, students, reports, dashboards, classes need

    • Detective ability to explore

    • Nil, it’s always nil

    • Boolean edge cases are mysterious

  • Ravi (Nilenso)

    • Healthcare, public record

  • Deepa (Nilenso)

    • Solving hypertension. An ignored health issue tied to lifestyle.

    • Diagrams should be intuitive, shouldn’t be ugly

    • Excalidraw is good, but too much energy wasted dragging things around

    • Mermaid is good for seq diagrams

  • Jim

    • The best things come from one person who thinks deeply about one thing

  • Christophi

    • Recommended a book about the benefits of a diverse background: Range by David Epstein.

  • Chris (Treasury Prime)

    • Most popular project is chessboardjs from 2011, just rewrote v2 in ClojureScript

    • Played a lot as a youth, 1800 rated. (That means he can beat most chess players every time).

    • HumbleUI is awesome: Smooth, animation, save/reload

    • Writing a FAQ for parinfer to answer the many questions he gets about the status of the project.

    • Lua is convenient for plugins

    • Discussed HSDS and .app TLD requiring HTTPS

    • The sponsors are mostly consulting firms this year

    • Remembered my previous hallway track drawings. I haven’t been sketching this Conj, but he reminded me that I do like drawing charactures




  • Alex (Cognitect/NuBank)

    • I wish tool makers would adopt the error reporting features in Clojure 1.10+

    • Deps has finally overtaken Leiningen in popularity in this year’s survey.

  • Elango (Google)

    • The Clojure community is very approachable

  • Brandon

    • Saw the gap in the diagram solution space

    • Working with security questionnaire forms using Mali

    • Enjoys Clojurians Slack #ClojureScript channel

  • Russell

    • Electrical diagram layouts are tough due to the tendency towards overlapping lines

  • Dustin (Electric)

    • CSS styling spreadsheet controls

  • Proctor (Guaranteed Rate)

    • CLJS AWS Lambda functions

  • Kimmo (Metosin)

    • Lots of Clojure happening in Finland

  • Daniel2 (Guaranteed Rate)

    • Starting a new Mortgage underwriting automation (ML)

  • Mathew

    • How can we best help people learn Clojure?

  • Jayden

    • Building an e-commerce platform (like Shopify)

    • Interested in building a tool for thought

  • Carin

    • Book recommendation: The murderbot diaries

  • Janet (Freelance)

    • Enjoying the opportunity to network

  • David (Vouch)

    • Life is busy when you have a 5 year old!

  • Jeaye (EA)

    • Building Jank

      • Cling is a pain because releases are inconsistent

      • Yes, you can use .cljc instead of .jank if you want to

      • let* instead of let

    • Pricing drives perceptions of quality

  • Rich

    • Turns up to the talks, mixes with everyone

    • Design, preparing to design, stuff happens before you can design

    • There’s more to it than hammock time

    • Communicating progress and backtracking

      • Tickets

    • Define the problem

    • List possible solutions

    • Create a criteria for evaluating solutions

    • Sleep on it before you code

    • Diagrams are useful for planning and documenting




Final thoughts


My favorite part of the conference came from a humorous, cheeky, and insightful audience question: “Is there the risk of an unintended consequence of putting Clojure code measuring 7 lines in length right next to the output measuring hundreds of lines of length and causing a world wide crash in interest in languages like Java? On a more serious note, I’ve heard that Clojure has a weakness in error messages. Has the answer been staring us in the face? Can we compile Clojure to Rust and get the error messages from Rust?” Earning applause and laughs from the entire audience who could see both the appeal of the idea, and the funny/ironic side of it. To me this exemplified that Clojurists are innovative thinkers, open to new ideas, and retain a keen sense of humor. I really enjoyed soaking up the ideas, ambitions, enthusiasm, and humor from everyone I met at the Conj.