Static/Dynamic vs Strong/Weak
What is the difference between Static开发者_运维技巧/Dynamic and Strong/Weak typing?
Static/Dynamic Typing is about when type information is acquired (Either at compile time or at runtime)
Strong/Weak Typing is about how strictly types are distinguished (e.g. whether the language tries to do an implicit conversion from strings to numbers).
See the wiki-page for more detailed information.
You have discovered a soft spot in the terminology that amateurs use to talk about programming languages. Don't use the terms "strong" and "weak" typing, because they don't have a universally agreed on technical meaning. By contrast, static typing means that programs are checked before being executed, and a program might be rejected before it starts. Dynamic typing means that the types of values are checked during execution, and a poorly typed operation might cause the program to halt or otherwise signal an error at run time. A primary reason for static typing is to rule out programs that might have such "dynamic type errors".
Strong typing generally means that there are no loopholes in the type system, whereas weak typing means the type system can be subverted (invalidating any guarantees). The terms are often used incorrectly to mean static and dynamic typing. To see the difference, think of C: the language is type-checked at compile time (static typing), but there are plenty of loopholes; you can pretty much cast a value of any type to another type of the same size---in particular, you can cast pointer types freely. Pascal was a language that was intended to be strongly typed but famously had an unforeseen loophole: a variant record with no tag.
Implementations of strongly typed languages often acquire loopholes over time, usually so that part of the run-time system can be implemented in the high-level language. For example, Objective Caml has a function called Obj.magic
which has the run-time effect of simply returning its argument, but at compile time it converts a value of any type to one of any other type. My favorite example is Modula-3, whose designers called their type-casting construct LOOPHOLE
.
Having said that, you can't count on any two people using the words "strong" and "weak" in exactly the same way. So avoid them.
Simply put it this way: in a statically typed language the type is static, meaning once you set a variable to a type, you CANNOT change it. That is because typing is associated with the variable rather than the value it refers to.
For example in Java:
String str = "Hello"; //statically typed as string
str = 5; //would throw an error since java is statically typed
Whereas in a dynamically typed language the type is dynamic, meaning after you set a variable to a type, you CAN change it. That is because typing is associated with the value rather than the variable.
For example in Python:
str = "Hello" # it is a string
str = 5 # now it is an integer; perfectly OK
On the other hand, the strong/weak typing in a language is related to implicit type conversions (partly taken from @Dario's answer):
For example in Python:
str = 5 + "hello"
# would throw an error since it does not want to cast one type to the other implicitly.
whereas in PHP:
$str = 5 + "hello"; // equals 5 because "hello" is implicitly casted to 0
// PHP is weakly typed, thus is a very forgiving language.
Static typing allows for checking type correctness at compile time. Statically typed languages are usually compiled, and dynamically typed languages are interpreted. Therefore, dynamicly typed languages can check typing at run time.
Weak typing means that the type of an object can change depending on context. For example in a weakly typed language the string "123" may be treated as the number 123 if you add another number to it. Examples of languages with weak typing are bash, awk and PHP.
Another kind of weakly typed language is C, where the data at a memory address can be treated as a different type by casting.
In a strongly typed language the type of an object does not change - an int is always an int and trying to use it as a string will result in an error. Both Java and Python are strongly typed.
The difference between dynamic and static typing is when the type rules are enforced. In a statically typed language the type of every variable and parameter must be declared in the source and is enforced at compile time. In a dynamically typed language the types are only checked when they are used at runtime. So Java is statically typed and Python is dynamically typed.
However the boundaries can be a little blurry at times. For example although Java is statically typed, every time you use reflection or a cast (e.g. when using containers of Objects) they you are deferring the type check to runtime.
Similarly most strongly typed languages will still automatically convert between integers and floats (and in some languages abitrary precision BigInts).
Today researching about this subject I came across this great article http://blogs.perl.org/users/ovid/2010/08/what-to-know-before-debating-type-systems.html It cleared up a lot of things for me and I thought It may add to some of the great answers above.
Strong and Weak Typing:
Probably the most common way type systems are classified is "strong" or "weak." This is unfortunate, since these words have nearly no meaning at all. It is, to a limited extent, possible to compare two languages with very similar type systems, and designate one as having the stronger of those two systems. Beyond that, the words mean nothing at all.
Static and Dynamic Types
This is very nearly the only common classification of type systems that has real meaning. As a matter of fact, it's significance is frequently under-estimated [...] Dynamic and static type systems are two completely different things, whose goals happen to partially overlap.
A static type system is a mechanism by which a compiler examines source code and assigns labels (called "types") to pieces of the syntax, and then uses them to infer something about the program's behavior. A dynamic type system is a mechanism by which a compiler generates code to keep track of the sort of data (coincidentally, also called its "type") used by the program. The use of the same word "type" in each of these two systems is, of course, not really entirely coincidental; yet it is best understood as having a sort of weak historical significance. Great confusion results from trying to find a world view in which "type" really means the same thing in both systems. It doesn't.
Explicit/Implicit Types:
When these terms are used, they refer to the extent to which a compiler will reason about the static types of parts of a program. All programming languages have some form of reasoning about types. Some have more than others. ML and Haskell have implicit types, in that no (or very few, depending on the language and extensions in use) type declarations are needed. Java and Ada have very explicit types, and one is constantly declaring the types of things. All of the above have (relatively, compared to C and C++, for example) strong static type systems.
From Scott's Programming Language Pragmatics, 3rd edition page 291, we have
Type checking is the process of ensuring that a program obeys the language’s type compatibility rules. A violation of the rules is known as a type clash. A language is said to be strongly typed if it prohibits, in a way that the language implementation can enforce, the application of any operation to any object that is not intended to support that operation. A language is said to be statically typed if it is strongly typed and type checking can be performed at compile time. In the strictest sense of the term, few languages are statically typed. In practice, the termis often applied to languages in which most type checking can be performed at compile time, and the rest can be performed at run time.
A few examples: Ada is strongly typed, and for the most part statically typed (certain type constraints must be checked at run time). A Pascal implementation can also do most of its type checking at compile time, though the language is not quite strongly typed: untagged variant records (to be discussed in Section 7.3.4) are its only loophole. C89 is significantly more strongly typed than its predecessor dialects, but still significantly less strongly typed than Pascal. Its loopholes include unions, subroutineswith variable numbers of parameters, and the interoperability of pointers and arrays (to be discussed in Section 7.7.1). Implementations of C rarely check anything at run time.
Dynamic (run-time) type checking is a form of late binding, and tends to be found in languages that delay other issues until run time as well. Lisp and Smalltalk are dynamically (though strongly) typed. Most scripting languages are also dynamically typed; some (e.g., Python and Ruby) are strongly typed. Languages with dynamic scoping are generally dynamically typed (or not typed at all): if the compiler can’t identify the object to which a name refers, it usually can’t determine the type of the object either.
So in simple terms, static/dynamic typing refers to the time when type checking occurs: compile time for static typing, and run time for dynamic languages. Likewise, strong/weak typing refers to how aggressive a language is in enforcing its type system.
I've tried to translate Scott's description into a nice diagram, which I've posted below.
Statically v/s dynamically typed languages
- Statically typed languages are those in which type checking is done at the compile time, so this also means that in statically typed languages each variable has a type and it doesn’t change over the course. Now, in contrast, dynamically typed languages are those in which type checking is done at runtime, and there is no type checking at compile time, so this also means that in dynamically typed languages there may or may not be a type associated with a variables, and if a type is associated then it could be a generic type like “var” in JS which hold good for both a string and number.
- “Implementations of dynamically type-checked languages generally associate each runtime object with a type tag (i.e., a reference to a type) containing its type information. This runtime type information (RTTI) can also be used to implement dynamic dispatch, late binding, down casting, reflection, and similar features.”
- Even if language is statically typed, still it could have some dynamically typed feature, which basically means that some sort of type checking at runtime as well. This is useful in casting of types.
- “A number of useful and common programming language features cannot be checked statically, such as down casting. Thus, many languages will have both static and dynamic type checking; the static type checker verifies what it can, and dynamic checks verify the rest.”
- “Some languages allow writing code that is not type-safe. For example, in C, programmers can freely cast a value between any two types that have the same size.”
- Advantage of “statically” typed languages are that:
- Since most of the type checking is done at compile time so interpreter or runtime can run at full speed, without worrying about the types.
- It leads to lesser number of runtime exception or errors related to type, because most of the type checking is done at compile time.
- Advantage of “dynamically” typed languages are that:
- They could help in extremely fast prototyping, since developer need not to understand the type system so dev can loosely create variables and run it, and this leads to very fast prototyping.
- List of statically and dynamically typed languages:
- Statically:
- Java
- C (C is a statically typed language but lesser “strongly” typed as compared to Java because it allows more implicit conversions)
- C++
- C#
- Dynamically:
- PERL
- PHP
- Python
- JavaScript
- Ruby
- Statically:
- Type checking is an important security feature. Suppose, there is no type checking, and a method accepts an object of type “BankAccount” which has a method called as “creditAccount(BankAccountDetails)”, now at runtime if there is no type checking then I can pass an object of my own class which has same method “creditAccount(BankAccountDetails)” and it will get executed, considering we are talking about object oriented language because OOP supports “polymorphism” and here what we are discussing is nothing but “polymorphism”. So, basically an object oriented language (which basically means it supports “polymorphism”) which doesn’t have strong type checking can lead to security issues.
Strongly v/s weakly typed languages
- Strongly typed languages are those in which implicit conversions are not allowed if there is loss of precision. For example, in Java, you can cast an “int to long” because there is no loss of precision but you cannot “implicitly” cast a “long to int” because there would be loss of precision. In contrast, in weakly typed languages, implicit conversions are allowed even if there is loss of precision.
- I think dynamically typed language can also be a strongly typed language if “at runtime” it doesn’t allow implicit conversions in which there is loss of precision.
Good further readings
- Type_system
- Strong_and_weak_typing
- Category:Statically_typed_programming_languages
- Category:Dynamically_typed_programming_languages
I think the other colleagues made a good job esp. explaining the difference between static and dynamic typing. But as far as strong and weak typing is concerned, it should be said that there are different understandings/views.
Here two examples:
Some say that Haskell is strongly typed, because you are not allowed to make any type conversions.
Others (e.g. Dario's view) say a language that allows to implicitly convert from string to number on purpose is weakly typed, but even others call this just duck typing.
Both statements highlight not the opposite extremes of a type system, but completely different aspects. So I join Mr. Ramsey's view not to use the terms "strong" and "weak" to distinguish between type systems.
In Programming, Data Type is a Classification which tells what type of value a variable will hold and what are the mathematical, relational and logical operations can be done on those values without getting error.
In each programming language, to minimize the chance of getting error, type checking is done either before or during program execution. Depending on the Timing of Type Checking, programming languages are 2 types : Statically Typed and Dynamically Typed languages.
Also depending on whether Implicit Type Conversion happens or not, programming languages are 2 types : Strongly Typed and Weakly Typed languages.
Statically Typed :
Type checking is done at compile time
In source code, at the time of variable declaration, data type of that variable must be explicitly specified. Because if data type is specified in source code then at compile time that source code will be converted to machine code and type checking can happen
Here data type is associated with variable like,
int count
. And this association is static or fixedIf we try to change data type of an already declared variable (
int count
) by assigning a value of other data type (int count = "Hello"
) into it, then we will get errorIf we try to change data type by redeclaring an already declared variable (
int count
) using other data type (boolean count
) then also we will get error
int count; /* count is int type, association between data type
and variable is static or fixed */
count = 10; // no error
count = 'Hello'; // error
boolean count; // error
As type checking and type error detection is done at compile time that's why during runtime no further type checking is needed. Thus program becomes more optimized, results in faster execution
If we want more rigid code then choosing this type of language is better option
Example : Java, C, C++, Go, Swift etc.
Dynamically Typed :
Type checking is done at runtime
In source code, at the time of variable declaration, no need to explicitly specify data type of that variable. Because during type checking at runtime, the language system determines variable type from data type of the assigned value to that variable
Here data type is associated with the value assigned to the variable like,
var foo = 10
, 10 is a Number so now foo is of Number data type. But this association is dynamic or flexiblewe can easily change data type of an already declared variable (
var foo = 10
), by assigning a value of other data type (foo = "Hi"
) into it, no errorwe can easily change data type of an already declared variable (
var foo = 10
), by redeclaring it using value of other data type (var foo = true
), no error
var foo; // without assigned value, variable holds undefined data type
var foo = 10; // foo is Number type now, association between data
// type and value is dynamic / flexible
foo = 'Hi'; // foo is String type now, no error
var foo = true; // foo is Boolean type now, no error
As type checking and type error detection is done at runtime, that's why program becomes less optimized, results in slower execution. Although execution of these type of languages can be faster if they implement JIT Compiler
If we want to write and execute code easily then this type of language is better option, but here we can get runtime error
Example : Python, JavaScript, PHP, Ruby etc.
Strongly Typed :
Data type related rules and restrictions are Strictly maintained
Conversion from one data type to another data type must be done explicitly, no implicit type conversion
# in python, "5" cannot automatically get converted to 5
pybar = "5"
print(10 + pybar) # error, no `+` operation between `int` and `str`
type checking may be done at compile time or runtime. It means strongly typed languages can be either statically typed or dynamically typed
Example : Python, Java, Ruby, C# etc.
Weakly Typed :
Data type related rules and restrictions are Loosely maintained
Conversion from one data type to another data type can occur implicitly
If we perform some operation between values of two mismatched data types then this type of language may not throw error. Instead weakly typed languages will apply their own rules for implicit type conversion and will return some result
jsbar = "5";
alert(10 + jsbar); /* "105", no error as javascript implicitly coerces Number 10
to String "10", so that it can be concatenated with other operand jsbar i.e. "5" */
type checking may be done at compile time or runtime. It means weakly typed languages can be either statically typed or dynamically typed
Example : JavaScript, C, C++, PHP etc.
Statically typed languages generally require you to declare the types of variables, which is then checked at compile time to reduce errors. The word "static" in "statically typed" refers to "static code analysis", which is the process of examining the code prior to executing it. Although it is possible for a statically typed language to infer the type of the variable from the right hand side of an expression or actual parameters, in practice most statically typed languages require variable types to be explicitly declared.
Dynamically typed languages generally do not require variable declarations to have types, and they infer variable types based on the type calculated as a result of evaluating the right hand side of every assignment statement or the actual parameters to a function call. Since the variable can be given multiple assignments over its lifetime, its type can change over time and this is why it is called "dynamically typed". Also, the runtime environment needs to keep track of the current type for each variable, so the type is bound to the value rather than with the variable declaration. This can be considered a runtime type information (RTTI) system.
Elements of statically and dynamically typed languages can be combined. For example, C# supports both statically and dynamically typed variables, and object oriented languages generally support down-casting the type hierarchy. Statically typed languages usually provide various ways to bypass type checking, for example by using casting, reflection and dynamic invocation.
Strong vs. Weak Typing refers to a continuum of how much the language tries to prevent bugs due to using a variable as if it were one type when it is in fact another type. For example both C and Java are statically typed languages, however Java uses much stronger type checking than does C. The following C code is happy to compile and run, and will put a random value into the variable b at runtime, most likely causing a bug:
char *a = "123";
int b = (int)a;
The equivalent Java code will produce a compile error, which is generally preferable:
String a = "123"
int b = (int)a;
From Addison Wesley, Object Oriented Analysis and Design with Applications, 3rd, page-66:
The concepts of strong and weak typing and static and dynamic typing are entirely different. Strong and weak typing refers to type consistency, whereas static and dynamic typing refers to the time when names are bound to types. Static typing (also known as static binding or early binding) means that the types of all variables and expressions are fixed at the time of compilation; dynamic typing (also known as late binding) means that the types of all variables and expressions are not known until runtime. A language may be both strongly and statically typed (Ada), strongly typed yet supportive of dynamic typing (C++, Java), or untyped yet supportive of dynamic typing (Smalltalk).
精彩评论