Worried about types + Clojure Elitism

I know what you mean. Some Clojure developers I used to look up to totally jumped ship because of types. When people whose opinion you respect disparage your favorite language it can cause a mini existential crisis. Like “am I living in blissful ignorance?” and then a video like this comes out which is comforting to know you are not alone in your enjoyment of the language. Then people post negative responses to it because he dare say anything about type systems. Then you have positive responses to the video to which some people respond with things like “oh these people just blindly follow their dear leader” You hear words thrown around like “cargo cult” and “cult of personality”.

But then you remember how much fun you have programming in Clojure and you accept that if dynamic typing is wrong, then you don’t want to be right. You’re happy, your customers are happy, and if you ever find one those things not to be true then you’ll reevaluate your choice of a main language.

I, for one, am an unapologetic Clojure developer.

I love learning knew languages but I also love learning knew paradigms and different ways to solve problems. Clojure gives me that.

7 Likes

This struck me too. It prompted me to ask Rich Hickey about it:

https://twitter.com/billburcham/status/919261246397890560

It might be self-serving to believe that this is wisdom (since I am a Clojure booster). Intellectual honesty, however, forces me to acknowledge that I might be influenced by nostalgia. Nostalgia for previous Lisps. I’m also inclined to agree with Rich Hickey on this point, because I agree so violently with him on so many other points.

I watched Snively & Laucher’s Strange Loop talk linked later in the thread. Seems like they are guilty of elitism too, slamming Ruby programmers, claiming programming with neither static typechecking nor TDD constitutes malpractice. I didn’t hear any actual support for either of those assertions in the talk.

That being said, I work on a big-ish Java system in my day job. Just yesterday I had to do a refactoring converting some horrendous constructors with up to 20 (positional) parameters, to static (factory) methods. Some needed their parameters re-ordered.

In the old days before IntelliJ refactorings, I might have done this w/ Emacs macros and regexps. What now takes 30 seconds would have taken me a morning.

The point is well taken, that you simply shouldn’t have positional parameter lists longer than say 3. But I think so many people are used to big messy Java codebases, I think it’s hard for them to imagine life without this sort of refactoring.

And this is an example of a larger problem: that until you’ve implemented a real system the “Clojure Way”, it’s hard to really have a well-founded position on Clojure’s approach to types vs your favorite other approach.

It’s Paul Graham’s “Blub” problem all over again. If you haven’t done it, it’s really hard to envision it.

3 Likes

Hi folks, I write The REPL which has a weekly section titled “People are worried about types”. I’m not sure if that’s what’s being referred to in the title of this thread? Here’s last weeks letter as an example. I have an explanation I link to on the “?” going to Why are people worried about types?, which explains the title of the section.

I use it as a joke, and somewhere to put spec/type related Clojure things. I hadn’t considered it before but I can see how you could take it as being dismissive of types. That’s not my intention at all, I think types are neat and useful.

2 Likes

The thing is - there’s a multitude of people, projects, environments and combinations of thereof. In some circumstances dynamically typed languages work great. In others - not so much.

If you have a team which:

  • feels comfortable using advanced statically typed languages
  • knows their way about building powerful abstractions without getting bogged down in type/category theoretic ivory towers or language-imposed minutiae
  • knows their end result in terms of business value

let them use Haskell/Idris/Scalaz. I strongly believe the systems they deliver will contain a lower number of defects than similar systems produced in dynamically typed languages. I think it’s definitely worth the time to learn some Haskell, get comfortable with modelling through types and understand how the “statically-typed” people think even if you program and love programming in Clojure. It only adds to your toolkit, never takes away.

Personally, I’ve been doing Clojure for a few years. It really shines when you’re in a small team working on data pipeline-like tasks. Which are most of them in the enterprises if we’re being honest :slight_smile: I love many things about Clojure. I love doing UI with Hoplon, not having to think about all the crazy componentDidMount lifecycle hooks and Form 1/2/3 component types. I love using Mount to structure application state on the backend. I love building asynchronous pipelines with Manifold so much I’ve ported it to Clojurescript. I love being able to read the source code for any library while not having my head explode due to the layers of abstraction (OK, this doesn’t apply to core.async, but that’s why I use Manifold :)). I love using the same language to automate build and deployment processes with Boot. I love not having to worry if the next Clojure version upgrade will break my code. I also love the fact that many people hate all of the above and use Lein, Re-frame, Core.Async and Component instead.

However, recently I had to do more numerically intensive code which naturally assumes algebraic structures (semigroups and the like). This sort of thing benefits immensely from type-driven development and a Haskell-like pseudocode is the first thing I reach for. Once the project grows, no matter how well you have divided and subdivided the pieces, the confidence that you get from the compiler telling you everything is fine is way higher than the test suite can provide, even if you’re doing extensive generative testing. “What if we’ve missed something?” - at least that’s how I feel. It’s true that there’s a huge hurdle of all the monad transformers, profunctors, yoneda lemmas and other scary “patterns” to learn in order to be fully productive. If that’s what it takes to make less defects when the cost/quality/scope allows - I think it can be worth the pain.

Anyway, I think that Clojure is the best thing there is on the JVM, for now. Hopefully Eta-lang will catch up and become a production-grade competitor as I’ve lost my hopes for Scala ever becoming pleasant to use.

5 Likes

I think there’s a lot of benefit to being a polyglot. When I first discovered Frege, it rekindled a desire to re-learn Haskell again (I’ve lost count of the number of times I’ve “learned Haskell” over the last two and a half decades!), and the first thing I did was write a Leiningen plugin to compile and run Frege code so I could experiment with mixed language Clojure/Frege code.

I’m currently trying to learn Kotlin (“learn a new language every year”) and, again, the first thing I did was write a Boot task to compile and run Kotlin code so I could experiment with mixed language Clojure/Kotlin code (and partly so I can easily compile my Kotlin examples and fire up a Clojure REPL and try them out – boot kotlinc repl :slight_smile: )

Over the last decade or so I’ve learned Groovy, Scala, and Clojure and taken them to production in mixed language environments. I’ve learned several other languages that have been just for fun projects.

Despite all the languages I’ve learned over the years – and the large subset of those languages that I’ve used in production – I still gravitate to dynamically typed languages but I have good friends who’ve always gravitated to statically typed languages. I know I’m not missing out – my friends and I just think differently about problem spaces. That’s why programmers have so many different tools.

(and I’m a mathematician by education and did category theory etc at university – so it’s not like I haven’t gone deep on it at some point past)

3 Likes

I disagree. I’ve been making stuff for Clojure beginners for nearly 5 years now. I’ll be the first to admit that my projects aren’t very widely used – the “market” for novice Clojure tools is incredibly tiny. That never bothered me (i make things for my own edification), but i don’t think it has to do with a lack of outreach.

Think back to when you were a beginner. What made you choose your first language? Chances are, you didn’t really choose it at all. For me, my first was C++, because i took a class in high school. In my free time, i started learning PHP, because the LAMP stack was so ubiquitous i thought it was the web.

If a young person today wants to make games, they’ll probably learn C# (unity) or GML (gamemaker). Beginners aren’t equipped to compare languages. They will come across some framework or tool that decides their language for them. Outreach is great but to get numbers you really need a killer app.

That may happen for Clojure at some point but it hasn’t happened yet. For now it’s the kind of thing you learn to gain a new skill (FP) which means mostly intermediate/advanced devs. I don’t think that spells doom – a lang can be healthy that way. Just keep making cool stuff and who knows, it may end up being our killer app, and i’ll be there reaping the benefits! :sunglasses:

4 Likes

I agree with @sekao that Clojure is unlikely to be anyone’s first language (except, perhaps, folks who come into Clojure via ClojureBridge, which is very specifically trying to reach beginners?) and so it should be expected that the vast majority of conference attendees are programmers with some level of experience who have now “discovered” Clojure. The community is certainly still growing so it’s not like the “cranky old programmer” market has become saturated yet :slight_smile:

If the question was instead “How many of you have been using Clojure less than a year?” I think you’d see quite a lot of hands go up. I’m pretty sure the vast majority of attendees are not yet using Clojure in production – so that’s a lot of people who are enthusiastic enough about a language that is not their day job to attend a conference! That’s a pretty healthy sign.

2 Likes

Clojure is not my day job, but part of the draw for me personally has been the excellent tooling around the developer experience, particularly with handling changes and reloads.

I’d rank Clojure (and Clojurescript) among the best, with tooling delivered by clojure.tools/repl, Component/Mount, and Figwheel. I for one do not think I would have come around to enjoying the language as much without these tools(!)

I sink a lot of time into what makes a good development experience on this side, and I watch developers with less experience fiddling with a lot of manual reloading because that’s what they’re used to. I feel it takes a little bit of exploration and introspection in one’s own workflow to develop the drive to improve it, which might be why something like Clojure isn’t picked over too often at the start.

I was showing some coworkers the kind of reloading developer experience that Figwheel offered this week, and it’s really not until they can compare it side by side in a non trivial application that the “why they should care” is apparent.

1 Like

@danielcompton yes, the title is inspired by The REPL. Whenever the flames of the eternal static vs dynamic debate flare up again I’ve come to think to myself “oh, people are worried about types again”.

It’s not meant to be dismissive of types themselves here any more than it is in The REPL, I take it more as a reminder to keep a bit of lightness in the discourse. We have had this debate since the dawn of time. It can be really interesting, and occasionally an actual new insight pops up, but there’s no need to get too worked up about this stuff.

I think them saying “Not relying on type safety is unethical” is kind of a jackass thing to say, because it’s an opinion. It’s not a pure fact.

I saw something on Reddit (I’d have to dig a bit to find it) that projects that use languages like Scala, Kotlin, Clojure, Elixir, Rust, Nim, and Crystal (not 100% sure it included those last two) have less buggy code. If you noticed there are 3 (or 2) dynamically typed languages on there. Yes, a majority are statically typed, but if a dynamic type system was truly “unethical” then people wouldn’t be writing such decent code with them.

When people gripe about dynamic type systems, I honestly think it’s really JavaScript’s fault because what a massive joke it can be sometimes, and how doing a lot of things in JavaScript can be a giant pain in the ass: so one thing people can blame that on is the dynamic type system it has, and not that it’s just not that great of a language a lot of the time.

EDIT: I found this Reddit post but it wasn’t the one I was looking for…I’ll keep digging.

Ah ha, it actually is! However, if you look at some of the comments on the post to r/programming, you’ll see that this is research is clearly flawed.

Hey everyone,

The elitism of Lispers is legendary and predates Clojure by a lot. The phenomenon has been given a name: Smug Lisp Weenie.

So this is just my opinion, but I think Clojure is having trouble “crossing the chasm”. There’s a book by that name that describes a theory of how products make it to the mainstream. The theory is called “Diffusion of innovations”. Clojure is a well-designed language and so has a lot of natural appeal. It easily got the first 16% of the “market” with innovators and early adopters. Rich Hickey’s talks, a lack of other options early in its life, and a lack of “practical” Lisps gave Clojure a huge, early migration of people ready to learn the warts and brave the lack of tooling.

The thing is, those people run out. If you want to get to that giant hump where most people are, you have to really appeal to the more conservative decision-makers. The early majority are looking for practical evidence that this is a good decision for them. They’re not concerned with features, and they won’t ever learn the language just to find out all the wonderful things we love about the language. They may already be interested in Clojure, but they’re waiting for a critical mass of their peers to jump in, too. It’s a chicken and egg problem. I believe this is where the excuse of fear of not being able to hire comes from. You can read more here.

The biggest issue is that Clojure programmers are all early adopters. We can’t sell Clojure to the majority with the same ideas that attracted us. And the only way to figure out what will convince others is to hit the pavement and talk to people who are kind of interested in Clojure but have not adopted it for some reason. Empathize with them, figure out what they want, and then give it to them.

About types: seeing all of the flamewars online, I try to elevate the conversation and transcend the differences most people fight over. That doesn’t always help others or the discussion, but it often helps me. It’s therapeutic and helps me develop my views of things. Another way it helps is to avoid getting caught in the repetitive back-and-forth of the flame trench warfare. I guess I’m like a war journalist on the Maginot line.

As an example, I wrote a post comparing the perspectives of static and dynamic typists. When I diagrammed it, I realized that we have fundamentally opposing assumptions. Static typists believe that untyped programs are a subset of typed programs, probably because that’s how you would implement a dynamic solution in a static one. On the other hand, dynamic typists see typed programs as a subset of dynamic–they’re programs checked for type correctness.

The reason I like this is every time I see a discussion, it’s very clear where the arguments come from. It’s in the nature of this type of discussion–the ones that get nowhere but people are fighting very hard–is that people are talking past each other. It is so clear when someone is stuck in either Church or Curry thinking. When they’re stuck, I have very little desire to argue with them.

Rock on!
Eric

13 Likes

Hi Eric,

I read your article. That was interesting, although I don’t fully comprehend the implications.

When you write in Haskell:

f :: Int -> Int
f = id

g :: Bool -> Bool
g = id

then g and f are different functions, while in Clojure they would be the same, because extrinsic typing is sort of an “add on”, that you run separately as e.g. a linter, but could also do without?

Does this mean that Java/Scala/Kotlin are also intrinsically typed? What are good examples of other extrinsically typed languages?

He @borkdude,

Java is a really interesting case. The JVM’s semantics are very dynamic. There’s an object model with methods, etc, and the types can be hinted but it’s mostly dynamically dispatched methods. But there’s very little type system in the semantics of the JVM. However, the Java language is intrinsically typed. Type correctness is an important aspect of the semantics of the language. Kotlin and Scala definitely are intrinsically typed as well.

It’s a good question. The way I see it, extrinsically typed means the types can exist, but outside of the semantics of the language. For instance, they can just be in the programmer’s mind, or in a comment, or in a type system imposed externally.

So in that sense, I’d say that any dynamically typed language (or if you prefer, untyped language) is extrinsically typed. A Python programmer does think in types and has some notion of type safety and reasoning about types. So does a JavaScript programmer.

Eric

3 Likes

Here’s my experiences. I don’t interact much with programming communities anymore, so if you don’t agree, maybe you know better than me.

Maybe it’s hard for new Clojure programmers to find mentors. If you work at a Clojure company, people would help you set up your computer and IDE. I hope ClojureBridge has an alumni mentor program. Saying something wrong in public is an easy way to feel unintelligent.

The tech industry’s elitist in general, and I had to swim against a current to use tools like Clojure. Other programmers, schools and companies have been hostile to my interests in things like Clojure and Lisp Machines. Even newer programmers are incentivized to be glib and argumentative.

When programmers ask why I like Clojure, I’m suddenly expected to play a salesperson and haggle. (For most other topics, they try to charitably interpret my words instead of firing back with the first half-baked retort that comes to mind. But not this topic.)

Maybe Clojure-interested programmers get filtered out by the wider tech industry?

FWIW, I use Clojure at a “hip” entertainment corporation and for activism. Yep, I work on a small self-managed team. If I were part of a conventional programming team, either I wouldn’t have much autonomy – precondition of adulthood – or be one of the few adults.

3 Likes

This is a super interesting take Eric, thanks for sharing. I never looked at it that way but you’re absolutely right, and it explains a lot.

2 Likes

Found this edifying post in the “People are worried about types” section of The REPL:

The author takes Rich Hickey up on the challenge: to think of every parameter to and the return value from every Clojure fn as being of type EDN.

He then proceeds to define the EDN type (in Haskell) and then writes a map fn that uses it:

clmap :: (EDN -> EDN) -> EDN -> EDN

Along the way he makes a case for why you might want to use Maybe and Nothing to make the EDN type more tractable.

I’ve always thought of the static typing argument from the standpoint of “what would Clojure look like with static typing”. Seeing it from the other side: “what would Clojure typing look like in Haskell” provided a valuable shift in perspective.

I definitely think more effort could go towards making Clojure accessible. The language itself is easy to learn and fun to use once you develop a good workflow. However, lack of tooling and documentation around it make it unreasonably difficult to get up and running on your own.

I think the problem is also compounded by the fact that a lot of the tooling is not well known outside the Lisp community. Using Clojure without the REPL and paredit/parinfer can feel downright painful. If nobody shows you that these tools exist, or how to use them effectively, then you can spend a lot of time getting frustrated.

8 Likes

That Front Row Ed article is very biased and makes its “point” by misrepresenting EDN and Clojure and skimming over (i.e., ignoring) a lot of details about semantics. It gets many function signatures completely wrong, omits arities, and is really rather self-serving instead of being suitably enlightening.

1 Like

Hi,
I just signed up so I could reply to this as it is an issue I feel strongly about and perhaps could shed some light. I haven’t read all the replies on this thread but many here seem to be experienced with Clojure and programming in general and there seems to be a variety of opinions on why new programmers aren’t taking up the language.

I consider myself a beginner Clojure programmer and somewhat of a beginner programmer in general too, though I have enough experience to kind of know what I’m talking about. As background: I completed a BSc in Computer Science at a university in New Zealand in my early 20s having not done in any programming prior to that and did not get a job in the tech field after that and have not been programming since but recently got back into it. So I don’t really have much practical programming experience only undergrad programming experience so in that regard I am a beginner.

I started learning Clojure programming some months back using Clojure for the Brave and True tutorials online (I think that was it) and I found that while it can be easy to get started with toy stuff doing these tutorials using tools like LightTable, online sites that let you type and run Clojure code on the site page and just using Leiningen and the REPL then at some point you want to graduate to more practical real-world programs and want a more ‘professional’ dev environment. This is where it gets really, really difficult for me as now you’re looking at something like IntelliJ IDE with Cursive or Emacs with the associated Clojure plugins or whatever you call them.

Learning how to use Emacs is like learning a new lang in itself and I tried what I thought was the easier option in IntelliJ - as soon as I try to build or run my program or whatever, instead of my program building or running some menu screen pops up with no helpful error message or anything. I suspect I have some Java build configuration setting or what not misconfigured. I can build and run Java programs and other langs just fine though.

After looking at various IntelliJ tutorials and searching for help on that, after a couple days, I just gave up, despite Clojure being my favourite programming language out of what I looked at so far. I still am planning on giving it another go and have already but each time I get stuck on getting a decent dev environment set up.

Learning a language full of parentheses, Lisp weirdness and a different way of thinking about things than OOP was not such a problem for me as a beginner. In fact it makes it more exciting and inspiring to learn because it’s fresh food for the brain. Getting stuck on build configuration issues or whatever it was while trying to get a bare minimum decent dev environment up and running is really not a fun, inspiring problem for a beginner. That’s the kind of problem that makes a beginner go “Ah! Screw it! This isn’t worth the trouble.” Especially when for just about every other language under the sun you can download, install and have a nice dev environment up and running in around 10 minutes. So given how long it’s taken me to get a dev setup going with Clojure which I still haven’t managed then I am thinking Clojure is worse than other languages in that area by many orders of magnitude.

So in conclusion, speaking as a Clojure beginner, I would say Clojure’s number one problem with attracting beginners is the dev environment setup. It’s simply monumentally painful for me. Any other reasons that may be mentioned here in this thread I would say are very secondary issues to this one here. Some batteries included IDE that can make useful real-world programs with fairly professional tooling but is still easy on beginners would go a long way towards fixing this situation I would think. And it would need to be promoted by the community as a clear choice for beginners.
I think Zach Oakes has something new out. So I will check that out and see if it helps :slight_smile:

7 Likes

I think you’re right about this. We need an integrated dev setup solution. That means REPL, testing, and dependencies, all set up for you, without requiring any particular editor.

1 Like