Static typing and Dynamic typing are two ways in which type systems are classified based on how they perform the type checking in programming languages.
Type Checking
Type checking is the process of verifying and enforcing the rules of types. For example, checking the types of both operands of a division operation to ensure that both the operands are numbers and the divisor is not zero.
Type checking can occur at compile time or at run time. Hence, we classify type systems as
- Statically typed (Type checking happens at compile time)
- Dynamically typed (when type checking happens at run time)
Static Typing
Static type checking occurs at compile time. It gives us early feedback on the type errors, allowing us to rectify them quickly. In static type checking, we need to specify the type of every variable that we use. We can do this explicitly (explicit typing) or let the type system infer it from usage (implicit typing). Since the type information is available at compile time, the compiler can generate optimized code. It also eliminates the need to run type checking at run-time, making the executable run faster.
Another advantage of statically typed language is that compiler can generate the optimized code that runs faster and uses less memory.
Some of the examples of static type checking type systems are C, C++, Java, C#, Scala, Haskell, Rust, Kotlin, Go, and TypeScript.
Dynamic Typing
Dynamic type checking happens at run time. Types are checked just before they are used. This makes the code flexible because you can assign different types of values to variables.
But dynamic type checking makes the code slower. We detect type errors only when we run the code. This is troublesome as we cannot test all possible scenarios. You may have to write lots of unit tests to eliminate most of the type errors.
Dynamic type checking results in less optimized code and runtime type error which is likely to occur since it forces runtime checks every time the program executes.
Examples of dynamically typed languages are JavaScript, Ruby, Python, Perl, PHP, Lisp, Clojure R, Bash
Dynamic Vs Static
Static
- You need to declare the data types of your variables. The declaration can be implicit or explicit
- We cannot change the type of the variable once declared
- Code requires us to compile.
- Type checking at the Compile time
- Most errors are caught during the compile phase. If there are errors, the code will not compile.
- Language is less flexible than dynamic. We cannot change the type of data
- Code is more verbose but easy to read because we know the types.
- The compiler can optimize the code. Hence better performance than the dynamic typing
Dynamic
- No need to declare the type of the variable.
- We can change the type of the variable at any time
- There is no compile stage. They are generally interpreted at the run time.
- Type checking at the run time
- You will get the errors at the run time.
- Language is more flexible than static typing. We can change the type of data dynamically.
- Code is less verbose but difficult to read because we cannot make out the type of variable.
- The code cannot be optimized. Hence lower performance than statically typed code
Note that none is superior to the other. It is just a matter of your preference. It is possible very good or bad code using both of them.