top | item 41633540

(no title)

snorremd | 1 year ago

This is the number one thing that made Clojure work for me despite being dynamically typed. Having confidence that values did not change under my feet after sending them into functions or across thread boundaries was so refreshing. In immutably valued languages even if you technically might be sending a reference to an immutable value type, you can at least practically think about it as pass by value instead.

I never really got into F# or Haskell (more than some tutorials) so can't really comment on the type safety part.

discuss

order

funcDropShadow|1 year ago

The value of static typing depends very much on the application domain. In a closed-world application domain where you can be reasonably sure that you know upfront all entities, their attributes, their valid ranges, etc, static typing is extremely valuable. That applies to domains like compilers, system software, embedded systems, and more.

In open-world domains, like business information systems, static typing is often an obstacle to fast adaptation.

Whereas immutability provides value in every domain, unless the performance requirement cannot be met.

bad_user|1 year ago

I've heard that argument before, but it never really clicked, and I'm a former fan of dynamic typing.

The application domain is not relevant because you rarely know the domain up-front. Even if the domain is fully known by business stakeholders, it's not known by the application developers, and those domains can be vast. Application development is a constant process of learning the domain and of extending the existing functionality.

This is why all the talk about how LLMs are going to make it possible to replace programmers with people using prompts in English doesn't make much sense. Because the act of programming is primarily one of learning and translating requirements that are initially confusing and context dependent into a precise language. Programming is less about making the computer dance, and more about learning and clarifying requirements.

Static typing helps with refactoring, A LOT!

So when your understanding of the domain changes, YOU WANT static typing because you want to safely change already existing code. You want static typing precisely because it gives you “fast adaptation”.

It's the same argument for why someone would pick Clojure over other dynamic languages. Clojure gives you some guarantees due to the pervasive use of immutability, such that it gives you a clearer view of the API's contract and how you can change it. But statically typed FP goes even further.

I've been involved in projects using dynamic typing (PHP, Perl, Ruby, Python) and with no exception, the code became a mess due to the constant evolution. This is one reason for why we preferred an architecture of microservices because it forces you to think of clear boundaries between services, and then you can just throw away or rebuild services from scratch. Large monoliths are much more feasible in statically typed languages, due to the ability for refactoring. And no, while unit testing is always required, IMO, it isn't the same thing.

iLemming|1 year ago

Apologies for being pedantic here, but Clojure is too - strongly typed, dynamically typed language. This means types are inherent to the values, not the variables that hold them, providing both safety and flexibility - even though variables don't have fixed types, every value in Clojure has a type.

In contrast, Javascript is weakly typed. Yet, Clojurescript, which compiles to JS, retains Clojure's strong typing principles even in the Javascript (weakly typed) runtime. That (to certain degree) provides benefits that even Typescript cannot.

Typescript's type checking is limited to the program's boundaries and often doesn't cover third-party libraries or runtime values. Typescript relies on static type analysis and type inference to catch type errors during development. Once the code is compiled to JS, all type information is erased, and the JS engine treats all values as dynamic and untyped.

Clojurescript uses type inference, runtime checks, immutable data, and dispatch mechanisms, optimized by its compiler, to achieve strong typing for the code running in the JS engine.