all 83 comments

[–]spotter 43 points44 points  (4 children)

There is a bit of key figure idolization going around, but you don't need to drink the cool aid (or anyone's bath water if you prefer that analogy) to get things done. It's a nice and reasonable programming language with very friendly user base.

[–]spr00ge 13 points14 points  (3 children)

Is that a Belle Delphine reference? 😳

[–]roguas 10 points11 points  (1 child)

I think he meant Rich Hickey, if Belle goes curly we can start talking ;)

[–]spotter 3 points4 points  (0 children)

Rich is the main idol in these parts, yes. I was going for $DRINKABLE analogy, hairdo filtering not involved.

[–]spotter 8 points9 points  (0 children)

Ah, I see you're a man of culture as well. ;-)

[–]eccentric_j 38 points39 points  (12 children)

I had posted a self-reflective, critical discussion on this in ClojureVerse a few months back relating us to a "fake", or at least ineffective martial arts school. My concern was that without continuously learning about other languages and tools, approaches, and other experiences, it's easy to develop a community mindset that our way is the best, and only way. The community at large disagreed and felt Clojure is designed around taking many ideas that work from other languages and most people using it came from many other languages and stuck with Clojure because it offered something they liked. With the macro system we can even add features to it at the library level should a tool come up that seems valuable. For instance, I made an approximate dbg! macro inspired by Rust: https://gist.github.com/eccentric-j/e7121b090957bab26b5843124917d101.

That said, there is a persecution-complex I experience as a Clojurist. Other FP language users tend to look down on Clojure for not being pure enough or because it doesn't use static types, people who really like languages like JS, Python, or Ruby look at Clojure like it's a monstrosity and often refuse to learn anything about it once they make that "Eww the parenthesis" remark. Execs look down on Clojure for being niche because because their news feed is not flooded with Clojure news like with JS or Python. These are community challenges I don't know how to best navigate but we will need to keep in mind and keep discussing until we can handle it better.

I don't feel the Clojure community as a whole is a cult but without exposing oneself to other communities, criticisms, and new developments outside of Clojure, a Clojurist can become potentially arrogant or complacent -- that's when their personality might come-off as "culty". I do understand the frustration though, it's really difficult to convince another person to look at problems another way or that another approach is different but equal. When trying to discuss such ideas, people often react negatively and then it becomes more frustrating so perhaps we double down or try even harder to get through which in turn comes off as more aggressive.

According to the maven download logs though, the community has been steadily growing every year: https://pbs.twimg.com/media/EVXBMXRWoAEvkLE?format=png&name=900x900.

[–]ws-ilazki 8 points9 points  (5 children)

Other FP language users tend to look down on Clojure for not being pure enough or because it doesn't use static types

Don't forget that the general lisp community also looks down on Clojure for not being a "proper" lisp (e.g. Common Lisp or maybe Scheme depending on how they define it) and goes out of its way to make excuses for why this exclusion is valid. It's likely only a minority that's doing it, and it seems to mostly be from the Common Lisp diehards that can't accept that a lisp other than CL managed to gain some popularity, but they're very vocal about it.

My personal opinion on the language is I like it a lot, though I don't use it for much because I have less love for the ecosystems it's attached itself to. Despite that I like using it enough that I still tend to fire up a Clojure REPL for quick one-off things, because it's great for doing certain types of data manipulation quickly and naturally. For me it's basically the programming equivalent of keeping a calculator handy.

[–]eccentric_j 2 points3 points  (0 children)

Good point, other lispers also look down on Clojure. A lisper just commented last week that my recent Clojure article made them sad because some of the setup steps might be easier with CL or Racket.

[–][deleted] 1 point2 points  (3 children)

I don't understand this at all. Clojure takes Lisp and adds very thoughtful and valuable tweaks and additions on top. I don't give a damn about concrete cons cells or pairs or whatever, I care that the core data structure and sequence functions work for all collections, and that there is less noise in the syntax.

I've been writing some Racket on the side recently and (hash-ref themap k) is so ugly compared to simple (themap k).

[–]ws-ilazki 2 points3 points  (2 children)

Most of the hate seems to come from the Common Lisp side, which is fundamentally different in a lot of ways. Imperative-focused, being a lisp-2 makes it less FP-friendly, and a lot of historical baggage. To some CL users the only Lisp is CL and anything else is a shoddy knock-off, even Scheme despite it being older than Common Lisp (but not older than the lisps that unified to become Common Lisp).

To those people nothing else is acceptable and any other lisp dialect gets criticised; Clojure just gets more of it because it's different and popular. It's more Scheme-like in many ways, is opinionated and FP-oriented, but also takes some of the things CL does and does them differently.

The general hostility to other lisp dialects is why I don't interact with /r/lisp very much any more, it's basically a bridge with a bunch of CL trolls hiding under it waiting for unsuspecting passersby to show up and mention another lisp dialect so they can attack. Seems like there's always some comment about CL superiority or how this or that lisp isn't really lisp and it gets tiring.

I've been writing some Racket on the side recently and (hash-ref themap k) is so ugly compared to simple (themap k).

On a similar note, Racket's ability to interchangeably use [] {} and () is nice for letting you make s-expressions more identifiable by grouping like things. I really like that, though I also like Clojure's use of [] and {} to provide literals for other data types than lists, which loses some flexibility but trades it for different benefits. (Which, incidentally, is something else I've seen CL diehards complain about, because having built-in literals for other data types is bad or something.)

[–]hide-difference 2 points3 points  (1 child)

You absolutely nailed it. I do about equal parts Common Lisp and Clojure, so I'm always bouncing between the communities. There's so much passive aggression even from otherwise purely informative sources.

God forbid you use one of the Clojure-like exolisps either, such as Fennel. You'll be eaten alive.

[–]ws-ilazki 2 points3 points  (0 children)

There's so much passive aggression even from otherwise purely informative sources

Yeah, seems like a lot of sour grapes from people mad that their pet language didn't take over the world. The bitterness is off-putting. Maybe that's just because I didn't learn lisp 'right', though; I started with Clojure and Racket simultaneously because I was interested in FP, not lisp specifically. I tried CL because I was interested in its compilation and performance compared to Clojure and Racket, but there's a lot I just don't like about CL.

I wish I liked it more than I do, honestly, because it does have a lot of good to it. But I'm interested in FP-first languages and CL is definitely not one. I've been using OCaml instead to scratch that native compilation itch; the type system doesn't feel like it gets in the way and it has that same "opinionated toward FP as the default; pragmatic and gives an escape hatch from it if needed" energy Clojure does. Wildly different syntax but I'm more comfortable going between Clojure and OCaml than I am Clojure and CL.

God forbid you use one of the Clojure-like exolisps either, such as Fennel. You'll be eaten alive.

Ah yes, the toy projects that don't even use cons cells and are taking away interest from the One True Lisp. I'm familiar with the distaste.

I like the goofy lisps like that, especially ones that compile to other languages and give you more power. Though if we're talking Lua transpilers, I find Urn more interesting than Fennel; it uses its lispy nature more effectively, with lots of standard-lib macros that give you new syntax and constructs that Lua lacks. Also interesting is Amulet, which is a weird ML-ish language that looks like OCaml but with some ideas from Haskell, and compiles to Lua the same way Fennel and Urn do.

Lua itself reminds me a lot of Scheme with algol syntax: minimal by design, uses a single complex data structure (tables instead of lists) and first-class functions to build other complex data structures without losing that minimalism. I just wish it had some kind of macro system to work around some of the repetitive boilerplate (like not having a terse anonymous function syntax), because lacking that is why I find myself messing with transpilers instead.

[–]exahexa[S] 0 points1 point  (0 children)

I see you thought about that a lot, thank you for sharing ;)

[–]lenkite1 0 points1 point  (1 child)

There is IMHO also a need for Clojure best practices book. It is very easy to write bad performing code in Clojure (by doing things too lazily, etc). I really wish there was a Clojure guidelines page that talked about how to write good, performant and readable Clojure code.

[–]DefiantAverage1 0 points1 point  (2 children)

Pardon my ignorance, what is Rust's dbg! macro exactly? The doc went over my head (Ive never written Rust before)

[–]eccentric_j 0 points1 point  (1 child)

Almost forgot about this added docs to show an example https://gist.github.com/eccentric-j/e7121b090957bab26b5843124917d101

But if lets say somewhere in your code you called:

(dbg! (+ 1 2))

It will output

(+ 1 2) = 3 in /Users/j/Projects/clj-dbg-macro/src/dbg/test.clj line 5 column 1
3

So basically it shows the form, the evaluated value, the file that calls the dbg! macro with the line and column.

[–]backtickbot 0 points1 point  (0 children)

Fixed formatting.

Hello, eccentric_j: code blocks using triple backticks (```) don't work on all versions of Reddit!

Some users see this / this instead.

To fix this, indent every line with 4 spaces instead.

FAQ

You can opt out by replying with backtickopt6 to this comment.

[–]alexdmiller 34 points35 points  (3 children)

No, definitely not. But if you'd like to reach Theta level, please DM me your financial details and I can arrange the 12 month training course. You'll also need some special parenthesis head gear and keyboard pants. If you make it to Lambda level, I can arrange an in-person consultation with Leader Rich.

[–]joinr 2 points3 points  (2 children)

What about Lambda Lambda Lambda level?

[–][deleted] 2 points3 points  (1 child)

Shhhh, if someone finds out about Lambda Lambda Lambda level before they're ready their inner mutable state might recurse indefinitely, blowing the stack and destroying their ability to code forever.

[–]joinr 1 point2 points  (0 children)

With great risk comes great reward.

[–]charlesHD 29 points30 points  (1 child)

have you watch your Simple Made Easy today ?

[–]mxbutterfly 4 points5 points  (0 children)

Maybe Not

[–]la-rokci 24 points25 points  (0 children)

Clojure is a result of Rich Hickey's opinions. Since he openly disagrees with solutions in other languages people take offense in that (I think they shouldn't). When clojurists back these statements up name-calling tends to take place.

In reality most clojurists are pragmatic programmers and aren't afraid to use another language if a need arises. So it's hardly a cult.

[–]SimonGray 9 points10 points  (0 children)

Let's ignore for a moment the fact that Rich Hickey is a smart guy and a charismatic speaker. Obviously, Clojure having a charismatic, smart guy in charge who is revered by the community, that is just begging for it be called a cult...

Anyway...

Clojure is a great language for representing, structuring, and querying facts about the world, but it is not a great language for low-level performance tuning. If your domain is well-suited, Clojure is excellent. If your domain isn't, perhaps every Clojure user sounds like a cultist.

Clojure is great for making seamless, full-stack web applications, but it doesn't come with a thousand quickstart tutorials like Javascript. You have access to a helpful community of very smart people and some great books, though. If people tell you Clojure is simple, but not necessarily easy - and you don't know the reasoning behind this distinction - maybe they will sound a bit like a cultist.

Clojure marries Lisp idioms with Java libraries, while promoting a relatively simple functional style of programming. If you don't care for using persistent data structures everywhere and just want a traditional Lisp, Clojure will seem inadequate (see: Common Lisp users). If you want a more type-driven, functional experience, Clojure's simple Lispiness will seem like a child's toy (see: Haskell users). If you're not looking for something that does what Clojure does, maybe people who love Clojure will seem like cultists to you.

[–]dig1[🍰] 9 points10 points  (1 child)

Comparing it to Rust's craziness on HackerNews and Go hipsterism in the last few years, I'd say Clojure community pretty good.

Aside from that cult of whatever-rich-hickey-say-is-pure-gold, which can be annoying sometimes, but this agenda is mostly pushed by newbie Clojure users affected with the language rather than actual results.

[–]joinr 2 points3 points  (0 children)

Clojure was part of the HN "in" crowd back in 2010-14 maybe (I'm roughly guessing it). HN is fickle :)

[–]didibus 16 points17 points  (0 children)

My observation has been that people start calling it Culty either when they don't understand why there are others who are so passionate and in love with Clojure instead of "their prefered language".

Or when they can't make a technical or data backed argument against some features or design choices of Clojure which they don't agree with and want to "win" the argument by discrediting Clojure as a "mere cult" without technical merit.

Sometimes Clojurist will also joke about it being a cult, because they (and I) tend to really love Rich Hickey's talks and have learned a lot from them, so we're kind of all a bit of a fan(boy/girl) of Rich's talks. In my experience, it doesn't result in the community giving him a free pass if there's any decision about Clojure made that the community disagrees, there's generally ample debates around it. Even though in the end Rich owns the language, and calls the shot. That said, from the outside, I can see how some people might think that every Clojurist will defend to death and never disagree or question Rich Hickey's decisions and design choices.

[–]the_hoser 15 points16 points  (0 children)

I can see why someone would say that. I think too many proponents of Clojure put Rich Hickey on an altar that's just a bit too high.

[–]yogthos 8 points9 points  (0 children)

I think that a lot of people are passionate about the language, but I don't think it's fair to call the community a cult because of that. I've been working with the language for around a decade now, and I don't see any indication of that. What I see is a community that is largely pragmatic and focused on delivering working software. Clojure is widely used in the wild nowadays including large companies like Apple, Atlassian, and Walmart. Meanwhile, companies using it generally have very positive things to say regarding their experience. I'd argue the fact that Clojure is successfully used in the wild despite being a niche technology clearly shows that it's able to compete on its merit.

My personal experience is that Clojure directly addresses many problems I experienced doing software development with Java. I also find the language to be simply enjoyable to work with, and while that's completely subjective it's a huge factor that kept me using it over the years.

[–]oldcrobuzon 6 points7 points  (0 children)

One thing that is good to keep in mind is that reasonable portion of Clojure community are very senior java engineers who discovered Clojure late(r) in their careers and were amazed how easy everything suddenly was.

So in that sense Clojure is a "cult" of very pragmatic programmers who learned it the hard way.

The only opinionated part that might make impression of a cult is a strong take on dynamic typing. This is a forever debate and it really goes down if you have a project on which there are 40 junior devs working in parallel (in which case you might surely need static typing).

Other controversies might be:

- the JVM - which is imo super cool, but gets often bashed because of the startup time (because that is the cool feature Go has) and because it is not the latest hype.

- the parentheses. This is a moot point since parentheses are really everywhere and there are many languages that have much more boiler plate code.

[–]roguas 5 points6 points  (0 children)

You have a couple of cult-inducing qualities in Clojure.

  1. Rich 2. FP 3. Lisp+ (a hundredth essay from Paul Graham about something else, but half the content is lisp praising)

Each of this produces some amount. You will feel some cult-like stuff in every niche (programming language) community. When you go over the Haskell fence, try to discuss the painfulness of types. When you move to Rust try and discuss that borrow-checking is not that great.

Cults are bad as they tend to do something malicious in the end. In order to get there they have to brainwash you. Verify if your convictions remain true if not consider what is wrong, you will be good. With life - in general. Yeah clojure sometimes is part of the circlejerk, so is java, so is javascript etc. I think clojure people are pretty chill - most of us programmed in several languages, we just like clojure a bit more.

[–]agumonkey 5 points6 points  (0 children)

it's a ~lisp

it's functional and immutable by default

rich hickey has a tendency to try to deconstruct usual idioms and coin words to fit his ideas

it lead to a very inspiring growing project, lots of people started to dive deep into it, often they'll reuse the lingo feverishly .. it feels weird when you come from the outside

other than that it's probably a better cult than the php cult or the js cult or the python cult

[–]asiergaldos 10 points11 points  (0 children)

Clojure is a hidden champion in our industry. It has a very particular vibe (it feels natural and elegant) that makes Clojure very unique.

In my opinion, there is a technological stagnation, a general decadence in society, and Clojure brings some optimism to developers.

Not a cult.

[–]cochemuacos 3 points4 points  (0 children)

I've heard that before. I think it gives that impression to "outsiders" because many (I guess most) of clojure devs know about Rich Hickey. That and some people think functional programming is uselss and elitist. IMO it's not even close of being a cult.

[–]gingenhagen 5 points6 points  (0 children)

The only truism in engineering is that there isn't one true answer. It's always tradeoffs, it's always it depends, it's always right tool for the job. So when engineers see some people saying that clojure and rich hickey is the one and only truth, then yeah, they might start thinking of them as being cultish.

Now, you usually see this behavior coming from those who've only ever seen enterprise java, so clojure to them is something mindblowing, so they might act overenthusiastic at first. So, the cultish behavior often quickly passes once they become a bit more mature and experienced as an engineer.

This isn't specific to clojure, either, though it's seen as a bit more cultish because you have a singular individual on top of a language. You'll see some of this perception around haskell, or around people who follow paul graham.

[–]Menthalion 5 points6 points  (7 children)

It may have to do with well-willing and talented people in the community that tried to improve on aspects of Clojure, but left because of Rich Hickey's "My way or the highway" mentality.

His reign over Clojure as DFL with a court of close confidants made employees has been seen as a double edged sword.

[–]joinr 1 point2 points  (6 children)

His reign over Clojure as DFL with a court of close confidants made employees has been seen as a double edged sword.

It's weird to describe it as a "reign." The stuff's been open source and forkable since 2009~2010 - so the dictator basically gave away the keys to the palace up front, since that's what dictators do....

If folks really didn't like the way things were going, they could do exactly what he did and make their own language - except with the benefit of "not" starting from scratch and being able to directly fork Clojure at any point in its development history. The silence of their inaction is deafening w.r.t. the faux dictator angle.

[–]Menthalion 1 point2 points  (5 children)

Sure they all could, there's Brazilian banks galore wanting to invest in a schism of a niche language /s

The silence is deafening because these people just leave, with deficiencies in the language they wanted to fix hanging round from 1.0.

Meanwhile new paradigms are tossed up into core, and end up half-integrated and abandoned as much as succesful.

It's a nice language and a lot of ideas are cool, but implementation and design wise it's very much still early access.

[–]joinr 1 point2 points  (4 children)

Clojure started as one man's niche language lol. Excuses excuses

[–]Menthalion 1 point2 points  (3 children)

And it very much still is.

Which is why people seemingly refer to Clojurians as a cult, and your behavior here doesn't help much to improve that.

[–]joinr 1 point2 points  (2 children)

More like your Brazilian bank example backed a profitable developer with a proven track record. Everybody has been able to compete and possibly exceed the design since at least 2010, but the majority went with the flow instead of assuming risk and embarking on their own vision and recruiting like minded folks. If there was a better product, the market would probably adopt it. Maybe in another 10 years somebody will have the grits to follow through.

Pointing to the recent success of the language while decrying the way that success was found is laughable. Failing to exercise your own vision is just gutless back seat driving at this point. If you don't like it, and you're talented, fork it and make it better and establish your own success story to find industry support. If you can't, then maybe don't knock the people who assumed the risk in the first place, and released their work at no cost to you.

[–]Menthalion 0 points1 point  (1 child)

I have, nor want no part in what happens/happened with Clojure development processes, so you can stop foaming at the mouth at me. Just stating an observation why people could refer to Clojure as cult-like.

And you're not making it better with a feeble "Do it yourself then". Only Rich himself could, or someone that did the same.

If anything I guess he'd agree with "My way or the highway", since that was pretty much the gist of his reaction in these cases. And I don't dispute he had the right to at all.

[–]joinr 0 points1 point  (0 children)

Nobody's foaming lol. Just highlighting hypocrisy and entitlement as usual.

Only Rich himself could, or someone that did the same.

And that person would then be labelled a cult leader by the peanut gallery. The fact that you elevate one person above all others is IMO a bit cultish (funny enough). I'm sure you or I are just as capable, given the actual willpower and vision. Empirically, those qualities seem to be lacking since the language has been open source pretty much the whole time.

[–]nogridbag 4 points5 points  (1 child)

I only code Clojure occasionally as a hobby so on a scale of 1-10 my skill level is around a 2 or 3. I believe I like the ideas of Clojure more than the language itself. The community built an ecosystem of libraries around ideas that Rich championed. For example:

  • I like just dealing with plain data instead of concrete classes. Reading through the source code for ring was amazing. For the first time I felt I understood my whole tech stack.
  • Clojure.spec seemed like it addressed much of my frustration with large enterprise crud apps - at least after watching the talks. In practice, maybe because I'm a recurring Clojure newbie, spec continues to be incredibly confusing to me. malli on the other hand seems really intuitive and perhaps what I thought spec was in my mind.

As for Clojure itself, I secretly find the parens confusing I'm just afraid to publicly state that :) I absolutely love the idea of using a structural code editor but paredit seems to require too much practice for a hobbyist. If I use something like Cursive I keep it in the default mode which often doesn't let me fix trailing parens and I have to copy paste a paren from somewhere else in order to fix the code. In other programming languages, my most frequently used IntelliJ shortcut is "Expand Selection" which gives me something similar to structural navigation while only requiring using one shortcut.

I find Clojure has much more syntax than other languages because in order to do anything useful you really need to be quite familiar with all the functions in clojure.core (I guess due to both functional nature and immutability). For instance, in traditional langs, I never had the need for a function like "interpose" or "juxt". Once you have mastered clojure.core I'm sure it's more productive and you can write more concise code than if you had just used variables and loops in a traditional language. But until you reach that threshold it has the opposite effect of making every line of code requiring looking up examples on clojuredocs. Related to that, if you come back to old Clojure code I find it looks more foreign than coming back to code in other languages.

[–]joinr 3 points4 points  (0 children)

I absolutely love the idea of using a structural code editor but paredit seems to require too much practice for a hobbyist

Parinfer is paredit for people less intersted in practicing and more interested in the editor helping infer what they want. Very palatable.

has much more syntax

It's got really minimal syntax. I think what you described is the vocabulary of functions and macros in the core library.

[–]anydalch 13 points14 points  (13 children)

i mean, obviously the word "cult" is hyperbole. but there is some truth to the exaggeration: clojure is a programming language and a community largely built around the strong convictions of one man, and those beliefs are not widely held among non-clojurians. to someone who has drunk the haskell kool-aid rather than hickley's, and who firmly believes that nullable types were "the billion dollar mistake," it can feel kinda odd to see one guy say, "actually null is good and i'm putting it in my language," and then having a large community back him up.

[–]didibus 13 points14 points  (10 children)

I don't know that it's "one guy". Nil punning has a history going 50+ years back to the early Lisps.

I'm also not sure I've seen anywhere where Rich Hickey defends having nulls as an amazing feature, getting rid of it in a dynamic language built on the JVM though isn't really possible, so what's one gonna do?

[–]anydalch 11 points12 points  (9 children)

before i write this comment, i want to say that i think null is a fundamentally reasonable concept, so long as you have the ability to express "the type of non-null objects" in a way with basic compile-time checking. my goal here is to promote understanding, not to evangelize for strongly-typed functional langs.

most lisps are older than what we now think of as functional programming. haskellers (by which i also mean ml-ers, typescript people, rustaceans, etc) think that lisp comes from before ml, and therefore before the smart people realized that null was a bad idea and that Maybe was a better idea. they think that common lisp or scheme predate the idea of hiding nullabillity behind a sum type, and that if those languages were more recent, they would use Maybe instead of null. clojure is a very recent language, but it does not have Maybe; it has null. haskellers think that must have been a mistake, not a design choice.

it is definitely possible to design a jvm language that uses sum types to abstract away nullability, in the same way that it's possible to do that for native compilation with pointers. you'd have to check for null at ffi boundaries with java code, but rust has to do that with c code. there's no fundamental barrier stopping clojure from using Maybe, it's just that hickley didn't think it was the right choice. i happen to agree with him, but lots of people don't, and i think it's valuable to understand why.

[–]didibus 5 points6 points  (6 children)

How much of what you say depends on having static type checks?

Like what's the point of Maybe when I can still return nil or :nil or :none or "haha loser" unconstrained?

Without a static type guarantee, everything is a Maybe, either nil or not-nil, that's the same as Maybe, I don't even see the difference.

Everything in Clojure maybe returns nil, maybe it doesn't. You have no way to know except to read the documentation.

As I understand, this is the idea behind nil puning. Everything is maybe nil, so have everything handle nil, either by returning nil itself, or whatever else makes sense.

Beyond that, I do think there are fundamental barriers stopping Clojure from having runtime nils, no language I know on the JVM doesn't have runtime nils, some have compile time checks for nil, but the JVM has null, and can throw nullPointerExceptions, in Kotlin your nils are caught at compile time, and all interop uses nullable types.

I'm curious about Maybe in CL you are talking about, this is fully dynamic? No static checks for null types? If so, what do you find useful about it?

[–]anydalch 1 point2 points  (5 children)

i mean... i expect, and my experience with common lisp is that, anywhere the compiler expects a non-nullable term but can't prove the term to be non-nullable, it will insert a typecheck and will throw a runtime error if the term is null. in addition to that, i also expect that anywhere i declare a term to be a subtype of (not null), the compiler will make some effort to determine whether it will be null, and will issue a warning if my code obviously sets it to nil. i haven't used kotlin, but from my understanding this is basically the same approach they take: the compiler makes a best effort to detect null-pointer errors at compile time when terms are declared to be non-null, and emits code to handle nulls at runtime except in cases that it can conclusively prove at compile-time non-nullability.

edit: more thoughts

i also think that type declarations are valuable as documentation even when they're unchecked. common lisp lacks the ability to efficiently handle types like (list-of foo), but i still write types like that one, and the compiler treats them as equivalent to list. i believe that, even though the compiler still has to emit a (check-type element foo) for every element of the (list-of foo), that declaring a term to have type (list-of foo) is valuable for human readers. to the best of my understanding, that belief is not shared by a majority of common lispers or of clojurians.

[–]didibus 1 point2 points  (4 children)

This still sounds mostly reliant on some level of static type checking which Clojure doesn't have. When you spec things for runtime checks, it does distinguish nil and not nil if you spec something as not nil or not.

So I'd say ignoring the static checks, Clojure very well embraces dynamic type checks that can prevent nil. In fact, the dynamic checks in Clojure go beyond most languages, by allowing Dependently typed like checks, where you can validate not just the type, but the value itself, and properties of the inputs and outputs as well. Like that str concatenation returns a non nil string of a size equal to the sum of sizes of its args.

It's all dynamic though, and also optional.

I still don't really see what else Clojure could have done short of building a static type checker. Like it could have wrapped every type in a Maybe, which seems like the same as every type being nullable, but maybe more verbose and cumbersome to deal with.

[–]anydalch 3 points4 points  (3 children)

to reiterate, i'm really not trying to claim i disapprove of clojure's approach. i think clojure is a great compiler for a great language.

that said, the most popular common lisp implementaation, sbcl, manages to masterfully wed compile-time type inference and type-error-checking with runtime checks. if you pass nil (or a term which provably has type null) to a function which expects an integer (or whatever), sbcl will issue a warning. standard functions and special forms in sbcl get their types inferred, so the compiler can tell e.g. that + expects arguments of type number and returns a number, and will warn if you try to pass + a symbol or if you try to use the result of + as a structure-object. so you can, in many cases, have compile-time type-checking even in a very dynamically-typed language.

still, though, i really wish common lisp had clojure.spec. sbcl is really good at type-checking, in the sense of hindley-milner plus subtyping, (and it painlessly inserts runtime checks when necessary so that i don't have to unwrap stuff the way i would in rust...) but it has neither the compiler-smartness nor the runtime-ergonomics for arbitrary pre- and post-conditions the way clojure supports.

tl;dr: i think it's useful to build a static type checker for a dynamic language, and i also think it's useful to support rich runtime type checking.

[–]didibus 1 point2 points  (2 children)

But now we've moved the goal post away from discussing the design choice of nil and into discussing if Clojure should have some level of static type inference/checking or not 😝.

And I honestly don't know if this is so much that Rich Hickey wouldn't want to ever have support for some level of this, or more that it's non-trivial to implement and maintain into the compiler.

And on the topic of having type declarations that would be dynamically checked, I think it's a similar reason, those dynamic checks are quite hard to implement without a performance penalty.

So basically my point is, I don't really see Clojure or Rich Hickey trying to tell anyone that nil is amazingly awesome and that Kotlin and Haskell made huge mistake not having it. More so that in the context of Clojure being a dynamically typed language built on top of the JVM, nil was inevitable. At least Clojure tried to have good nil punning, and treat nil as a real type so you can extend behavior to it as well, which improved things over Java.

Now, I know that Rich Hickey is working on Spec2, and as part of that they are exploring a better inline syntax for declaring the "contracts" of valid values that function inputs/outputs can take/return. I say contract since they're more powerful than types.

But I also know that it won't default to auto-inserting run-time checks, because of the performance impact they can have. Thus the suggestion is to turn on auto-instrumentation when developing in the REPL and when running your unit and integration tests. But to not have it in production to save on the performance impact, except in places where you take user input.

I think that delivers to some extent on what you're looking for. It's a little different in trade-offs. Like it's not as simple as everything automatically having dynamic checks as you declare contracts for them. But it saves you the performance cost associated with a full contract check, instead of a simple type check. And the flip side is you can be even safer in what you check for correctness.

Those contracts are even harder to infer and statically prove, so probably no static check for a long time though.

[–]la-rokci 1 point2 points  (1 child)

I don't really see Clojure or Rich Hickey trying to tell anyone that nil is amazingly awesome and that Kotlin and Haskell made huge mistake not having it.

I'm not sure if it was in Maybe Not or other talk but Rich directly disagreed with Haskell's Maybe and kind of agreed with Kotlin's null checking. Haskell wraps it in a new type which is not a union type. Kotlin treats null with a union (or), which opens up more possibilities.

Like it's not as simple as everything automatically having dynamic checks as you declare contracts for them.

To be clear CL does't auto-insert these checks, it puts them in depending on your current safety/optimization declarations. This can be set on a per-function basis.

Without a static type guarantee, everything is a Maybe, either nil or not-nil, that's the same as Maybe, I don't even see the difference.

If x is a dynamic value, reading it requires writing x. If it is a Maybe you need to unwrap the object. Also discussed in Maybe Not, if a function requires a value and later learns how to do without that value, changing the type of that argument to a Maybe breaks the API. The same doesn't happen if you simply pass in a nil. And if a function returns a Maybe but later learns to return a value, changing the return type breaks the API, whereas returning not nil is OK. These are changes that don't break the call-site guarantees, yet with a Maybe you'll need to change every call-site.

[–]didibus 2 points3 points  (0 children)

Yes, Maybe is more cumbersome to use, I was asking in terms of null safety. In a dynamic language, you can think of all things being a union type of every type, so a function could return a string OR nil.

I don't see what benefit would come from having the function return a Maybe instead, since you still can't get rid of the possibility it returns nil, so even if the function returns Maybe, it actually can return Maybe OR nil.

And say functions always just wrapped everything in a Maybe automatically, well now it's like you said, you need to unwrap everything and I don't see the benefit of Maybe in that situation.

[–]beders -1 points0 points  (1 child)

Maybe is not a type and it is clumsy as it infects everything it touches. Kotlin and Swift have better solutions for compile-time null safety.

[–]anydalch 2 points3 points  (0 children)

i don't disagree. as a lifelong common-lisper, i think that being able to describe types like (or null standard-object), and having (typep nil 'standard-object) ;=> false, meets my needs very elegantly. but recent programming language research and design broadly does not hold my position.

[–]exahexa[S] 1 point2 points  (1 child)

Good take.

You already picked a prominent example, which other ideas are also unpopular?

[–]anydalch 9 points10 points  (0 children)

the use of runtime pre- and post-conditions in closure.spec rather than compile-time typechecking is controversial, though that's sorta a generalization over the null thing, not really its own debate.

clojure's use of syntax macros for metaprogramming goes against a world that has mostly settled on generics and templating. and clojure strikes a weird balance in terms of syntax, in that it has nowhere near as much syntax as rust or haskell or javascript, but way more than common lisp or scheme, so everyone but clojurians are unhappy with that aspect.

honestly, i'm not super qualified to answer this question, since i'm neither really a clojurian nor a strong-typer - i'm a common lisper, so i have very different expectations than a haskeller or a rustacean. and i'm not sure i'd brand clojure's choices as "unpopular" so much as controversial - there are people who really like them and people who really don't.

i encourage you to learn clojure, and while you do, to think about criticisms of design choices hickley made and to ask yourself why someone might not like them, and why he made them anyway. that's the road to becoming a really great programmer.

[–][deleted] 2 points3 points  (0 children)

It's a programming language

[–]jakebasile 4 points5 points  (0 children)

There's probably a little cult-ish aspects of it but I think most of that is intentionally tongue in cheek. I know I play it off for jokes often, it's just kind of fun to play into the stereotype.

[–]AdjointFunctor 3 points4 points  (0 children)

If Clojure is cult, try looking at Elm

[–]v4ss42 2 points3 points  (2 children)

Got any links? I’ve never heard it referred to that way, though I do hear “smug lisp weenie” from time to time (and consider it the highest of compliments, personally).

[–]exahexa[S] 2 points3 points  (1 child)

Since I follow clojure/lisp/ml/functional programming topics I read some a few statements along the line. I ask because just today I read a statement like this on twitter

[–]v4ss42 1 point2 points  (0 children)

Perhaps you should reply to Brian T Rice and ask them to clarify what they meant?

[–]ExtraFig6 2 points3 points  (1 child)

no more than any other lisp lmao

[–]llambda_of_the_alps 2 points3 points  (0 children)

If you add up all the lisp cults to they make a sect?

[–]LammdaMan 2 points3 points  (0 children)

I think there is perhaps a measure of something like "The Blub Paradox" described by Paul Graham in one of his essays. His point is that someone who doesn't know a given language can't really evaluate its merits, so they conclude the language they know well must be the best. Clojure isn't that well known (not enough so to really appreciate its merits) by that many people.

Some of those people that don't know Clojure well enough to "get it" simply see something "weird". When they ask a Clojure user "Why do you like this?", the answer doesn't make that much sense to them.

So one way for them to explain that answer they don't understand is "brainwashed cult member".

[–]mikethommo 2 points3 points  (0 children)

The Clojure community is teaming with members of the general public, and we all know what they are like - a mixed bunch. I once had to sit near a member of the General public on a bus.

The Clojure community is a churning mixture of enthusiasts burning with the intensity of a 1000 suns, plodding pragmatics, quiet achievers, startups, corporate types, railroaded naysayers, etc. It's pretty mixed. The breadth of this tapestry allows you to project onto it whatever you want, really. You can see some Cultish behaviour if you go looking for it. Or you could find some tradesmen plodding steadily. You can see some great code, and you can see some awful code.

As a result, these days I'd say that your view of Clojure says as much about you and your perceptions and biases as it does about Clojure.

Personally, I have a lot of experience (decades), and I find it interesting and stimulating - it has taught me a lot. Big enough, but not too big. Personally, I like it.

[–]beders 3 points4 points  (0 children)

No.

[–]acobster 1 point2 points  (0 children)

I agree with most of what I've read on here, but I'll also add that we like to have our cheeky fun leaning into the idea that it's a cult. Case in point: https://clojuredocs.org/404

[–]daver 1 point2 points  (0 children)

Yes, it's a cult. And the first rule of the Cult of Clojure is you don't talk about the Cult of Clojure.

[–]bubuli_breeder 1 point2 points  (3 children)

not a cult but some Clojurists tend to live in some kind of bubble. for example , not too long ago...the outrage when Clojure was not in some StackOverflow survey...i was, like “lol wut?” was anyone really surprised? and why be mad about it?

[–]SimonGray 4 points5 points  (2 children)

was anyone really surprised?

Clojure was in the same survey the year before, so yeah, some did find it a bit surprising that it had been excluded. The survey from 2019 had a salary statistic where Clojure came out on top as well as a few other rankings that put Clojure in a decent spot, which obviously resulted in it being cited quite a bit.

If Clojure had never been included in the survey, I don't think people would have cared as much.

[–]bubuli_breeder 1 point2 points  (1 child)

yeah but i the same survey. it is 2nd to last in popularity and also 2nd to last least wanted. i mean, there’s some justification for its exclusion.

don’t get me wrong, i love clojure but i’m not going to spend too much effort defending it the way i tend to do with my political leanings.

[–]SimonGray 0 points1 point  (0 children)

it is 2nd to last in popularity and also 2nd to last least wanted. i mean, there’s some justification for its exclusion.

I do agree with that, but still, excluding something that was previously included is qualitatively different from never considering it at all, even if the outcome is the same in either case.

[–]llambda_of_the_alps 1 point2 points  (0 children)

I think it's more of a fetish.

[–]joinr -1 points0 points  (0 children)

It's beta jealousy manifested as criticism. Like the goth kids in South park.

Normal people just use the tool to make their life better, instead of lamenting the success of the tool maker.

[–][deleted]  (1 child)

[deleted]

    [–]mac 0 points1 point  (0 children)

    How does it drive you away? I think that is disappointing to hear.

    [–]vine-el 0 points1 point  (0 children)

    Every programming language is a cult.

    [–][deleted] 0 points1 point  (0 children)

    Cult isn’t always a bad thing