6 ms·
I've been working in Clojure now for about 12 years. Maybe 12+ years of Java prior to that. I've created some great apps, and great libraries (in both Clojure
by hlship 2y ago
I've been working in Clojure now for about 12 years. Maybe 12+ years of Java prior to that.
I've created some great apps, and great libraries (in both Clojure and Java).
I often describe Clojure as "the least worst programming language", which is an off-handed complement, but I think accurate. Things you don't like can generally be fixed (at least locally) using macros and libraries. The core is strong, a good basis for building things ... and as described all over this thread, stable.
As you master your tools, you gain a level of speed and precision in your work that I have not found elsewhere. The REPL-oriented workflow is a central value proposition in Clojure, and many features (and a few limitations) of the language exist to properly support it.
Working in Clojure feels like I'm working "with" my code, molding it like clay. My prior experiences in Java and Objective-C were so much slower, with long code-compile-test-debug cycles that are compressed down to instantaneous responses in the running REPL.
- rootnod3 2y agoHaven't worked much in Clojure, but I have the same experience with Common Lisp. The malleability and live image workflow is just very pleasant to work with.
- erichocean 2y agoClojure is like that, but because data structures are default immutable, and all of the standard library (and the vast majority of 3rd party libraries) are also default immutable, the stress level is much lower. You can still get mutability and I do this on every project. But it's a very small percentage of the code, less that 1%, and also well-defined. Something like FlowStorm [0] isn't really practical in anything but Clojure, and things like Clerk [1] are easy and very natural. [0] https://www.flow-storm.org/ https://www.flow-storm.org/ [1] https://clerk.vision/ https://clerk.vision/
- rootnod3 2y agoI know. What I just miss in other implementations is the live reflection in the SBCL REPL via Sly/Slime for example. And conditions. When I do CL, I try to code it in a more immutable style and avoid things like self until I get my own version bootstrapped.
- eddd-ddde 2y agoHow does the REPL approach scale in very large codebases? I.e. code that talks to multiple services, complex configurations, etc..
- huahaiy 2y agoScales very well. Immutable data pairs great with REPL. Because data are immutable, you don't need to care about where that data come from and where it will go. Just focus on what you need to do with that data at the point you work. Everything is localized due to immutability.
- chamomeal 2y agoI’ve started learning clojure recently and I haven’t quite grasped the REPL yet. I really like it, but so far the type of feedback it provides feels similar (and sometimes inferior to) a static type system. I mostly use it as a tool for answering “wait what data does this return?” And of course trying functions as I’m building them. Are there any tricks or habits you learn with the REPL that go beyond what a static type system gives you?
- m1n1 2y agoI worked with a 60K LOC thing* that talked to multiple services and had complex configuration. Ran fine on my laptop pointed at the company's dev env. The REPL let me test my changes while inside the thing as it ran. No problems. Someone wrote a nice *recording* debugger too which helped immensely -- no more "oops, I'm past the interesting part and have to start over" * in prod we usually give it a small number of large instances
- m1n1 2y agoForgot to add: multiple threads ... multiple DBs ... multiple topics on more than one kind of message queue ... hitting and serving REST endpoints -- all no problem for the REPL and the debugger[0]. If the thing was in Java, each fix attempt would mean waiting for startup and state re-creation. And each successful debug could have meant multiple sessions (vs visiting any mix of spots in a single recording) [0] https://www.flow-storm.org/ https://www.flow-storm.org/
- gavmor 2y agoI played with Clojure just a bit in 2014 because I wanted to write GUIs in Om, and this gave me a seriously warped habit of calling React.el('div',...) for a while. Sorry not sorry. I'm used to using TDD for fast feedback as I'm molding my code. Do you miss unit testing? Or, do you find that the REPL in no way obviates unit testing? And, do you miss static typing?
- huahaiy 2y agoREPL code is copy/pasted straight into tests. So really, REPL is for helping write tests. BTW, when Clojurians talk about REPL, it's not about that separate window where you type and run the code as in other language such as python. They are talking about an invisible REPL running behind the scene, to which they send code within their editors, and the results show up in the editors too. There's no need to "miss static typing" in Clojure. If I need static typing, I just write deprotocol and deftype in Clojure, as many Clojure libraries do.
- gavmor 2y ago> copy/pasted When I've seen it done, it's seemingly executed in-place, which is very cool.
- ndr 2y agoThank you, this is the most concise description I've seen for the REPL. That gets often lost due to the curse of knowledge. It's a completely different thing to be coding "from within your running program" and it's hard to signal that to who has never tried.
- lkitching 2y agoNeither defprotocol nor deftype introduce static typing into Clojure. Errors in their usage are not checked statically and are only discovered at runtime.
- rrgok 2y agoSo what happens at runtime if errors are found?
- pjmlp 2y agoNot the same thing, but having something like JRebel can get quite close, and even if jshell isn't the best example of REPL, it isn't that bad either.
- Byamarro 2y agoMaybe I miss what REPL really is, but... If REPL is the main value proposition, how is it better from average JavaScript development? Dev tools allow you to basically interactively work with your code.
- cess11 2y agoYou can keep a JVM running in the background with your project loaded and send stuff there from your IDE/editor. I don't think this is possible with JavaScript.
- dmos62 2y agoYou can eval strings in Javascript, so pretty sure that's possible.
- cess11 2y agoLooking around I don't find any maintained projects for this purpose.
- stronglikedan 2y agoIt's just a native function named eval(), so I wouldn't expect to find projects built up around it.
- cess11 2y agoThat's not enough, there ought to be IDE/editor integration and so on. Here's one such project: https://github.com/swank-js/swank-js https://github.com/swank-js/swank-js
- throwup238 2y agoQuokka.js would probably be the nearest JS equivalent.
- deleted 2y ago
- xigoi 2y ago> Things you don't like can generally be fixed (at least locally) using macros and libraries. What macro do I use to make it not run on the JVM? :)
- erichocean 2y agoThat's one of it's best features! But it runs on other things—Microsoft's CLR, Dart's runtime, JavaScript's runtime, Erlang's runtime, and with Jank, on top of LLVM.
- chamomeal 2y agoBabashka!
- barrenko 2y ago"...not as clumsy or random as AI, an elegant weapon from a more civilized age."
- nogridbag 2y agoI gave Clojure a shot some years ago and even wrote an important tool used daily by all employees at our company in Clojure. The problem for me was maintenance. If I had to make any change to that code, I had to dive into the REPL just to understand it. Whereas with something like Java, even if something is poorly written and not documented, I can get at least a minimum understanding of the code just looking at the types. I've been working on a large modern Java application lately and have never really felt the need for a REPL workflow even after having been exposed to it in Clojure. I tend to structure my Java code so it can be easily unit-testable and then just run the suite of unit tests (several thousand) in a few seconds as needed.
- nathan_compton 2y agoWhat about core.typed. I find gradual type systems to be hard to work with for some reason.
- lucyjojo 2y agocore.typed main problem for many years was that it was maintained by 1 (busy) student. i don't know about nowadays though, he probably has graduated long ago! nowadays i'd just use core.spec/malli/other honestly (for what i use clojure for).
- incangold 2y agoBuilt a significant system in Clojure (from several smaller systems). Same experience. I wish Hickey had built gradual typing in to the language. I still love Clojure anyway.
- lucyjojo 2y agomaintained a few clojure code bases at my old company for 10+ years i find core.spec did wonders for that problem. also, i have a tendency to write a lot of in-code documentation, whichever language i use. so it probably helps too.
- perrygeo 2y agoI picked up Clojure recently after a 10 year hiatus. My early complaints were around tooling - a Lisp-specific IDE felt all but required to get the benefits of the REPL and structural editing. And leiningen, god how I despise that tool. With clojure-lsp, deps.edn, and more REPL tooling (conjure in neovim in my case), the situation is better now. I find myself reaching for Clojure for almost everything these days - from scripting to data crunching to quick web apps to database work. Clojure is an amazing tool once you grok it - closest thing to a super-power we can get. > working "with" my code, molding it like clay This the best description. Clojure feels very fun/interactive but simultaneously feels rock solid for production work. There is no gap between "notebook" and "prod". Zero compromises. Most other languages pick one or the other (Python - interactive but plagued by runtime errors, Rust - rock solid but clunky to iterate and experiment)