Specifically, how does language manage data?
A variable is a symbolic name associated with a storage location that contains a value or a pointer(to a value). Made up by name, value, storage, lifetime, mutability,
A value is a piece of data with a type, that is either referred to by a variable or computed by a program expression. It has type, value, storage, lifetime and mutability.
A variable’s/values’s data type influences its size and encoding, what operations we can perform on it, and how it’s converted to other types.
It is possible to have a programming language without types, and in fact, most assembly languages are untyped. In typed languages, a variable might not always have a type associated to it, but a value always has associated type.
There are strong type and weak type, static type checking(type check prior to execution) and dynamic type checking(type check during runtime).
With static typing, a type checker checks that all operations are consistent with the types of the operands being operated on prior to the program’s execution. To support static typing, a language must have a fixed type bound to each variable at its time of definition. Once a variable’s type is assigned, it can’t be changed. Type can also be inferenced.
Static type checking is conservative — it can prevent technically correct programs from compiling.
With dynamic typing, the safety of operations on variables/values is checked as the program runs. If the code is attempting an illegal operation on a value, an exception is generated or the program crashes. The compiler/interpreter uses “type tags” to detect type violations.
Sometimes, dynamic type checking are needed in statically-typed languages as well. Specifically, when there’s a down-cast: from a derived class to a based class.
Compared to static type, dynamic type checking has more flexibility, easier in generics, simpler code and faster prototyping. But there’s also cons like slower runtime, less guarantees
Duck Typing is only doable in dynamic typing language. So one way to distinguish to check if a language is dynamic typed is to see if there’s any explicit type casting. If there is → not dynamic type.
There is a middle ground between static and dynamic typing, the Gradual Typing. With gradual typing, you can choose whether to specify a type for variables/parameters. If a variable is untyped, then type errors for that variable are detected at runtime. But if a type is specified, then some type errors can be detected at compile time.
Strongly-typed: A strongly-typed language ensures that we will NEVER have undefined behavior at run time due to type-related issues. In s strongly-typed language, there is no possibility of an unchecked runtime type error.