5 ms·
Data Manipulation in Clojure Compared to R and Python
- soumyaskartha 8mo agoClojure never got the data science crowd even though the language is genuinely good for it. Always felt like a distribution problem more than a technical one.
- asa400 8mo agoUnfortunately, having to mess around with a JVM is a tough sell for a lot of data analysis folks. I'm not saying it's rational or right, but a lot of people hear "JVM" and they go "no thank you". Personally I think it's a non-issue, but you have to meet people where they are.
- famicom0 8mo agoMeanwhile, I find it very annoying to deal with the litany of Python versions and the distinction between global packages and user packages, and needing to manage virtual environments just to run scripts. That being said, I am not an expert but that's always been my experience when I need to do anything Python related.
- pjmlp 8mo agoThe irony given the mess of Python setup where there are companies whose business is to solve Python tooling.
- asa400 8mo agoOh, I completely agree. Like I said, it's not rational, but it is what it is.
- cmiles74 8mo agoI dunno, if you can slog through the Python ecosystem then the JVM is starting to look not so bad. Plus with Clojure you don't need to deal with the headache and heartache that is Maven.
- KingMob 8mo agoI think that's true for only a limited subset of programs, though. The Clojure lib ecosystem is nowhere near the size of the broader Java ecosystem, so you frequently end up pulling Maven deps to plug holes anyway.
- pjmlp 8mo agoThat is the goal of a polyglot runtime, and why Clojure was designed to be a hosted language that embraces the platform, unlike others that make their tiny island.
- KingMob 7mo agoUhhh, yes, but I was trying to convey to the parent that most real-world Clojure programs won't isolate you from Maven.
- packetlost 8mo agoidk, I don't think I've had to do anything beyond install the JVM to work with Clojure. I'm not really a fan of the clj commands flag choices though (-M, -X, etc. all make no sense)
- KingMob 8mo agoIt's unfortunate, but people's associations with Java the lang bleed into their beliefs about the JVM, one of the most heavily-optimized VMs on the planet. There's some historical cruft (especially the memory model), but picking the JVM as a target is a great decision (especially with Graal offering even more options).
- pjmlp 8mo agoExactly, especially because there isn't THE JVM, rather a bunch of versions each with their own approaches to GC, JIT, JIT caches, ahead of time compilation. Only .NET follows up on it at scale.
- levocardia 8mo agoIn this very post you can see why: the dplyr code is just so much more readable. Like a lot of python, dplyr reads almost like pseudocode: take this dataset, select the columns that start with "bill", then filter so that bill_length is less than 30. So simple and so little fluff!
- erichocean 8mo ago> is just so much more readable I thought that too before I learned Clojure, now I find them equally readable.
- lemming 8mo agoI'm very familiar with Clojure, but even I can't make a good argument that: (tc/select-rows ds #(> (% "year") 2008)) is more, or at least as, intuitive as: filter(ds, year > 2008) as cited above. I think there's a good argument to be made that Clojure's data processing abilities, particularly around immutable data, make a compelling case in spite of the syntax. The REPL is great too, and the JVM is fast. But I still to this day imagine infix comparisons in my head and then mentally move the comparator to the front of the list to make sure I get it right.
- Capricorn2481 8mo agoI am really not in data science, and I have decent Clojure experience. Is there a reason anyone would pick Clojure over something like K? From what I understand, those array languages are really good for writing safe but efficient code on rectangular data.
- erichocean 8mo agoHow about this? (filter ds (> year 2008)) That's a trivial Clojure macro to make work if it's what you find "intuitive."
- deleted 8mo ago[deleted]
- 8mo ago
- ertucetin 8mo agoI’ve built many different kinds of software (backend, frontend, 3D games, cli tools, code editor, and more) with Clojure and have been using it for over a decade now. I can confidently say that, among the list I mentioned, it’s the best for data manipulation/transformation. Thanks to the author for presenting it clearly and showing how the libraries and code look across different languages, all of which do a great job. But Clojure has its own special place (maybe in my heart as well :). I think Clojure should be used more in the data science space. Thanks to the JVM, it can be very performant (I’m looking at you, Python).
- hatmatrix 8mo agoThere was XLISP-STAT before R, but the scientists have spoken. They don't like the parentheses.
- iLemming 8mo agoIf you compare every single language Clojure can emit - Clojure&Java, Clojurescript&Javascript, babashka&Bash, Clojure-Dart&Dart, Jank&C++, Fennel&Lua (even though technically Fennel is only Clojure-like) - the number of delimiters (and often even number of parens) would be universally higher than in the Clojure code. I guarantee it. Clojure has a lower delimiter-to-structure ratio. Java has parens that exist purely for syntactic obligations - `(if (`, `for (`, etc. It's not that Clojure has fewer parens absolutely, yet it has no wasted ones - that is 100% true.
- __mharrison__ 8mo agoGood pandas and polars code should also be written in an immutable way...
- epgui 8mo agoGood python code can exist, but python makes it so easy to write bad code that good python rarely exists.
- nxpnsv 8mo agoAgree. While it is common to see code like these pandas examples, it is very possible to write these manipulations so that they return a new frame or view without changing the inputs.
- olivia-banks 8mo agoHaving "NA" being treated as nil/null/None by default seems like it would cause the Namibia problem!
- QubridAI 8mo ago[flagged]
- thrawa8387336 8mo agoI always wished Incanter took off.
- zmmmmm 8mo agoSeems like it's going to be a tough sell to get people to want to write (tc/select-rows ds #(> (% "year") 2008)) instead of filter(ds, year > 2008) They seem to ignore the existance of Spark, so even if you specifically want to use JVM it feels clearer and simpler: ds.filter(r => r.year > 2008)
- condwanaland 8mo agoCouldn't agree more. R and dplyrs ability to pass column names as unquoted objects actually reduces cognitive load for new people so much (pure anecdata, nothing to back this up except lots of teaching people). And that's on top of the vastly simpler syntax compared to what's being shown here
- iLemming 8mo ago> vastly simpler syntax I've been programming for decades. I've used dozens of different, at times enormously esoteric languages. At one point I built ERPs in a language where operators were abbreviated Russian terms. After just a few years of using Lisp dialects I am absolutely convinced - there's no simpler and more readable syntax than of Lisp's. Anyone who doesn't see that, in my eyes just not made the distinction between familiarity and simplicity. They're measuring how quickly their eyes can parse something they've already seen a thousand times, and calling that readability. But readability isn't recognition speed - it's the cognitive distance between the code and the computation it describes. And on that measure, Lisp is essentially lossless. There's no syntactic residue. No ceremony the language demands for its own sake. What you write is the structure of the thing, all the way down. "You get used to it. I don't even see the code. All I see is blonde, brunette, redhead..." I don't look at Matrix feeling puzzled anymore. I see the truth. People who bounce off the parentheses are reacting to something real: it doesn't look like what they already know. But that's not the language failing them. That's just the last bit of the old syntax dying. Give it a few months of structural editing and a proper REPL workflow, and you won't see parentheses anymore - you'll see shape. You'll see depth. And going back to anything else will feel like someone handed you a map drawn in crayon and called it a feature.
- teleforce 8mo agoAll the comparisons are with scripting and untyped languages perhaps for faster development and more intuitive eco-system to increase developer productivity. In the age of IntelliSense, auto-completion and AI assisted coding, does the choice of scripting and untyped language justifiable for increased in productivity at the expense of safety and reliability? If you're building data system not just for exploratory, surely modern compiled and typed system languages like Rust and D language make more sense for safety and reliability for the end users? Even more so with D language where you can even have scripting capability for exploratory and protyping stage with its built-in REPL facility [1],[2]. This is feasible due to its very fast compile time unlike Rust. It has more intuitive "Phytonic" syntax compared to other typed languages [3]. You can also program with GC on by default if you choose to. Apparently, you can have your cake and eat it too. [1] drepl: https://github.com/dlang-community/drepl https://github.com/dlang-community/drepl [2] Why I use the D programming language for scripting: https://opensource.com/article/21/1/d-scripting https://opensource.com/article/21/1/d-scripting [3] All in on DLang: Why I pivoted to D for web, teaching, and graphics in 2025 and beyond! [PDF] https://dconf.org/2025/slides/shah.pdf https://dconf.org/2025/slides/shah.pdf
- geokon 8mo agoIt's a bit apples to oranges. If you're "building data system not just for exploratory" then you're probably not going to be using any of the presented options. However, in my experience Clojure has an ecosystem where there it is very easy to transition from exploring/playing with data at the REPL to a more robust "pro" setup that's designed to scale, handle failures, etc.
- teleforce 8mo agoI understand the sentiments but I disagree with the approach, it's probably efficient for exploratory but not effective for everything else including prototyping and systems development. For any engineering work, including software engineering you choose the best tool for the job. In D you can have the high performance tool capable of bit shifting, string processing, array manipulation (to name a few) and from scripts to highly concurrent low-latency applications (see presentation in the ref [3] above by Prof. Shah from Yale). It's a shame that the proper typed programming language are being ignored just because of programmers' locally sub-optimal preferences and limited exposure. The productivity increased using typical scripting languages including Python is diminishing everyday with the proliferation of IntelliSense, auto-complete and AI assisted coding. For production codes, the scripting language based systems if they ever made it to production (mostly do e.g AirBNB, Twitter, Shopify, Github, etc) will be a maintenance headache and user nightmare, if the supports are not great and not unicorn start-ups. The last thing you want is that your saved eclaim form that you spent many hours preparing totally dissapeared since the system cannot recall the saved version. Granted this can be because of many reasons, but most of the problematic production systems are mostly written in scripting languages including Python because these are the only language the programmers know and familiar with. Adding to the insults are the readily available so called "battery included" libraries are convenients but ironically written in other compiled but unsafe system language in C/C++.
- manudaro 8mo agoThe Clojure tablecloth performance numbers here are pretty surprising, usually see Python/polars dominating these benchmarks. Been running similar transformations on transit data feeds and polars consistently outperforms pandas by 3x-5x on the group-by operations, but hadn't considered Clojure for the pipeline. Anyone actually using tablecloth in production data workflows?
- daslu 8mo agoGreat post. The way Tablecloth unifies column processing and row processing in a functional way is so elegant.