[HN Gopher] Why Clojure?
___________________________________________________________________
Why Clojure?
Author : jgrodziski
Score : 103 points
Date : 2025-02-22 09:44 UTC (1 days ago)
(HTM) web link (gaiwan.co)
(TXT) w3m dump (gaiwan.co)
| fithisux wrote:
| Now LISP has the big three. CL, Scheme and Clojure. Each
| introduces a fundamentally different way of thinking and all come
| from standards or standard implementations. There is also
| Newlisp, more akin to R and Julia and other LISPs each bringing
| some new things on the table. Still you need to have an idea from
| the big three to appreciate what LISP is all about.
| moi2388 wrote:
| Because you want the type safety of lisp with the simplicity of
| the jvm /s
| gleenn wrote:
| You are being snarky but I'll take immutability over types and
| interoperability and access to a vast and stable ecosystem over
| the simple and extremely limited and underperforming
| alternatives. Thanks for the segway. I also cannot understate
| the reasoning ease that comes with basically everything being a
| static, top-level function. Testing never requires mocks
| because you can redef any function anywhere trivially when you
| otherwise would reach for a mock which tends to be painful,
| complicated, and requires comlex mocking libraries. Even with
| immutability by default, you get an extremely performant
| platform that usually stomps on nearly all the dynamic
| languages you might otherwise choose like Python or Ruby etc.
| And you get first-class functions and a concise and extremely
| stable language that is a joy to program in. Thanks Rich and
| Alex!
| AnimalMuppet wrote:
| > I'll take immutability over types and interoperability
|
| OK.
|
| > Thanks for the segway.
|
| A segway is a motorized transport; a segue is a transition to
| a different topic. So this could be considered a type error,
| and demonstrates why you need types, not just immutability.
| slowmovintarget wrote:
| While amusing, I still disagree.
|
| Complex static type syntax ends up infecting your code,
| because the syntax becomes load-bearing. A change to one
| type has a tendency to ripple through the entire body of
| code. This means you have tight coupling as a consequence
| of the syntax, which is a bad trade-off. Clojure's strong
| dynamic abstract types allow you to focus on the function
| of the code instead of its structure. Trying things out in
| the REPL first helps you find many of the things that you
| might need to wait for a compiler to find.
|
| There are studies that estimate that the kind of bugs
| shipped to production that strong static types help prevent
| account for only 2% of defects. The rest are things like
| off-by-one errors, design errors, and incorrect logic.
|
| The other thing a static type system can help you with is
| reading code. But it's primarily an aid to people
| unfamiliar with the language, or put in more popular
| parlance a "skills issue." We know tooling can navigate the
| code, because we have tooling that does so (language
| servers, CIDER, Calva, Cursive, Conjure...). This means
| that static typing for the purpose of merely reading the
| code is a crutch. I'd argue it's also a crutch or training
| wheels for writing correct code.
|
| You can't run with crutches. You can't corner well with
| training wheels. Clojure is meant to make the expert nimble
| and fast. The main thrust of its design is to make
| experienced devs more productive, like professional tools
| without novice guide-rails make experienced craftsman more
| productive.
|
| Rich Hickey gave a talk where he mentioned this idea of
| guardrails on the highway. He told a story of how we all
| get in our car, then bump into guardrails all the way to
| our destination... right? Of course not, we learn to keep
| the car in our lane of travel, to signal others when we
| switch, and to blend with other traffic on the way. (Rich
| was talking about TDD, but it still applies to static type
| systems, IMHO.) Clojure is that power tool without all the
| novice presets. It's the automobile we keep away from the
| rails when we drive it.
|
| Mutable state is arguably responsible for far more defects
| shipped than type errors. Mutability is only a thing
| because hardware constraints required reuse of memory
| locations instead of allowing for persistent data
| structures. Thankfully, for "situated" applications that
| start and operate for extended periods, those constraints
| aren't so tight.
|
| If you have to choose between immutable data and static
| types choose immutable data. But why not both? We can have
| all our luxuries, right? Because you have to spend so much
| more time proving things to the compiler, you have so much
| more syntax to manage. More code and more syntax for the
| same problem is almost always worse. I'll take Clojure.
| AnimalMuppet wrote:
| > There are studies that estimate that the kind of bugs
| shipped to production that strong static types help
| prevent account for only 2% of defects. The rest are
| things like off-by-one errors, design errors, and
| incorrect logic.
|
| If you've got a reference, I'd be interested. (Not saying
| you're wrong...)
|
| > The other thing a static type system can help you with
| is reading code. But it's primarily an aid to people
| unfamiliar with the language, or put in more popular
| parlance a "skills issue."
|
| It's an aid to people who are unfamiliar with the
| _program_ , who have no idea what the shape of "that
| thing" is. (Especially, what is the shape of the thing
| that this function gets called with? For _all possible
| callers_?)
|
| I've been hired to start working on code bases that have
| existed for a decade or two. Static, stated types are a
| life saver. Sure, they may slow you down while you're
| creating the code. It's easier to not have to explain
| everything that's in your brain. But when you and your
| brain leave, and I'm left with a bunch of variables that
| I have no idea what type they are - what are the maximum
| set of types that they can be for all paths through all
| callers - then I _really need_ static types to help me
| figure out what 's going on.
| slowmovintarget wrote:
| Or you need a REPL that lets you poke at the living code.
| It's just different.
| slowmovintarget wrote:
| On the studies, I believe the results were drawn from
| this [1] study and followed up here [2]. I seem to recall
| reading a blog post based on these results, but I could
| be mistaken.
|
| [1]: A Large-scale Study of Programming Languages and
| Code Quality in GitHub
| https://dl.acm.org/doi/10.1145/3126905
|
| [2]: On the Impact of Programming Languages on Code
| Quality: A Reproduction Study
| https://dl.acm.org/doi/fullHtml/10.1145/3340571
| synthc wrote:
| Immutability removes so much accidental complexity, it makes
| whole classes of mistakes dissapear. I'd also take
| immutability over types.
|
| Clojure sort of guides you to simplicity, building everything
| out of functions and simple datastructures has big advantages
| when testing and reasoning about code.
|
| I do find that in larger code bases, Clojure lack of types
| causes friction (spec is just a bandaid, not a fix).
|
| There are languages with immutability and types (like
| Haskell), but these don't have the get-shit-done factor I
| seek.
| yogthos wrote:
| I've used Clojure for over a decade and the JVM has never been
| an issue. The only people I see complaining about the JVM are
| people who never actually worked with it. Meanwhile, there's
| zero evidence for the notion that static typing has any impact
| on code quality. https://danluu.com/empirical-pl/
| jrsj wrote:
| Elixir is a little less flexible since it doesn't have the JVM
| interop but for domains where it's a good fit I think it's _even
| better_ at most of this stuff (and easier to teach people
| unfamiliar with FP or lisps)
| nbittich wrote:
| I tried clojure long time ago, honestly what made me give up is
| when I saw a java stacktrace in place of a proper error message
| when learning it. Also the repl was slow. The UX sucked, I wonder
| if they improved that
| jb1991 wrote:
| The repl isn't slow, what are you referring to?
| ekzy wrote:
| Probably referring to startup time. Larger apps solve this
| with the "reloaded" type of workflow
| (https://www.cognitect.com/blog/2013/06/04/clojure-
| workflow-r...)
| gleenn wrote:
| There are no Clojure stacktraces specifically, only JVM/Java
| ones. Clojure sits closely beside its host so there is no
| difference. People do complain about stacktraces and they've
| made some improvements. But they are long because the
| abstractions run deep and the function you passed in might be
| on the stack at the very bottom with the actual origination of
| the cause.
| fiddlerwoaroof wrote:
| I used to hate JVM stacktraces but they're incredibly useful
| and I miss them when I'm using other ecosystems these days. The
| way JVM exceptions do "caused by" when an exception is thrown
| while handling another exception gives so much more information
| than other languages. It's also relatively simple to filter out
| the noise when you want a concise error message: just remove
| lines that start with a tab.
|
| CIDER (the emacs IDE for Clojure) does a really good job of
| filtering the stack trace and presenting several views
| depending on what you care about. L
| kccqzy wrote:
| Usually there is also an error message together with a stack
| trace. I like stack traces: they are usually more informative
| than just an error message. I had lost too much time debugging
| Haskell exceptions where they by default do not come with any
| stack traces.
|
| The only thing that really sucked is just the documentation.
| They are overly concise. You end up relying on non-official
| sources of documentation.
| ilrwbwrkhv wrote:
| I run a multi-million dollar business which I started with common
| lisp. I since moved away to go and then rust but I've been
| looking at clojure again lately.
|
| For a team that needs to get s** done and has more per employee
| productivity than Faang combined it's hard to beat the speed with
| which you can build things when you have the repl and interactive
| programming.
|
| The jvm while doesn't have great error messages is a fantastic
| runtime.
| giancarlostoro wrote:
| > which you can build things when you have the repl and
| interactive programming.
|
| This is how I use Python to be honest. If I'm unsure of
| something, I just bust out the REPL.
| ilrwbwrkhv wrote:
| I know people talk about python being Lisp without brackets,
| but for example in SBCL and in other lisps like clojure I
| could just run a larger function, figure out that there is
| the wrong output, change a tiny function in it, eval that,
| eval the larger output, get the result. In SBCL there is also
| the break loop which is just magical.
|
| I do not know how you do that in python without using a
| debugger and stepping through the code line by line. To be
| fair I used Python only a little bit almost a decade back.
| Are things more interactive now?
| zelphirkalt wrote:
| I think in Python REPL you just have to redefine the whole
| larger function. I am not aware of a way to access
| internally bound identifiers, or even modify what values
| they are bound to.
| codr7 wrote:
| The condition framework/break loop is one thing I wish more
| Lisps would copy.
| kubb wrote:
| I feel like there's a minimum developer quality that's needed
| when using a language like Clojure, without static typing, and
| with a wealth of idioms and best practices that need to be
| followed and libraries that need to be known.
|
| Without it it's a matter of time before the codebase can't be
| developed anymore and the software doesn't work as intended.
| jb1991 wrote:
| Yes and actually this happens often that a project is moved
| to another language because of maintainability, especially
| when a key person leaves the company.
| lispisok wrote:
| I would love to see how Clojure's "wealth of idioms and best
| practices that need to be followed and libraries that need to
| be known" compare to almost any other popular language.
| Clojure is by far the simplest most straightforward language
| I've ever used with very few details and gotcha's that need
| to be memorized.
| oDot wrote:
| You should give Gleam a shot. No REPL, but its simplicity,
| functional-ity and the BEAM lend themselves to the get-shit-
| done approach
| ilrwbwrkhv wrote:
| Gleam takes more code to write than rust. Doesn't have a
| strong enough documentation / ecosystem yet. But I agree the
| beam VM is very underutilized and underappreciated.
| ndr wrote:
| Immutable data and REPL is where is at for iteration speed
| though.
| closeparen wrote:
| Different meanings of "productive." In a language like Clojure,
| you could have one engineer rewrite the entire system in a
| weekend. Which is very valuable if you're an early-stage
| startup! But you are probably leaving some corporate
| productivity on the table if you already have the maximum
| number of people who can coexist in the codebase without
| interference, and +EV work is still piling up in the backlog.
| agumonkey wrote:
| Can you describe your stack and workflow ?
| MarkMarine wrote:
| Learning clojure has improved all of my programming in every
| language. I'm in love with the simplicity and smallness of it.
| Rich said one of the reasons he built it was he was programming
| like this already (pure functions acting on data) but the
| languages he was using didn't support it well. There is a lot to
| be learned and applied even if you can't use clojure at work
| every day.
| ampunix1337 wrote:
| Idk ... it feels Clojure stalled since Nubank bought Hickeys
| company. Worst thing: spec is still in alpha !! I put so much on
| this ... but nothing really happened since ... idk 8 years?
| ekzy wrote:
| Call it "stalled" if you like, it's stable and it's pure joy. I
| can just get stuff done with Clojure. And things that may seem
| inactive, like that lib that you need that hasn't had a commit
| in 8 years, turns out that it just works and doesn't need to
| change. This is commonplace in Clojure.
|
| Spec is still alpha and I'm not sure it will evolve more or if
| it'll be something completely different. At least they're not
| pushing you down the wrong path. Use/look at Malli instead of
| spec.
| yogthos wrote:
| Spec isn't really essential to Clojure, and most people use
| Malli nowadays which is very actively developed
| https://github.com/metosin/malli
|
| I see the fact that there isn't much happening with the
| language as a positive myself. I want the core language to be
| small and stable. The big difference with Clojure and most
| languages is that it makes it far easier to implement new
| semantics in user space. It has a powerful macro system and new
| ideas can be expressed using libraries instead of having to be
| baked into the core language itself.
|
| Most language grow through accretion as usage patterns change
| over time. New end up features end up getting bolted on to
| facilitate that, and the language keeps growing. The problem
| here is that the scope of things people have to know keeps
| growing as a result.
|
| Meanwhile, Clojure managed to stay small and focused, while
| different kinds of ideas are expressed using libraries. When a
| new idea comes along people can just use a new library, and
| they don't have to learn about all the previous libraries that
| worked differently. I think this is a huge benefit from user
| perspective.
| slowmovintarget wrote:
| But have you seen _flow_? I don 't think it's stalled at all,
| and Nubank seems to have become an enabler to the ecosystem.
|
| I mean, Datomic is free to use!
|
| [core.async.flow]:
| https://github.com/clojure/core.async/commit/03b97e0b3e0ec32...
| lukev wrote:
| I don't know what you're talking about, 2 new versions of
| Clojure have come out since then, both of which have more
| substantive changes than the previous couple versions.
| codr7 wrote:
| Tried to love Clojure, but found it to opinionated as a daily
| driver for me.
|
| Sometimes I just need to get some code running to see a result,
| which is my main use case for Lisp.
|
| I used to default to Common Lisp, but it needs a lot of
| scaffolding to become ergonomic, and even then it has too many
| quirks to be really enjoyable for me.
|
| So I started designing my own:
|
| https://github.com/codr7/eli
| thom wrote:
| What wall did you hit? I can jump into a Clojure REPL without
| needing a project or even any files.
| cellularmitosis wrote:
| Macros being supported via quoted arguments is clever
| viccis wrote:
| I like Clojure well enough, but it feels like every single time I
| see it mentioned now is an write up trying to justify using it.
| phtrivier wrote:
| The part about the "stability" is a bit surprising - in my
| experience, I try playing with clojure about once a year, and
| every time, everything is different (I mean, I had to go through
| classpathes, then lein, then boot, then deps.edn - what is the
| current way to "try and run a program" du jour ?)
|
| Also, is running your "hello world" still going to be incredibly
| slow, or has something changed in the core system (I know I'm
| supposed to fix that with graails. Or is it babashka ? Or
| something else, I suppose.)
|
| It's really sad, because i just love the language. Reading about
| clojure is a pleasure. Trying to write anything has always been a
| blocker to me, though. Maybe that's the true "immutable" nature
| of the language ?
| cschep wrote:
| While clojure has gained (accreted) more options of ways to run
| things, every single one of the ways you mentioned still work!
| It's extremely stable in this regard. Nothing was taken away
| because there is a new hotness. Sure, things were added. Why is
| that bad at all?
| newlisp wrote:
| Using Clojure without Datomic can be frustrating since you feel
| like you lose some of the language's value, as you likely want to
| extend its philosophy and style to the database as well. Of
| course, Hickey probably knew this when he started planning
| Clojure, which is why he also created Datomic. However, Datomic
| can be a hard pill to swallow
| dustingetz wrote:
| Why Clojure = for Datomic, Rama, Electric and Missionary. No need
| for long blog post - this stack screams if your app fits within
| its intended operational margins - enterprise cloud information
| systems and rich interactive web products.
| d_t_w wrote:
| My co-founder uses the phrase minimal-viable-company for maximum-
| viable-product.
|
| We bootstrapped for 5 years to well over $1M+ ARR before recently
| closing a seed round[1], Clojure played a large part in our
| ability to deliver as a small team. Also in our general happiness
| as programmers, it is a nice language to work in.
|
| We will grow our Clojure core product team over the next couple
| of years, but mostly the funding round is about balancing our
| business to keep up with our product delivery.
|
| Clojure has been very good to me (I had 15 years on the JVM prior
| to moving to clj/cljs in 2013-ish). YMMV.
|
| [1] https://factorhouse.io/blog/articles/from-bootstrap-to-
| black...
___________________________________________________________________
(page generated 2025-02-23 23:00 UTC)