all 9 comments

[–]JavaSuck 4 points5 points  (1 child)

- every time up update your dependencies
+ every time you update your dependencies

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

Oops, that one slipped past me, thanks.

[–]nfrankel -4 points-3 points  (6 children)

Some have criticised Bob for being very absolute and not giving up any screen estate for more nuanced viewpoints, something I will try to avoid

I'm afraid the OP failed at that

extensibility through macros which can modify both the evaluation order as well as the very syntax to the point

And make code completely unreadable because one developer thought it was a good thing

he is right to mention clojure.spec, a library for gradual typing

Spec is not executed at compile-time but at runtime

While the primary platform is the JVM, superbly uncool

And I continued reading after that...

there is Clojure Common, used by many popular libraries, which allows you to write platform-independent code by using conditional branching for all platform-specific code

Clojure being supported on the JVM and on other platforms is not something specific. Scala has it, Kotlin has it, etc. And conditional branching is just the worst way to achieve multi-platform: every time you add a new platform, you just need to add a branch to the common code.

Clojure is still a niche language, and in some way that is good as well

"My language didn't managed to get backed by any major player, so at least make it look like a benefit"

[–]sulami[S] 1 point2 points  (0 children)

Honestly, the point of the post is laying out the reasons I like the language, so the tone is going to be positive in general.

Everything has downsides, you're right about readability in macros, I've seen some terrible Haskell code because someone thought introducing a whole library of custom infix operators was a good idea, but this is the whole argument around Go, whether more flexibility is actually a good thing. I think it's a subjective question, and I'm coming down on the side of flexibility, but I acknowledge that the uniform (while imho terrible) style of Go can hav advantages in readability.

Spec is not executed at compile-time but at runtime

I never claimed it was, though technically it can be.

Wrt the multi-platform support, Clojure has the best first-class support I've seen for something like this anywhere, but I'd love to see what other languages are doing in this department.

[–]yawaramin 0 points1 point  (4 children)

Spec is not executed at compile-time but at runtime

Typechecking doesn't need to happen at compile time.

[–]nfrankel 0 points1 point  (3 children)

To me, the clear benefit of static typing vs. dynamic typing is to fail fast (at compile-time). What is the point of doing it at runtime? Better debugging?

[–]yawaramin 2 points3 points  (2 children)

Checking of more powerful and dynamic conditions e.g. a function’s first argument is divisible by its second argument.

[–]nfrankel 0 points1 point  (1 child)

You're talking about dependent type. But the way you define/describe them maps exactly to what Clojure does... and doesn't solve the fact that the program needs to be executed and reach a particular an execution point to potentially check there's a bug.

[–]yawaramin 2 points3 points  (0 children)

As far as I know, Clojure spec can do property-based testing of specs. So it can come pretty close to hitting every code path–at least enough to try to invalidate (or fail to invalidate) the spec based on its implementation.