Hacker News new | past | comments | ask | show | jobs | submit login

It’s great, and I learned a ton from Rich Hickey, despite not fully grokking Clojure or FP in general. I briefly worked at a small Clojure shop with an extremely talented crew. People were excited about FP and writing real business logic with it. My stack was different there.

The problem started when the honeymoon phase ended, and the codebase grew as the business gained traction. Dynamic typing became a burden, and once the key people moved on, they struggled to hire developers who wanted to write Clojure.

Also, JVM juju shooed many away. After I left, a coworker told me they had started rewriting part of it in Go, and that was going alright. Now, their stack mostly consists of Python for LLM stuff and Go for the main backend. There’s still some Clojure running legacy systems that haven’t yet been migrated over.




>>Also, JVM juju shooed many away. After I left, a coworker told me they had started rewriting part of it in Go, and that was going alright.

Golang can make even Python look terse.

There's practically 0 abstractions to meaningfully tame large code bases. You just end up writing same/similar code patterns over and over again.

If you are willing to go down that path I'd recommend using Java entirely. You get the full enterprise thing.


I’ve been having a lot of fun messing with clojure, but the dynamic typing really grates on me.

At your clojure job, we’re y’all using spec? I haven’t looked into it yet, and I’m wondering how much it mitigates the annoyances of dynamic types


I don't think spec with solve issues you are having about dynamic types.

Spec is about asserting structure at ___domain boundaries; once you're inside a context, it will not do anything.

i.e. If you're connecting stuff together and you want to make sure the state is correct as you pass between contexts -> great!

If you're writing stuff and internally you miss having a strong type system... uh... I don't think it's really going to help you.


why not just program to protocols?

For complex data structures I typically just hide details behind a protocol and deal with the set of interface functions.

You can then freely mess with the internals and not worry about details


I don't know enough about protocols. Will the compiler stop you if you misuse them?


The compiler will not know if a protocol is not passed to a function expecting a protocol. Whereas a static typing language will not compile.

Similarly nothing prevents invoking missing functions of a protocol, you will only know during runtime.


Well you're typically not thinking of a compilation step with Clojure.. so I found the original question a bit not-applicable

The goal isn't to introduce .. a compilation step? but to have the program blow up in the spot where there is an type mismatch. If you don't use a protocol you may not blow up, you may generate a nil, and you may blow up much further down the line (or not at all)

In the rare instances where dynamic types cause problems, they're virtually always something convoluted like that. The protocol design pattern describes the interface and protects you from hard to debug situations


In my experience (mainly when trying to understand the implementation of core.logic), the problem with protocols is that the code inspection tools choke on them.


It was in alpha stage and changing rapidly when they were considering it. But it’s similar to Python’s type hints and isn’t enforced by the compiler. However, that’s better than nothing.


In what way is clojure.spec similar to python's type hints? O_o


The tooling around static types is worlds better than any tooling around spec - it's not like working with a static typing system, unfortunately.


Coming from a love of strong typing (scala) clojure dynamic typing was a real adjustment.

One thing I grew to really love is how small my changes were when I’m just adjusting a decidedly brownfield chain of functions that operate on data. With go in place at work, I added a couple fields to a core data type in my business and I ended up with thousands of lines of changes to pipe them everywhere. Doing the corresponding change in clojure would be <100 lines. I do miss the feeling I get with Haskell that if it type checks, I’m (maybe) good, but like Rich says “List[A] -> List[A] tells me almost nothing about the reverse function.”


The Haskell type `[x] -> [x]` (the equivalent of `List[A] -> List[A]`) tells you an incredible amount about the function. It tells you that the function must calculate a subset of a permutation of the input list. The function cannot be anything else (or else it will crash or hang). In a language with stricter requirements you can omit even the crash/hang caveat.

Don't underestimate the amount of information even simple type signatures contain!


Not necessarily a permutation; e.g.

    f :: [a] -> [a]
    f [] = []
    f (x:xs) = x: x: f xs


Yeah, Hickey was just wrong about this. For me, watching his talks goes like this:

Hickey: I value X, Y, Z

Me: Yeah man!

Hickey: We get great consequences A, B, C

Me: Ah yeah, I love programming like that. That's why I love Haskell!

Hickey: That's why Haskell is bad.

Me: err, what!?

> It tells you that the function must calculate a subset of a permutation of the input list

As tromp pointed out, "permutation" is technically incorrect. You mean something like "a list formed only from elements of the elements of the input list, and the particular arrangement is independent of the values of the input list"!

Not sure why you were downvoted though.


I think what he’s saying is the type signature alone isn’t enough, but in some languages like Haskell, people do imagine if the program type checks, it’s good. But that isn’t necessarily true, you need a ton of other context to actually have a proper functioning program, and the reverse function is an example of this.

I didn’t say Haskell was bad though. I love Haskell in a different way from clojure.


Rich’s point is the type signature actually tells you little about what the function does. You need the name, docs, tribal knowledge, your own understanding of the math… etc. to actually understand what it does. Type signature alone is a very incomplete understanding. But come on, do you think I learned how to write Haskell and don’t understand what a type signature’s value is? Give me a little credit.

Here is Rich’s work on the subject: https://youtu.be/YR5WdGrpoug?si=7C8EjQ7TVo2Ua8w7

I’m biased, but I think he’s got a point.




Consider applying for YC's Summer 2025 batch! Applications are open till May 13

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

Search: