Solving Problems the Clojure Way - Rafal Dittwald
Clojure/north10 HN recommenders · 2019–2025
87K views · talk · evergreen · Uploaded 2019-05-24
Rafal Dittwald's Clojure/north talk shows how to move from writing Java-style code in Clojure to thinking in data-driven, functional terms. He walks through a JavaScript example, refactoring imperative code step by step into a functional core.
HN repeatedly recommends it as a fantastic demonstration of procedural, OOP and FP approaches to the same problem, and of functional core and imperative shell.
53:22Ruby Conf 12 - Y Not- Adventures in Functional Programming by Jim Weirich
Confreaks
38:47RailsConf 2014 - All the Little Things by Sandi Metz
Confreaks
42:03The Soul of Erlang and Elixir • Sasa Juric • GOTO 2019
GOTO Conferences
1:01:39"Simple Made Easy" - Rich Hickey (2011)
Strange Loop Conference
25:06"Making Impossible States Impossible" by Richard Feldman
elm-conf
1:31:06William Byrd on "The Most Beautiful Program Ever Written" [PWL NYC]
PapersWeLove
40:20"Testing Distributed Systems w/ Deterministic Simulation" by Will Wilson
Strange Loop Conference
1:03:55🚀 TDD, Where Did It All Go Wrong (Ian Cooper)
DevTernity Conference
15 comments from Hacker News
If you're new to functional programming, I recently gave a talk on applying FP concepts at ClojureNorth: [VIDEO] The main example I work through is in JavaScript so that Clojure's syntax doesn't get in the way (I love s-expressions, but they're not the point of the talk).
Watch the video via recommendations here, but no longer can find it. [Solving Problems the Clojure Way - Rafal Dittwald]( [VIDEO] ) It is a great video and is highly recommended. Spent two days to type and tidy up the source code. If you want the source, and if you like me cannot find it, you may try my version. Just hope Mr. Dittwald would not mind.
The main benefits of Clojure compared to Elixir? I can create - Desktop apps - Server-side apps - Mobile apps - Unity games - Live coding music performance - AI apps - C libraries - Native apps I can use libraries with low friction from the following ecosystems: - JavaScript - Java - .NET - Python Runtimes include but limited to: - JavaScript - JVM - CLR - Erlang - SubstrateVM Clojure specific advantages: - Datomic - Crux - Datascript - Datahike Most "functional" languages bottom out into some highly mutable SQL thing and it's gross Then there are the cultural things, so as you grew as a programmer you probably went imperative, OO to FP, well with Clojure you go another step: imperative, OO, FP, Data-driven: [VIDEO] Technologies like this: [LINK] , machine learning etc are showing that data and data processing is likely to yield the next frontiers in computer programming The next things on the near horizon are data-driven declarative layers to raise the bar of abstraction like [LINK]
Maybe more of the hype comes from the fact that its a Lisp. To get a feeling for the "magic" of lisp, I would suggest either watching SICP video lecs[0] or reading the book. I started learning lisp, almost the same time I've started learning programming with Java (college). Honestly I was thinking why they don't just teach us that, instead of Java at that time. Also Clojure is created by a fairly respected dude (afaik) Rich Hickey. His talks and Clojure design decision articles on the site are really insightful. Also this talk[1] also pretty good overview of different paradigms and `Clojure way`, imo. [0] [LINK] [1] [VIDEO]
Hi fellow PHP'er and in a long time gone C#er here I would highly recommend learning the spirit of Clojure first: [LINK] [VIDEO] There are a few classes of tech that are uniquely Clojure: Data driven DSLs: - [LINK] - [LINK] - [LINK] Hyper normalised relational databases: - [LINK] - [LINK] - [LINK] Advanced SPA tech (hyper normalised data driven): - [LINK] - [LINK] Once you understand the spirit and rationale for Clojure it becomes apparent why other communities don't have this kind of tech yet Once it gets down to practical things I recommend using clj-Kondo with type hints, Cursive for Intellji, make sure you learn how to hot code inject new code into your running program using your editor shortcuts, and TDD in Clojure is also excellent and immediate: [LINK] Also look out for GraalVM and Babashka we're using it to compile fast native binaries out of Clojure
There are lots of comments and no doubt JavaScript really has its problem. But one year still I watching this and how he used mainly JavaScript to demonstrate how to think in clojure way. It is not that bad, guys [VIDEO] (solving problems the clojure way by Rafal Dittwald).
This talk kind of alludes to the data driven stuff at the end: [VIDEO] It's a shame the code examples are just the fp and oop solutions not how it could look in a data oriented way
In spite of its name this video use JavaScript to implement a game using the three styles of programming. Great video learnt from hacker news: [VIDEO]
Sometimes the architecture/algorithm matters, and sometimes the architecture/algorithm needs to align with the language. Absent seeing the broader code base [1], I'm inclined to think that the author's larger design led to these expensive functions existing as they did [2]. Pure speculation on my part, but if one has a lot of experience with imperative, mutable languages, one might design a system that ends up being not so great when written in a functional, immutable language. If so, then seeing improvements when directly porting to an imperative, mutable language might be not so surprising. Tangent: Regarding the power and importance of code structure, I highly recommend watching "Solving Problems the Clojure Way" by Rafal Dittwald at Clojure North 2019 [3]. [1] I didn't see a link, but if it's available, I'd love to take a look. [2] The `rule-field-diff` function for example seems to be burdened with some odd choices, e.g., taking in two "rules" as arguments, (which seem to be collections of rules keyed by field), then using two hard-coded "operations" (also keyed by field), and yielding a map whose values are sequences by field (I think). Off the top of my head I don't see why this fn needs to work across multiple fields in the first place (i.e., any field-specific "loop" should be in a surrounding context. Ditto for `diff-rules-by-keys`. [3] [VIDEO]
-- (Even if you don't read this whole comment, I urge you to watch this fantastic video which illustrates procedural, OOP(lite), and FP approaches to a sample problem: [VIDEO] (Despite the name, it illustrates JavaScript, not Clojure). If you follow this approach, you don't even have to tell people you are doing FP. You'll just end up with better, more understandable, and more easily testable code.) -- The early (early as in C++ days) benefit of OOP was probably that it made programmers stop and plan before coding. Having learned FP 20 years after learning OOP, I feel certain that I can do the same things in less and more understandable (and MUCH more easily testable) code in FP. OOP was awesome for a small set of cases and for academic scenarios. But like REST, it doesn't map well to all needs. Then it becomes awkward and unnecessarily complicated. FP, or simplified as immutable data transformations with necessary mutations pushed to the edges, works everywhere, all the time. In FP you can still choose to model your data in hierarchies, keeping some of the useful bits of OOP. But it's still data in, results out. Until you've spent time on real projects in both, you cannot appreciate why FP is superior. (And to be clear, I'm not even talking about Haskell and type-obsessed FP. Perhaps because I'm not a Haskell guy, I can't appreciate it. But it smells to me like an extreme of a good thing (and therefore not usually the best thing for the situation); but I digress.) Concretely
I understand your worry, but I've had a quite opposite take on this. I think we can agree that it's not that hard to find ANY job as an experienced developer. However it's much more difficult to find a great, satisfying job. For that you need to navigate around a lot of corpo-bullshit type of projects, and Clojure has served me well as a useful filter in doing that. My reasoning is that Clojure is niche enough that when company is using it, you can assume that it's due to a deliberate technical choice, and not just because of its popularity. That tells me two things that are symptomatic, in my opinion, of a healthy tech company culture: - tech decisions are made by engineers, not by top-level executives, - their conclusions and bets align with mine because we all see and agree on Clojure's edge over more popular solutions. Admittedly, there's always a risk that someone just followed the hype and got out of their depth but I think this risk is relatively small, because Clojure's no longer a new kid on a block and choosing a tech stack is a major decision and usually done by senior tech leadership, hopefully less hype driven. Of course, Clojure is no silver bullet and it's just a tool that gives you enough rope to hang yourself. Messy codebases are just as possible as in other languages, especially when the team is new to lisps that are very different from mainstream languages, but that's a nature of software development - you learn with the experience. I do cringe when I look
In the second part of the "Solving Problems the Clojure Way"[0] talk, the speaker shows step-by-step transformation of the heavy imperative (book-keepish) JavaScript code to a more functional approach. As a result of transformation, ~95% of the code is easily unit-testable and the only impure code is the call to main which basically starts all the domino falling. [0] [VIDEO]
I like to build this way when possible. Unfortunately, I find many people - especially tech leads - resistant to this approach. The first and most common reason is, "Why do I need this? What we are doing is fine." Or when the attitude is positive about it, the common issue is, "I think this would be too difficult for our devs to adopt." I find both of these scenarios disappointing and frustrating, because technology (and software) is usually about improving processes and systems so better results can be made more easily. But at this point it feels like a lost cause, or rather a hill not worth dying on. For my own projects, I go this path; for others, I work dumber and keep the corporate apple cart upright. Rant aside, there is a video which I really like that demonstrates this functional core/imperative shell approach: Solving Problems the Clojure Way - Rafal Dittwald. It is a Clojure talk, but it gives an imperative to functional refactor demo in JavaScript in the middle of the talk. Even though it is a toy example, it is big enough that the result shows a meaningful difference in approach. [VIDEO]
> I would love a language that has this gradual evolutional abstracting as a core concern. That makes it easy. Where you can start from simplest imperative code and easily abstract it as the need for this arises. This is about how I write Clojure. I start out with some code that does the thing I want. Either effectfull code that "does the thing" or functions from data to data. After a while, I feel like I'm missing a domain operation or two. At that point I've got an idea about what kind of abstraction I'm missing. Rafael Dittwald describes the process of looking for domain operations and domain entities nicely here: [VIDEO]
This is a common idiom, and does not necessarily imply mutation. Even in cases where you often do have mutation, say in databases, the benefits of a functional approach lie having pure functions between mutations rather than one big ball of Xs sometimes mutatingYs via Zs. Here[0] is a wonderful talk that demonstrates this in practice. 0. [VIDEO]