To elaborate on why JavaScript is not gradually typed, let's look in the other direction at C#, which is statically typed with implicit typing.
According to MSDN, C# introduced a var
keyword with version 3.0 released in 2007. It is only allowed on "variables that are declared at method scope", what I would call local variables. The var
keyword falls short of being a dynamic type, because it allows the compiler to figure out what type the declaration should, but then treats all references to that variable as the given type exactly as if you had declared it statically yourself.
Here are some examples of how it can and cannot be used.
class MyClass {
// Standard member variable
public string MyName = "Patrick";
// Illegal declaration - var cannot be used here even though the type may be inferred
// from the literal definition; compiler throws an error
private var LuckyNumber = 7;
// Have to do it like this:
private int LuckyNumber = 7;
private MyClass(int luckyNumber) {
LuckyNumber = luckyNumber;
}
public MyClass MyClassFactory(int newLucky) {
// Legal - myInstance is in the method scope
var myInstance = new MyClass(newLucky);
// Not legal - myInstance is not a dynamic type just because we declared it with var
myInstance = new MyOtherClass();
// We can return myInstance because its type matches the method signature
return myInstance;
}
}
In other words, C# does not provide a way to declare an variable that can hold an arbitrary type. The closest you can get is with polymorphism, where assignments are restricted to the inheritance tree.
Note that in sharp contrast, JavaScript would allow the illegal line in MyClassFactory
. The following is perfectly legal in JS:
var foo = "foo";
foo = 1;
foo = 2.0;
foo = new Date();
foo = [];
foo = {};
foo = function() {};
Every line changes the type of foo
. Furthermore, there is no way to declare foo
as a type that may not be changed.
Note that there are ways to shoehorn static typing into JavaScript, but they are actually wrapper layers around the actual JS code, which ends up every bit as dynamically typed as if you had written it by hand. There are way more ways than I would have imagined, as it turns out: here is a comprehensive-seeming list of languages (or more properly syntaxes or parsers) that can churn out JavaScript. Of these, CoffeeScript is the most common in my experience.
Finally, a language must provide both dynamic and static declarations in order to be considered dynamically typed. In other words, the following must be possible with some syntax:
// Statically typed declaration
Integer myNumber = 3;
// May be legal if the language provides for auto-conversion or dynamic-casting; may
// throw an error. It depends on the language
myNumber = 7.5;
// Static type declaration of an object class
MyParentType instance = new MyParentType();
// legal if MyChildType inherits/extends MyParentType - illegal otherwise
instance = new MyChildType();
// Illegal always - MUST throw an error
instance = new IncompatibleType();
// Dynamic typed declaration
dynamic otherInstance = new MyParentType();
// Legal for variables declared dynamic - MUST NOT throw an error
otherInstance = new IncompatibleType();
Note that, as demonstrated, neither C# or JS support both types of variable declarations for different reasons.