English · 01:12:06 Jan 23, 2026 7:50 PM
On Clojure, feat. Michiel Borkent (aka @borkdude) | Traces, Appendix 12
SUMMARY
In this podcast interview, host Cristian Cibils chats with Clojure developer Michiel Borkent about his programming journey, embracing functional programming over OOP, Clojure's Lisp roots on the JVM, open-source tools like clj-kondo and babashka, and future projects.
STATEMENTS
- Michiel Borkent began programming as a kid with GW-BASIC on his father's PC, learning by breaking it and writing simple programs like "hello world."
- During high school, Borkent lost interest in programming, focusing more on teenage social activities, but rediscovered it when choosing university studies.
- Initially drawn to economics but deterred after losing money on a bankrupt IT company's stock, Borkent pivoted to computer science due to his love for mathematics.
- In his computer science degree, Borkent studied Miranda, a functional programming language predecessor to Haskell, appreciating its pure functions and elegant reasoning.
- Switching to Java in later courses disillusioned Borkent, as it lacked the elegance of Miranda and failed to inspire side projects despite practical usability.
- Borkent's internship combined functional programming and music at a university researching music cognition, where he encountered Common Lisp and its code-as-data structures.
- Common Lisp allowed expressive programming but was mutable, not strictly functional, and rarely used in industry jobs upon graduation.
- Starting his career in a .NET company, Borkent dabbled in F#, an object-oriented functional language, but kept it to small side projects.
- As a lecturer at a university of applied sciences, Borkent taught Java but sought a more engaging JVM language, leading him to Clojure.
- Clojure appealed to Borkent for its Lisp heritage, immutable data structures enforcing functional programming, and access to the JVM ecosystem.
- Borkent developed and taught a Clojure course, then joined a commercial project using Clojure with Datomic in 2013, using it consistently since.
- Functional programming felt natural to Borkent, unlike OOP, which he found boilerplate-heavy and less intuitive for his mindset.
- In functional programming, code revolves around functions and immutable data, reducing complexity compared to OOP patterns like visitor or MVC.
- Migrating from OOP to functional requires unlearning "place-oriented" programming, where variables mutate, and embracing functions that return new data.
- Modern languages like JavaScript incorporate functional elements like destructuring and map/filter, easing the transition to Clojure.
- Clojure's JVM hosting leverages decades of Java ecosystem development, including dynamic features like hot-swapping and ongoing improvements in Java 21.
- As a Lisp dialect, Clojure's homoiconicity allows code as data, enabling powerful macros and easy manipulation of expressions.
- The parentheses in Clojure syntax initially scare newcomers but become familiar quickly, with no more density than other languages, just different placement.
- Clojure's REPL enables interactive programming, allowing incremental evaluation and hot-reloading of functions without restarting the application.
- In the REPL, functions are stored in vars, enabling indirection that updates references seamlessly during redefinition, preserving state.
- Clojure emphasizes eternal backward compatibility, a cultural norm extending to libraries, avoiding breaking changes through flexible data structures like maps.
- Clojure's standard library excels at data transformation using immutable structures, coherent and portable across hosts like JVM and JavaScript.
- Borkent's open-source journey started in 2019 with clj-kondo, a static analyzer providing warnings without full type systems.
- Babashka, Borkent's interpreter, enables fast-starting Clojure scripts by avoiding full JVM boot, using GraalVM for binaries.
- Borkent went full-time open source in 2021 after 11 years with Clojure, supported by GitHub sponsors and part-time company work.
- The Clojure community is tight-knit and friendly, influenced by Rich Hickey's etiquette and conference connections.
- Borkent's current project, Squint, reimplements ClojureScript semantics using JavaScript objects for smaller bundles and better npm interoperability.
IDEAS
- Childhood experimentation with GW-BASIC taught Borkent programming resilience through trial-and-error, even at the cost of frustrating his father.
- Losing investment in a bankrupt IT firm shattered Borkent's interest in economics, redirecting him toward computer science's mathematical purity.
- Miranda's functional elegance contrasted sharply with Java's imperative tedium, highlighting a divide between theoretical beauty and practical utility.
- Combining music and functional programming in an internship revealed Common Lisp's power for creative expression beyond rigid structures.
- Industry irrelevance of Common Lisp forced Borkent into mainstream stacks like .NET, underscoring the gap between academic ideals and job realities.
- Teaching Java while craving deeper JVM insight led to Clojure, blending Lisp flexibility with industrial leverage.
- Immutable data in Clojure enforces functional discipline, transforming potential chaos into predictable, reason-friendly code flows.
- Functional paradigms simplify reasoning by eliminating mutable state surprises, unlike OOP's hidden object graph mutations.
- Hot-swapping on the JVM enables dynamic updates, making Clojure a living codebase rather than a static artifact.
- Homoiconicity in Lisp turns syntax into manipulable data, unlocking metaprogramming that feels like extending the language itself.
- REPL-driven development fosters a conversational flow with code, accelerating iteration without full recompiles.
- Backward compatibility as a cultural promise in Clojure builds trust, allowing long-term projects without rewrite fears.
- Maps and lists as core primitives maximize data reusability, avoiding the rigidity of typed classes.
- Static analysis via clj-kondo complements REPL interactivity, catching issues before runtime without Haskell-level overhead.
- Babashka democratizes scripting for Clojure users, bridging high-level concepts to everyday automation tasks.
- Full-time open source after years of exploration rewards deep commitment, blending personal tools with community needs.
- Clojure's coherence stems from one visionary's design, avoiding committee bloat for a unified worldview.
- Tight-knit communities like Clojure's thrive on shared pragmatics, fostering friendships over ideological battles.
- Squint's JavaScript-native approach shrinks ClojureScript footprints, easing integration into web ecosystems.
- Exploring alternatives like Haskell ultimately reinforced Clojure's joy, proving happiness trumps trend-driven choices.
- GraalVM's native binaries unlock lightweight Clojure tools, challenging JVM's startup stereotypes.
- Interactive teaching of Clojure inspired Borkent's career shift, showing education's role in personal growth.
- Data-oriented programming views functions as services communicating via JSON-like structures within one program.
- Philosophical overlaps between Lisp and abstract thinking attract polymaths like Rich Hickey to Clojure.
- Tooling like Calva transforms parentheses from hurdles into navigable, color-coded highways.
INSIGHTS
- Functional programming's immutability eliminates shared-state pitfalls, fostering code that's inherently concurrent and easier to debug.
- Leveraging the JVM's maturity provides Clojure with battle-tested performance without reinventing infrastructure.
- Homoiconicity blurs code and data, enabling self-modifying languages that evolve with user needs.
- REPL interactivity shifts development from batch processes to real-time dialogues, boosting creativity and speed.
- Backward compatibility culture ensures longevity, turning software into durable assets rather than disposable experiments.
- Standard library coherence in Clojure amplifies productivity, as data transformations become intuitive pipelines.
- Open-source evolution from personal tools to community staples highlights the value of solving real pains persistently.
- Community etiquette in Clojure cultivates inclusivity, making technical depth accessible without toxicity.
- Static analysis augments dynamic languages, providing safety nets without sacrificing expressiveness.
- Scripting reinterpretations like Babashka extend functional paradigms to ad-hoc tasks, unifying workflows.
- Exploring alternatives refines preferences, revealing Clojure's pragmatic balance over purist extremes.
- JavaScript interop optimizations in Squint reveal how simplifying semantics can unlock ecosystem synergies.
QUOTES
- "By breaking his PC I learned about a computer much to my father's annoyance."
- "Miranda was fun uh in the sense that it was elegant to me and it was easy to reason about."
- "Clojure was actually a lisp for the gvm which uh which I like very much because of my common list past."
- "Functional programming is so much um there's less stuff you know there's only functions and data that run through the functions."
- "The reple is one of the key features of any lisp I would say um including closure."
- "It's this culture is very much promoted by Rich hickey himself who is setting the best example of this with closure."
- "I was always kind of dreaming about being able to execute B scripts but using closures data structures and the closure language with fast startup."
HABITS
- Experiment with programming early through simple, hands-on projects like GW-BASIC to build intuitive understanding.
- Pivot studies based on personal losses or passions, such as shifting from economics to computer science after financial setbacks.
- Supplement formal education with side interests like mathematics, philosophy, and teaching to broaden technical perspectives.
- Seek internships at the intersection of interests, like functional programming and music, to discover inspiring tools.
- Explore languages iteratively, starting with elegant but impractical ones like Miranda before practical JVM options.
- Teach emerging technologies like Clojure to deepen personal mastery and identify ecosystem gaps.
- Build personal tools after years of exploration, turning frustrations like slow JVM startup into projects like Babashka.
- Maintain diversity in income sources, combining open-source sponsorships with part-time consulting for stability.
- Attend conferences to nurture community ties, fostering friendships that enhance collaboration.
FACTS
- Clojure was initially developed with versions for both JVM and CLR, but the CLR port was abandoned in favor of JVM's larger ecosystem.
- The JVM supports dynamic features like hot-swapping bytecode, enabling runtime updates harder to achieve on .NET's CLR.
- Java 21 introduces virtual threads, enhancing concurrency and excitement for JVM-hosted languages like Clojure.
- Clojure's vars provide indirection, allowing function redefinitions to propagate without replacing references.
- GraalVM enables standalone binaries from Java code, reducing memory footprints for tools like clj-kondo.
- Nubank, a major Brazilian bank, uses Clojure extensively, integrating tools like clj-kondo across services.
- ClojureScript targets JavaScript, but advanced compilation often duplicates standard libraries, hindering npm sharing.
REFERENCES
- GW-BASIC: Early programming language used on PCs for simple scripts.
- Miranda: Functional programming language, predecessor to Haskell, taught in Borkent's first university course.
- Java: Imperative OOP language that disillusioned Borkent but provided JVM foundation.
- Common Lisp: Dialect encountered in internship, praised for code-as-data and expressiveness.
- F#: Functional language on .NET, used for side projects in early career.
- Clojure: Lisp dialect on JVM, central to Borkent's work since 2010.
- Datomic: Database used in Borkent's first commercial Clojure project in 2013.
- Haskell: Explored for type safety, influencing clj-kondo's static analysis.
- GraalVM: Oracle's Java compiler for native binaries, key to Babashka and clj-kondo.
- clj-kondo: Borkent's static analyzer and linter for Clojure.
- Babashka: Borkent's fast-starting Clojure scripting tool.
- SCI: Small Clojure Interpreter, maintained by Borkent.
- Clojure LSP: Language server using clj-kondo for editor support.
- Calva: VS Code extension for Clojure with REPL integration.
- Power Edit: Tool for structural editing of Clojure expressions.
- ClojureScript: Clojure dialect targeting JavaScript.
- Squint: Borkent's alternative ClojureScript compiler using JS objects.
- CodeMirror: Text editor component with Clojure syntax plugin ported to Squint.
- The Joy of Clojure (book): Referenced resource on Clojure.
- Clojure for the Brave and True (book): Beginner-friendly Clojure guide.
- Data-Oriented Programming (book): Explores Clojure's data-focused approach.
HOW TO APPLY
- Begin with pure functions in your code, inputting data and outputting new data without side effects to build functional habits.
- Unlearn mutable variables by always returning fresh structures from functions, avoiding in-place modifications.
- Use maps and lists as primary data types, adding keys or arguments flexibly to maintain backward compatibility.
- Integrate a REPL into your workflow for incremental evaluation, testing small code pieces while the app runs.
- Leverage JVM libraries by interoping Clojure with Java classes, gaining access to established ecosystems.
- Employ static analysis tools like clj-kondo early to catch syntax and style issues before runtime.
- Script automation tasks with Babashka for fast Clojure-based prototypes, bypassing full JVM startup.
- Structure libraries around data transformations, ensuring functions communicate via simple, immutable payloads.
- Explore homoiconicity by writing basic macros to manipulate code as data, extending language expressiveness.
ONE-SENTENCE TAKEAWAY
Embracing Clojure's functional Lisp on JVM unlocks productive, stable coding through immutability and community-driven tools.
RECOMMENDATIONS
- Dive into Clojure via REPL experimentation to experience interactive feedback firsthand.
- Migrate OOP code by refactoring mutability to immutable transformations step-by-step.
- Use clj-kondo for linting to enhance code quality without imposing full typing.
- Adopt Babashka for daily scripting, applying Clojure idioms to automation.
- Prioritize backward compatibility in libraries by designing with flexible maps.
- Join Clojure conferences to build networks and absorb pragmatic mindsets.
- Port small projects to Squint for lighter JavaScript bundles in web work.
- Teach Clojure basics to solidify your understanding and inspire others.
- Balance open-source pursuits with stable income to sustain long-term contributions.
- Explore Rich Hickey's talks on simple design to align with Clojure's philosophy.
MEMO
Michiel Borkent's journey into programming began innocently enough, tinkering with GW-BASIC on his father's PC as a child in the Netherlands. What started as innocent "hello world" loops quickly escalated to system crashes, much to his father's chagrin. This hands-on chaos instilled a resilient curiosity, but high school social whirlwinds sidelined coding until university loomed. Drawn to mathematics yet soured by a teenage stock market flop in a Dutch IT firm, Borkent abandoned economics for computer science. His first course in Miranda, a elegant functional precursor to Haskell, captivated him with its pure inputs-to-outputs logic—no hidden mutations. Java's imperative grind soon soured the thrill, exposing a chasm between theoretical grace and real-world drudgery.
An internship fused Borkent's passions for music and functions at a music cognition lab, where Common Lisp's code-as-data magic reshaped his worldview. Though mutable and industry-obscure, it promised boundless expression. Post-graduation, corporate realities thrust him into .NET shops and F# side gigs, but teaching Java at a applied sciences university reignited his JVM quest. Clojure emerged as the revelation: a Lisp dialect enforcing immutability on Java's robust platform, blending Lisp's flexibility with industrial muscle. By 2013, Borkent's first commercial Clojure gig with Datomic solidified his allegiance, teaching the language and weaving it into daily work ever since.
Shifting from object-oriented to functional mindsets proved intuitive for Borkent, who found OOP's boilerplate and patterns—visitors, proxies, MVC—a mechanical slog. "There's only functions and data," he notes, distilling complexity to essentials. Rich Hickey's "place-oriented" critique resonates: mutable objects invite under-the-rug changes, fracturing reasonability. Clojure's immutable structures and data primitives like maps demand fresh outputs, easing concurrency and debugging. Modern bridges like JavaScript's map/filter help OOP veterans unlearn mutation, paving a smoother path.
Clojure's JVM perch leverages decades of Java innovation—hot-swapping, virtual threads in Java 21—without foot-dragging on ports like .NET's CLR. As a homoiconic Lisp, its parentheses prefix functions, forming data structures ripe for macros. Newcomers balk at the syntax, but editors like Calva color-match them, turning trepidation to tool. The REPL revolutionizes development: evaluate a function, tweak it live, watch updates ripple via var indirection—all without restarts. State persists, iterating feels conversational, ideal for UI tweaks or backend flows.
Eternal backward compatibility defines Clojure's ethos, championed by Hickey and echoed ecosystem-wide. Libraries shun breaks, favoring map extensions over rigid interfaces. This stability counters frontend frenzy, where frameworks obsolesce biennially. Borkent praises the standard library's data-transformation elegance—vectors, lists as JSON-like messengers—coherent across hosts like JavaScript. Not committee-cobbled, it's one mind's vision: pragmatic, maker-focused, free of academic excess.
Open-source beckoned after 11 Clojure years. In 2019, clj-kondo's static linter addressed REPL blind spots—state drift, syntax slips—bootstrapped via GraalVM binaries. Babashka followed, a nimble interpreter slashing JVM boot times for scripting superpowers. Full-time by 2021, sustained by sponsors and part-time gigs at Clojure-heavy firms like Nubank, Borkent's tools now underpin banks and beyond. The community's warmth, per Hickey's etiquette, stems from conference bonds and shared pragmatism.
Looking ahead, Squint reimagines ClojureScript with JavaScript natives, slimming bundles to kilobytes and npm-friendly. Porting a CodeMirror plugin proved interoperability, sharing a minimal stdlib sans duplication. For Borkent, Clojure's blend of joy, productivity, and leverage—functional force on JVM rails—remains unmatched, inviting tinkerers to rewrite their code, and realities.
Like this? Create a free account to export to PDF and ePub, and send to Kindle.
Create a free account