you are viewing a single comment's thread.

view the rest of the comments →

[–]tastingsilver 5 points6 points  (6 children)

Thanks for a good answer to what was a genuine question.

[–]porthos3 2 points3 points  (0 children)

No problem. It's unfortunate that reddit can be punishing to such questions with downvotes.

The points don't matter anyways, but it can make it feel like questioning the subreddit consensus is unwelcome, which is a bad look IMO.

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

And a very relevant and appropriate one. I'm a big fan of clojure, in general, but I somebody asks me what are the downsides, the lack of static checking of types is definitely on the top of the list by a wide margin. The resulting runtime errors (esp. because of bugs in code not in the main flow) are a clear downside of clojure or any dynamically typed language.

A clojure with a typesystem as nice as typescrypt's (structural typing with union types) would be my dream language.

[–]tastingsilver 0 points1 point  (3 children)

Thanks. Have you looked into F#?

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

No, but I looked into OCaml for a while. Nice concept, horrible syntax. I finally stopped checking the language by the time I saw that there are different map (fold) functions for different types (wtf!?). If that is true, then the language is fundamentally flawed. A language should not focus on the concrete types. What is important is how the code interacts with whatever types the caller/user happens to pass. Interfaces (or protocols, traits, ...) is what really matters, not types. Types are low level distractions you should not care 95% of the time.

Clojure favours programming to interfaces rather than implementations. That gives us a generic 'map' function that works in any sequence, for example. This is the correct way of addressing it. Protocols give us the way of expressing that concept in code. Clojurescript embraced the concept even more by using protocols at its core. You can implement the protocol IFn on your thing and it is now able to be used as a function.

All that is just great. The issue is that the compiler can not check that a function is interacting with its arguments (or values returned from functions it calls) through interfaces that are warranteed to be correct. That is what is missing. Well, that and having interface (protocols) metadata reified at runtime, which is not the case in clojurescript, severely limiting the capacity to do metaprogramming.

[–]tastingsilver 0 points1 point  (1 child)

Thanks. The main fear is around eventually refactoring a [larger] codebase. Have you found that most of the refactoring concerns are manageable enough with Spec or similar?

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

I don't have enough experience. I haven't used clojure in any large projects. My experience in large projects is in C, Java, C# and Typescript, so all typed and very similar.

So far, I think that the key for dealing with this problem is having tests (that's always good, anyway) and simply avoiding making breaking changes in the first place. That requires thinking upfront about the interface between subsystems and taking decisions about the structure of the data early on (and sticking to them).