240 likes | 249 Views
Language Typing. Heath Carroll Bill Hanczaryk Rich Porter. What We Originally Wanted to Do. A Theory of Type Polymorphism in Programming Robin Milner (1977) Milner credited with introducing the idea of type polymorphism
E N D
Language Typing Heath Carroll Bill Hanczaryk Rich Porter
What We Originally Wanted to Do • A Theory of Type Polymorphism in Programming • Robin Milner (1977) • Milner credited with introducing the idea of type polymorphism • The programming language he developed, ML, was the first language to use polymorphic type inference and type-safe exception handling.
What We Will Do Instead • Introduce the design of polymorphic type inference • Present three programming languages that utilize different degrees of typing • ML – Bill Hanczaryk • C# – Heath Carroll • Python – Rich Porter
Terms We Will Use • Type Polymorphism – A feature of a program that allows different data types to be handled essentially the same way. • Polymorphic Function – A function that can evaluate values of different data types. • Polymorphic Data – A data type with only a generalized type. • Static Typing - type checking at compile-time. • Dynamic Typing – type checking at run-time. • Strong Typing - In order to mix types, you must use an explicit conversion. • Weak Typing - mixing types without an explicit conversion is okay.
ML • ML Typing • static – type checking at compile time • strong –type mixing must be done explicitly • inferred -> Next Slide • Even though type inferred, basic types still exist • int, real, string, bool, and char. • ML created (by Milner) to specifically utilize the Hindley-Milner type inference algorithm to automatically infer the types of expressions
Type Inference • Type Inference - The ability of a programming language to automatically detect the data type of a variable. • A compiler is often able to infer the type of a variable without explicit type annotations having been given. • Why is it useful? • A programmer does not have to explicitly define type annotations while still maintaining about the same level of type safety. • Types often clutter programs and slow down programmer efficiency.
ML Type Inference • Example -fun f(x) = 2+x; >val it = fn : int -> int • How does it work? • + has two types: int*int -> int, real*real -> real • 2 : int has only one type • This implies + : int*int -> int • From context, need x: int • Therefore f(x:int) = 2+x has type int -> int
ML Type Checking and Type Inference • Standard type checking • int f(int x) { return x+1; }; • int g(int y) { return f(y+1)*2;}; • Type inference • f(x) { return x+1; }; • g(y) { return f(y+1)*2;}; • Look at code without type information and figure out what types could have been declared.
C# • According to the Wikipedia C# is : • static – compile time type checking • dynamic – runtime type checking • strong – any type mixing must be done explicitly • safe – type mismatches throw errors, find a way to work (ie adding an int to a string in javascript) • nominative - two variables are type-compatible if and only if their declarations name the same type Basically Java using C syntax, boxing, and garbage collection, but without global variables.
Static AND Dynamic ? o_0 ? • How on earth can a language be both at the same time? Don’t they contradict each other? • Sort of. It’s just redundant to type check at both compile time and runtime. • But C# isn’t fully dynamic, it’s dynamic only when you’d want it to be, literally. C# has a new static type: Namely the dynamic type.
Example of dynamic type • dynamic d1 = new Foo();dynamic d2 = new Bar();string s; • d1.M(s, d2, 3, null); • Q: What does the compiler do when it comes across this function M()?
Example continued…Compiling • A: Nothing! It allows the program to figure it out at runtime. (ok, so maybe it does something…) • The compiler sorts the function call to M(), so that at runtime M() can be invoked with the arguments passed in. • Which it does as follows:
Example continued…Runtime 1. Reflection is used to obtain the actual runtime types of the two objects, d1 and d2, that did not have a static type (or rather had the static type dynamic). The result is Foo for d1 and Bar for d2. Reflection - provides objects (of type Type) that encapsulate assemblies, modules and types. You can use reflection to dynamically create an instance of a type, bind the type to an existing object, or get the type from an existing object and invoke its methods or access its fields and properties. If you are using attributes in your code, Reflection enables you to access them.
Example continued…Runtime • 2. Method lookup and overload resolution is performed on the type Foo with the call M(string,Bar,3,null) using ordinary C# semantics. • Overload resolution – The Dynamic Runtime Library is responsible for figuring out which method to actually use if more than one is found. • Betterness rules apply.
Last step of dynamic typing • 3. If the method is found it is invoked; otherwise a runtime exception is thrown
Betterness rules • M(string s, int i = 1);M(object o);M(int i, string s = “Hello”);M(int i); Given the functions above are all applicable, which one or ones are most suitable and which one gets the call?
Betterness continued… • Given these overloads, we can see the working of the rules above. M(string,int) is not applicable because 5 doesn’t convert to string. M(int,string) is applicable because its second parameter is optional, and so, obviously are M(object) and M(int). • M(int,string) and M(int) are both better than M(object) because the conversion from 5 to int is better than the conversion from 5 to object. • Finally M(int) is better than M(int,string) because no optional arguments are omitted.
PYTHON • Strong • No implicit type conversions • Duck • “When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck” • Dynamic • No initialization/declaration • Type “determined” at run time
PYTHON - STRONG • Cannot add int to string • ‘a’ + 3 → error • ‘a’ + ‘3’ → ‘a3’ • Cannot add string to list • ‘at’ + [‘bad’,‘cat’] → error • [‘at’] + [‘bad’, ‘cat’] → [‘at’,‘bad’,‘cat’] • Interesting • 3*3 → 9 • ‘3’*3 → ‘333’ • ‘3’*’3’ → error
PYTHON - DUCK • Not concerned with type inference • Only interested in the aspects that are used rather than the object itself.
PYTHON - DYNAMIC • Values carry type not variables
PYTHON – DYNAMIC • Type is determined at run time
PYTHON – INFERENCE • Normal type inference is not necessary with duck typing • Python Type Inference Applications: • Optimized Interpreter • Compile Python → Another Language (Perl, C, …) • Further Reading • “Psyco” • “Type Inference for Python” • “Aggressive Type Inference”