“So the question is, do we want to make monkeys happy, or do we want to produce correct programs?”
https://bartoszmilewski.com/2014/11/24/types-and-functions/
In programming we pass the results on one function to another. The program will not work if the target function is not able to correctly interpret the data produced by the source function. The two ends must fit for the composition to work. The stronger the type system of the language, the better this match can be described and mechanically verified.
The only serious argument I hear against strong static type checking is that it might eliminate some programs that are semantically correct. In practice, this happens extremely rarely and, in any case, every language provides some kind of a backdoor to bypass the type system when that’s really necessary.
- Even Haskell has unsafeCoerce. But such devices should be used judiciously. **Franz Kafka’s character, Gregor Samsa, breaks the type system when he metamorphoses into a giant bug, and we all know how it ends. **
Another argument I hear a lot is that dealing with types imposes too much burden on the programmer. I could sympathize with this sentiment after having to write a few declarations of iterators in C++ myself, except that there is a technology called type inference that lets the compiler deduce most of the types from the context in which they are used. In C++, you can now declare a variable auto and let the compiler figure out its type.
https://github.com/hmemcpy/milewski-ctfp-pdf
When I first learned OCaml (knowing only Python), I swore a lot at the type checker for refusing to compile code that I knew would work at run-time (e.g., a variable having multiple types, but on strictly disjoint execution paths). It seemed insane to me that people would want to subject themselves to this kind of bondage and discipline. And yet, many years later now, I have learned and internalized how type systems work, I have learned not to try and simply replicate Python patterns in OCaml, and as a result I use OCaml to write code quickly and without any headaches; and not only is the type checker no longer an obstacle, it’s now a valuable assistant.
I believe that we are seeing the same kind of phenomenon in Rust: we are trying to replicate C or C++ code directly in Rust, and we get frustrated when our efforts are foiled by the borrow checker. It’s going to take some time and some efforts before we learn and internalize how borrowing works in Rust and how to change the way we write programs so that it is no longer an obstacle. The Rust team looks very receptive to comments about taking away some pain points (e.g., non-lexical lifetimes), but we also need to accept that, for a little while, we are going to feel like we did when we were new programmers and were trying to make sense of these new constraints.
https://news.ycombinator.com/item?id=13470881
Statically-Typed Languages
We call a language “statically-typed” if it follows type checking during compilation. So, every detail about the variables and all the data types must be known before we do the compiling process.
In this type of language, once a variable is assigned a type, it can’t be assigned to some other variable of a different type. If we try to do so, the compiler will raise some errors, and we need to fix them. Hence, for a declared variable, the data type is fixed.
Some examples of statically-typed languages are Java, C, C++, C#, Swift, Scala, Kotlin, Fortran, Pascal, Rust, Go, COBOL, etc.
In most of the statically-typed languages, the programmer must specify what the data type of each variable is, just like we do in Java, C, and C++.
But for some other languages like Hascall, Scala, and Kotlin, the type system have the in-built capability (which is called type inference) to deduce the type of a variable from the code.
Dynamically-typed Languages
We call a language “dynamically typed” if type checking takes place while the program runs (run-time). In this type of language, there is no need to specify the data type of each variable while writing code.
It means that you can write pretty quickly since you do not have to specify types every time. Some languages do allow you to provide type information but do not require it.
Most modern programming languages are dynamically typed. Some examples of dynamically-typed languages are Python, Javascript, Ruby, Perl, PHP, R, Dart, Lua, Objective-C, etc.
A dynamically-typed language has the capability to identify the type of each variable during run-time. In these languages, variables are bound to objects at run-time using assignment statements.