Hacker Newsnew | past | comments | ask | show | jobs | submit | midnight_eclair's commentslogin

the benefit of lisp in an editor with integrated repl environment is that you get to see immediate feedback by easily evaluating chunks of your code as you navigate it, without copying stuff back and forth between the editor and the repl

and the benefit of lisp comes from the fact that every expression is fully delineated by parentheses, so you don't need to select any text, find the start or the end of any syntactic construction, you just eval the form you're standing at and see the result

or just as easily you can wrap that form, bind the locals to test values and eval that to see what changes


i'm surprised anybody coming from clojure would say this.

you absolutely do NOT need to learn paredit to write lisp, any modern vim/emacs/vscode plugin will just handle parentheses for you automatically.

that said, if you do learn paredit style workflow - nobody in any language in any ide will come even close to how quickly you can manipulate the codebase.


I realize how lame it is to relitigate Clojure's downsides every time it comes up. I fell into the same trap that annoys me about Elm threads: people who haven't used it in a decade chiming in to remind everyone they didn't like some aspect of it. Wow, such contribution.

It's like seeing that a movie is playing at the theater so you show up only to sit down next to people to explain your qualms with it, lolz. Sometimes you need to let others enjoy the show.

The OP of this thread even said all that needed to be said "The learning curve is steep but very much worth it" yet we're trapped in this cycle because someone had to embellish it with a listicle.

I take my post back.


I didn't realize it was a no-no to share opinions here.

Plus to be fair we're having this discussion in the context of an article from 2021 that just rose to front page of HN, only to repeat the same set of pros we've been hearing about Clojure for ages (code as data, repl, etc).

Probably should expect some dissenting opinions.


i can link you similarly undecipherable walls of text in rust and zig and c

but i bet if you sat down a junior developer not yet entrenched in any style yet, they'd be able to grok lisp code MUCH faster than the intricacies of syntax of the other alternatives ¯\_(ツ)_/¯


To me, it's the uniformity and limited rules that make lispy languages attractive.

Javascript's destructuring syntax can look almost indecipherable, and it is mostly because the language syntax is not uniform in its meaning.

  const f = ({a: {b: [x, , z] = [], c: {d: w} = {}} = {}, e: [, y] = []} = {}) => ({x, y, z, w});
This is a function written in one of the most popularly used programming languages in the world.

My opinion about this, is that it appears to depend on how a particular person's brain is wired, as to which language(s) they will understand faster and like. There can be a "winner" in terms of which language more people gravitate towards, but then that is very relative to many factors, including corporate influence.

People also put themselves into bubbles. Once in, they can filter out other languages (with all kinds of excuses), and be overly focused on certain families or only specific languages.


so many similar conversations happening, it's refreshing xD

https://news.ycombinator.com/item?id=47587386


every time i go back to writing non-clojure code outside of repl-driven environment i feel like a cave man banging rocks against each other

no amount of ide smartness or agentic shenanigans is going to replace the feeling of having development process in sync with your thought process


You just made me wonder if REPL driven development and LLMs can be better combined somehow.

This is already a strong theme in the Clojure ecosystem, e.g.:

https://github.com/BetterThanTomorrow/calva-backseat-driver


I use a REPL in tmux. That lets Claude code read/write to it easily, as well as letting me take manual control to investigate.

even if i would generally agree with the principles, no amount of markdown prompting is going to increase my confidence in agent's output and so i keep asking this question:

> what do you use for normative language to describe component boundary, function and cross-component interactions?

something i can feed into a deterministic system that will run a generative suite of tests (quickcheck/hypothesis/clojure.spec) that will either give me the confidence or give the agent the feedback.


OP / Author here, I started closer to where you are but ended up realizing I've led a few eng teams and was never satisfied with code quality. What I COULD be satisfied by was moving our metrics in the right direction. Testing coverage, use cases covered by E2E / integration tests, P99/backend efficiency metrics, cost of infrastructure and obviously user growth along with positive feedback from Users.

That said, I don't "vibe" because it creates great code I love reading, but I can monitor and move the same metrics I would if I was managing a team.

I also use code tours a bit, and one of my first tools I needed and built (intraview.ai) was to support this need to get deep in the code the Agents were claiming was ready to ship.


inb4 it's AI generated and Tom sold his channel to some faceless corpo 3.. 2.. 1...

I don't think Tom would ever do that. From firsthand accounts from people I know who know Tom, that would be extremely out of character and not consistent with their moral compass.

Veritasium dude sold his channel so why not Tom?

I meant to reply days ago, but, if I were to hazard a guess:

• Tom Scott's brand is Tom Scott the Creative Vision, and Tom Scott the "It's Ready When It's Ready". Sacrificing either would drive away the audience.

• Having a presence on a creative collective platform like Nebula affords a great deal more autonomy here. Yeah, while the YouTube channel occupies a special and inimitable place, there's not a lot of recourse from their mercurial and non-transparent algorithmic changes.


clojure itself is a joy to use, on the web or outside of it

BUT

it doesn't have the equivalent of rails, mostly because lispers are an opinionated bunch and can't come together to agree on how web development should be done

the frameworks that do exist are more of a collections of libraries with some plumbing to connect the dots


Which in reality isn't a problem, once you absorb the ideas of Clojure and try to apply them when using Clojure. Composition of well picked libraries beat batteries-included frameworks for most use cases, both short term and long term, at least in 99% of the cases I'm writing Clojure/Script code.


I think it actually is a pretty big problem. "Once you absorb the ideas of Clojure" takes months or years to fully get. Composing libraries yourself, like your comment says, requires that they are "well-picked". Stitching together separate libraries is really time consuming and a distraction from the project you're trying to build. It also results in pointless thrashing within a team as everyone has become personally invested in their own mosaic of hand-selected libraries for every little thing. By the time a beginner learning Clojure has researched and put together their web stack and got it all hooked up and is ready to start, the Django developer already shipped their project last quarter, iterated on it a few times, and is on to the next thing.

One big library/framework has huge benefits and network effects, from enabling a big 3rd party plugin ecosystem, to a deeper documentation literature (including paid courses, books, and AI). It means that there's less or virtually zero getting up to speed when changing from one project to an other. It means that the upstream framework team takes care of upgrades whereas you have to consider, when a new technology comes up, how to integrate this into your stack. There's a reason that Laravel, Django, Rails, and Spring each have thousands or hundreds-of-thousands of times more websites in production than all of Clojure combined.

At a meta/discourse level, I also find the Clojure community's tendency to constantly deny and downplay any criticism or even just issue that people face to be really frustrating and counter productive.


> By the time a beginner learning Clojure has researched and put together their web stack and got it all hooked up and is ready to start, the Django developer already shipped their project last quarter, iterated on it a few times, and is on to the next thing.

Yes, but this is intentional. Django developers are optimizing for "easy" which makes it fast to spin up project after project, Clojure developers are optimizing for "simple" which means way longer time to get the project of the ground, to nail all the design before things start to actually be put together, which makes it easier and faster to iterate on the same codebase after years of working on.

Ask the Django developer how easy it is for them to add features after a project they've done that approach with for N years, then compare it to a Clojure codebase, and you'll notice the difference.

Sure, I guess this is "downplaying" and "denying", personally I see people who disagree with me as people who disagree with me, that's fine, I thought that was why we were sharing our opinions in this forum in the first place. But anyways, if you're very deep into "frameworks are clearly superior in every case", that we disagree probably matters less. Best wishes regardless!


Rich's Simple Made Easy talk is really interesting and insightful and I still love it but I think now the distinction is brought out too often almost reflexively, and used as a crutch. Yes "simple" and "easy" are not the same thing, but nor are they opposites. Just because something is "not easy" doesn't mean it's "simple".

I think there are lots of well maintained Django projects. In fact, if I do a search on AI and on google for what one web stack probably has the lowest overall total cost of ownership including maintenance years down the line, Django usually is what comes up, without even specifically searching for/mentioning it.

> if you're very deep into "frameworks are clearly superior in every case"

This is a mischaracterization of what I have said, and is more like the extreme position that Clojure devs seem to take. The original commenter said that Clojure is wonderful, but it's too bad that [for the people who want it,] there isn't the option of a well maintained, all-in-one, batteries included framework. You deny that this is a problem, saying that actually a well-chosen set of libraries are superior (I guess in every case, because if not then it actually would be a problem sometimes).


In my experience, Clojure was a huge pain in the ass to get into, and there's a non-zero amount of community members that talk about it in nothing about aphorisms. I really wanted practical advice, but getting people to talk normally about it was an uphill battle. This made me almost quit several times. But it is a very pragmatic language underneath (which you've already mentioned).

But I'm not sure a framework is really going to change that onboarding process, or help with network effects that much. Elixir has a de facto framework, but it's barely more popular than Clojure. I mean, we had Leiningen starter kits and we have Kit. But what's confusing to me wasn't setting up a project, it was learning how it was wired together. Wiring small libraries together and just passing data can feel surprisingly leaky, and I don't really have to peak into the internals of Laravel the way I do Clojure projects.

I think Biff is a promising step in the right direction. I think the way it has wired things up is easier to follow. But for whatever reason, they made the choice to use XTDB as a default, which is a huge cognitive burden for newcomers. They have an article on how to use something else instead, but this is already getting out of the "it just works" territory if you haven't even learned Clojure yet. But the author is a really nice and talented person, and I am looking forward to seeing where it goes.

> I think there are lots of well maintained Django projects. In fact, if I do a search on AI and on google for what one web stack probably has the lowest overall total cost of ownership including maintenance years down the line, Django usually is what comes up, without even specifically searching for/mentioning it.

Having used Clojure, Laravel, Spring, and Django, I wouldn't touch Django again with a 10 foot pole. I don't know what you're referring to by "doing a search of lowest cost of ownership" but it sounds pretty unscientific. Anecdotally, I do legacy apps, and I have picked up people's Django apps, and I've never loved what I saw. It's a classic fast to start, slow to maintain framework. Huge businesses have been built on it, but huge businesses have been built on everything.


> I'm not sure a framework is really going to change that onboarding process, or help with network effects that much

having one commonly accepted and recommended way does improve onboarding, because it collapses the decision space beginners face. right now they are supposed to make decisions (not even directly, but just through selecting one of the many frameworks) about things like:

  1. which project templating tool to use? (lein, clj-new, neil)
  2. which dependencies management tooling to use? (lein, deps)
  3. which build tooling to use? (lein, tools build, boot)
  4. which web server? (jetty, httpkit, undertow)
  5. which routing library? (pedestal, reitit)
  6. which templating engine? (hiccup, rum, selmer)
  7. how to deal with javascript and it's build tooling? (clojurescript with a host of it's own decisions, bolt ts/js and wire it yourself, dodge that completely with htmx)
whats worse - most of the alternatives overlap in various ways, so making the "best choice" in order to reduce future headache induces quite a bit of anxiety.

yes, multiple frameworks exist that make those choices for you, but then you inevitably hit the problem that some of the components haven't been updated in a while, so documentation is out of date and when you try updating it just for your project you need to fix the framework plumbing and due to number of frameworks, the corpus of useful information on the internet is quite fragmented and the community help is limited, and on and on.

none of this is good beginner experience.

and don't get me wrong, choice by itself isn't bad, focus on composability of smaller libraries is important, dominant framework is not going to improve anything when it locks people into bad decisions.

what we lack is convergence behind a single "reference stack" of libraries that ought to be good enough for the general case and a minimal framework of plumbing that doesn't require dozens of files just to get started.

there doesn't need to be a single way of doing it, but there needs to be a single recommended way of doing it.


I don't disagree with what you're saying. But by "onboarding process" I mean the effort of getting more people into Clojure, not the experience for a single person.

What I'm suggesting is Elixir has everything you're talking about in Phoenix, yet it's still an extremely niche language most people haven't even heard of. Because come on, it's a totally different paradigm than what people are trained to program in. I understand the mental math of "easier means more people," but I don't think that's really going to cut it for Clojure. I had full projects spun up the minute I started learning, but that wasn't where the difficulty was.

So yes, I think having a solid framework is good for Clojure, but the original person suggested it's not popular because it doesn't have one, and I just don't think that's true.


> the original person suggested it's not popular because it doesn't have one, and I just don't think that's true

i agree that it's not a sufficient condition, but it's an important factor and it would significantly improve the onboarding process by collapsing the decision space beginners have to navigate

even going by your definition of onboarding (the effort of getting more people) - dispersing that effort across multitude of dimensions and directions is certainly less effective than coordinating and converging

not intending to have an argument about popularity, but since you keep bringing up elixir - there's a lot that can be said about elixir/phoenix as to why they aren't more popular than they are, but they are more popular than clojure in every recent ranking i've checked ¯\_(ツ)_/¯

if anything, elixir/phoenix is a good example for how strong default improves onboarding and ecosystem cohesion, even if it doesn't make the language broadly popular

i don't look at it from perspective of "what should clojure do to be more popular than php" - there are fundamental reasons why that just can't happen in this timeline

i look at it from perspective of "what does this ecosystem lack that makes it hard for beginners to get going and stick"

and lack of "single recommended way of doing it" is at the top of my list


Yeah, Elixir's Pheonix if anything demonstrates how important a flagship framework/stack plays a huge role in driving language adoption. Despite Elixir coming out after Clojure, and running on a VM that is more esoteric/niche than the JVM, and having a host language which is 1000 times smaller in popularity and library ecosystem size, it still is probably more popular than Clojure at this point and almost all of that is from people picking up Elixir to use Pheonix. And Clojure's use is not just staying where it is, it seems to be in free fall. There used to be dozens of Clojure job postings in Canada, now without exaggeration I don't think there's a single one.

Wouldn’t touch it with a 10 foot pole. What would you prefer over django of the listed above? Curious.

Any of them. My experience with Laravel hasn't been flawless, but I think it's better in just about every way.

The fundamental mistake of Simple Made Easy was how many people interpreted them as orthogonal (or even opposing) qualities, when that's not inherently true.

This led to a lot of Clojure code being simple, but avoiding the hard additional work of also making it easy, and sometimes in even making it complete.

The prime example was tools.deps/deps.edn. It largely supplanted Leiningen for new code, but by being simple and minimal, it led to an explosion of ad hoc, custom tooling for 2-3 years afterwards, as everyone rewrote functionality that Lein already had, but tools.deps was missing. (And I say this as someone who once lost a whole week debugging a subtle maven/lein set ordering bug.)




Welp, nothing I can say is going to make a stronger argument than that.

yep, every word.

Yes, huge selling point in favor of Clojure!

it really isn't, unless your goal is to scare away the casuals.

the wonders of visibility algorithm: https://news.ycombinator.com/item?id=47556827


I guess all the Clojure fans were in their hammocks?

virtually all abstractions are built on top of primitive data types and mappings


> virtually all abstractions are built on top of primitive data types

Obviously. The point being made is that the Clojure style discourages building DSLs and the like and prefers to remain close to Clojure types and constructs. It departs in various ways from traditionally Lisps.


> Clojure style discourages building DSLs

does it really? https://github.com/simongray/clojure-dsl-resources


DSLs typically involves constructing macros that are domain specific (to cobble together a domain specific programming language on top of the host). Most of the linked examples are not macro based and are the exact opposite. They specifying domain specific data layouts built directly using the Clojure-native immutable datatypes. They don't create Domain specific datatypes or function-generating wrappers. It's just rarely necessary

A good example is making GUIs in Clojure. At first there was a cool macro based system called `fn-fx` that maked a JavaFX GUI. Then vlaaad wrote `cljfx` which just used plain Clojure maps and removed the macros entirely. This increased the boilerplate a tiny amount but made the system much more flexible and extensible


> DSLs typically involves constructing macros that are domain specific

a DSL is a constrained language for expressing domain concepts.

in traditional Lisps they are often syntax-oriented, because code is lists and macros are a natural tool.

in Clojure, pervasive use of keywords, vectors and maps allows you to shift DSL design towards data interpretation rather than syntax transformation.

so in Clojure doesn't discourage DSLs - clojure practicioners simply prefer data-oriented DSLs to macro-oriented ones, mostly because they are easier to reason about and process with existing tools, while macros are used more selectively.


The original comment you took issue with "The point being made is that the Clojure style discourages building DSLs and the like and prefers to remain close to Clojure types and constructs". You seemingly read half the sentence and in the most unfavorable way possible. (in context it's clearly not talking about "data-oriented DSLs)

> DSL is a constrained language for expressing domain concepts

What you're calling "data-oriented DSLs" is not constrained.

I guess this is all semantic, but in my book just specifying a data-structure doesn't make a language. You're not extending the host language in any way


> What you're calling "data-oriented DSLs" is not constrained

constraints come from the interpreter, not from the syntax

> in my book just specifying a data-structure doesn't make a language

correct, it does not

what makes it a language is defining constraints on that structure and rules for how it's interpreted

that works both for clojure (where the data structure can involve lists, vectors, maps and primitives) and traditional lisps (where data structure is lists, or to be precise cons cells and primitives)

in both cases macros can be used and are used (but don't have to be used) to prevent immediate evaluation of those data structures according to host language rules and instead change how they are evaluated according to DSL author's rules

for example, datomic queries are just data structures, but they clearly form a constrained language with well defined semantics and the fact that they're not implemented via macros doesn't make them less of a DSL


I think you're talking past each other.

"DSLs" can both mean "Using the language's variant of 'arrays' to build a DSL via specific shapes" like hiccup in Clojure does, and also "A mini-language inside of a program for a specific use case" like Cucumber is its own language for acceptance testing, but it's "built in in Ruby" in reality.

Clojure favors the "DSLs made out of shapes" rather than "DSLs that don't look/work like lisp inside of our programs".


no, not really. when people talk about DSLs in context of lisps, they usually still mean staying in the domain of s-expressions.

Yes, maybe that's the sort of DSL you're talking about, the other person mentioned "Clojure style discourages building DSLs" which I'm fairly sure to be about the other DSL and is also true, hence the whole "you're talking/reading past each other".

that doesn't make sense, why would they be talking about departure from traditional lisps if they weren't talking about macro-based DSLs?

> Clojure style discourages building DSLs and the like and prefers to remain close to Clojure types and constructs

This to me, seems to indicate they're talking about "DSLs not built with Clojure types and constructs", I'm just trying to have the most charitable reading of what people write and help you understand why it seems you're not actually disagreeing, just talking about different things.


> DSLs not built with Clojure types and constructs

and in context of lisps that still most likely means macro-based DSLs using traditional lisp constructs ¯\_(ツ)_/¯


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: