1 / 83

Type Systems and Structures

Type Systems and Structures. Programming Language Principles Lecture 22. Prepared by Manuel E. Bermúdez, Ph.D. Associate Professor University of Florida. Data Types. Most PLs have them. Two purposes: Provide context for operations, e.g. a+b (ints or floats). In Java,

kyrie
Download Presentation

Type Systems and Structures

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Type Systems and Structures Programming Language Principles Lecture 22 Prepared by Manuel E. Bermúdez, Ph.D. Associate Professor University of Florida

  2. Data Types • Most PLs have them. • Two purposes: • Provide context for operations, e.g.a+b(ints or floats). In Java, • Widget x=new(Widget), allocatesmemory for an object of type Widget, and invokes a constructor. • Limits semantically legal operations, e.g. n + "x".

  3. Type equivalence and compatibility. • At hardware level, bits have no type. • In a PL, need types • to associate with values, • to resolve contextual issues and • to check for illegal operations.

  4. Type System • Mechanism for defining types and associating them with PL constructs. • Rules for determining type equivalence, compatibility. Type inferencing rules are used to determine the type of an expression from its parts, and from its context.

  5. Type Systems • Distinction between "type of expression" and "type of object" important only in PLs with polymorphism. • Subroutines have a type in some languages (RPAL: lambda-closure), if they need to be passed as parameters, stored or returned from function.

  6. Type Systems (cont’d) • Type checking: process of enforcing type compatibility rules. A "type clash" occurs if not. • Strongly typed language: enforcement of operations only applied to objects of types intended. Example: C is not very strongly typed: "while(*p++) { ... }"used to traverse an array.

  7. Type Systems (cont’d) • Statically typed language: strongly typed, with enforcement occurring at compile time. Examples: ANSI C (more so than classic C), Pascal (almost, untagged variant records) • Some (few) languages are completely untyped: Bliss, assembly language.

  8. Type Systems (cont’d) • Dynamic (run-time) type checking: RPAL, Lisp, Scheme, Smalltalk. • Other languages (ML, Miranda, Haskell) are polymorphic, but use significant type inference at compile time.

  9. Type Definitions • Early on (Fortran, Algol, BASIC) available types were few and non-extensible. • Many languages distinguish: • type declaration (introduce name and scope) • type definition (describe the object or type itself).

  10. Type Definitions (cont’d) • Three approaches to describe types: • Denotational. • A type is a set of values (domain). • An object has a type if its value is in the set. • Constructive: • A type is either atomic (int, float, bool, etc.) or is built (constructed) from atomic types, i.e. arrays, records, sets, etc. • Abstraction: • A type is an interface: a set of operations upon certain objects.

  11. Classification of Types • Scalar (a.k.a. discrete, ordinal) types: • The terminology varies (bool, logical, truthvalue). • Scalars sometimes come in several widths (short, int, long in C, float and double, too). • Integers sometimes come "signed" and "unsigned."

  12. Classification of Types (cont’d) • Characters sometimes come in different sizes (char and "wide" in C, accommodating Unicode) • Sometimes "complex" and "rational" are provided. • COBOL and PL/1 provide "decimal" type. Example(PL/1): FOR I=0 TO 32/2 ...

  13. Classification of Types (cont’d) Enumerations: • Pascal:type day = (yesterday, today, tomorrow) • A newly defined type, so: var d: day; for d := today to tomorrow do ... • Can also use to index arrays: var profits: array[day] of real; In Pascal, enumeration is a full-fledged type.

  14. Classification of Types (cont’d) • C: enum day {yesterday,today,tomorrow }; equivalent to: typedef int day; const day yesterday=0; today=1; tomorrow=2;

  15. Classification of Types (cont’d) • Subrange types. • Values are a contiguous subset of the base type values. The range imposes a type constraint. Pascal: type water_temp = 32 .. 212;

  16. Classification of Types (cont’d) • Composite Types. • Records. A heterogeneous collection of fields. • Variant records. Only one of the fields is valid at any given time. Union of the fields, vs. Cartesian product. • Arrays. Mapping from indices to data fields.

  17. Classification of Types (cont’d) • Sets. Collections of distinct elements, from a base type. • Pointers. l-values. Used to implement recursive data types: an object of type T contains references to other objects of type T. • Lists. Length varies at run-time, unlike (most) arrays. • Files. Hold a current position.

  18. Orthogonality • Pascal: variant fields required to follow non-variant ones. • Most PL's provide limited ability to specify literal values of composite types. • Example:In C, int [] x = {3,2,1} Initializer, only allowed for declarations, not assignments. • In Ada, use aggregates to assign composite values.

  19. Type Equivalence • Structural equivalence: Two types are equivalent if they contain the same components. • Varies from one language to another.

  20. Type Equivalence (cont’d) Example: type r1 = record a,b: integer; end; type r2 = record b: integer; a: integer; end; var v1: r1; v2: r2; v1 := v2; • Are these types compatible ? • What if a and b are reversed ? • In most languages, no. In ML, yes.

  21. Type Equivalence (cont’d) • Name equivalence: based on type definitions: usually same name. • Assumption: named types are intended to be different. • Alias types: definition of one type is the name of another. • Question: Should aliased types be the same type?

  22. Type Equivalence (cont’d) • In Modula-2: TYPE stack_element = INTEGER; MODULE stack; IMPORT stack_element; EXPORT push, pop; procedure push (e:stack_element); procedure pop ( ): stack_element; • Stack module cannot be reused for other types.

  23. Type Equivalence (cont’d) • However, TYPE celsius = REAL; fahrenh = REAL; VAR c: celsius; f: fahrenh; f := c; (* should probably be an error *)

  24. Type Equivalence (cont’d) • Strict name equivalence: aliased types are equivalent. • type a = bconsidered both declaration and definition. • Loose name equivalence: aliased types not equivalent. • type a = bconsidered a declaration; a and b share the definition.

  25. Type Equivalence (cont’d) In Ada: compromise, allows programmer to indicate: • alias is a subtype (compatible with base type) subtype stack_element is integer;

  26. Type Equivalence (cont’d) • In Ada, an alias is a derived type (not compatible) subtype stack_element is integer; type celsius is new REAL; type fahrenh is new REAL; • Now the stack is reusable, and celsius is not compatible with fahrenh.

  27. Type Conversion and Casts • Many contexts in which types are expected: • assignments, unary and binary operators, parameters. • If types are different, programmer must convert the type (conversion or casting).

  28. Three Situations • Types are structurally equivalent, but language requires name equivalence. Conversion is trivial. • Example (in C): typedef number int; typedef quantity int; number n; quantity m; n = m;

  29. Three Situations (cont’d) • Different sets of values, but same representation. • Example:subrange 3..7 of int. • Generate run-time code to check for appropriate values (range check).

  30. Three Situations (cont’d) • Different representations. • Example (in C): int n; float x; n = x; • Generate code to perform conversion at run-time.

  31. Type Conversions • Ada: name of type used as a pseudofunction: • Example:n = integer(r); • C, C++, Java:Name of type used as prefix operator, in ()s. • Example:n = (int) r;

  32. Type Conversions (cont’d) • If conversion not supported in the language, convert to pointer, cast, and dereference (ack!): r = *((float *) &n); • Re-interpret bits in n as a float.

  33. Type Conversions (cont’d) • OK in C, as long as • nhas an address (won't work with expressions) • nandroccupy the same amount of storage. • programmer doesn't expect run-time overflow checks !

  34. Type Compatibility and Coercions • Coercion: implicit conversion. • Rules vary greatly fromone language to another.

  35. Type Compatibility and Coercions (cont’d) • Ada: Types T and S are compatible (coercible) if either • T and S are equivalent. • One is a subtype of the other (or both subtypes of the same base type). • Both are arrays (same numbers, and same type of elements). • Pascal: same as Ada, but allows coercion from integer to real.

  36. Type Compatibility and Coercions (cont’d) • C: Many coercions allowed. General idea: convert to narrowest type that will accommodate both types. • Promote char (or short int) to int, guaranteeing neither is char or short. • If one operand is a floating type, convert the narrower one: float -> double -> long double

  37. Type Compatibility and Coercions (cont’d) • Note: this accommodates mixtures of integer and floating types. • If neither type is a floating type, convert the narrower one: int-> unsigned int-> long int-> unsigned long int

  38. Examples char c; /* signed or unsigned -- implementation? */ short int s; unsigned int u; int i; long int l; unsigned long int ul; float f; double d; long double ld;

  39. Examples (cont’d) i + c; /* c converted to int */ i + s; /* s converted to int */ u + i; /* i converted to unsigned int */ l + u; /* u converted to long int */ ul + l; /* l converted to unsigned long int */ f + ul; /* ul converted to float */ d + f; /* f converted to double */ ld + d; /* d converted to long double */

  40. Type Compatibility and Coercions (cont’d) • Conversion during assignment. • usual arithmetic conversions don't apply. • simply convert from type on the right, to type on the left.

  41. Examples s = l; /* l's low-order bits -> signed number */ s = ul; /* ditto */ l = s; /* s signed-extended to longer length */ ul = s: /* ditto, ul's high-bit affected ? */ s = c; /* c extended (signed or not) to */ /* s's length, interpreted as signed */ f = l; /* l converted to float, precision lost */ d = f: /* f converted, no precision lost. */ f = d; /* d converted, precision lost */ /* result may be undefined */

  42. Type Inference • Usually easy. • Type of assignment is type of left-side. • Type of operation is (common) type of operands.

  43. Type Inference (cont’d) • Not always easy. Pascal: type A: 0 .. 20; B: 10.. 20: var a: A; b: B; • What is the type ofa+b ?In Pascal, it's the base type (integer).

  44. Type Inference (cont’d) • Ada: • The type of the result would be an anonymous type 0..40. • The compiler would generate run-time checks for values out of bounds. • Curbing unnecessary run-time checks is a major problem.

  45. Type Inference (cont’d) • Pascal allows operations on sets: var A: set of 1..10; B: set of 10..20; C; set of 1..15; i: 1..30; C := A + B * [1..5,i]; • The type of the expression is set of integer (the base type). Range check is required when assigning toC.

  46. Type Inference (cont’d) • Type safety in Java

  47. Type Inference in ML • Programmer can declare types, but if not, ML infers them, using unification (more later in Prolog).

  48. Type Inference in ML (cont’d) • ML infers the return type of "fib": • i+1 implies i is of type int. • i=n implies n is of type int. • fib_helper(0,1,0) implies f1, f2 of type int, and confirms (doesn't contradict) i is of type int. • fib_helper returning f2 implies fib_helper returns int. • fib returning fib_helper(0,1,0) implies fib returns int.

  49. Type Inference in ML (cont’d) • ML checks type consistency: no contradictions or ambiguities. • By inferring types, ML allows polymorphism: fun compare (x,p,q) = if x = p then if x = qthen "all three match" else "first two match" else if x = q then "second two match" else "none match";

  50. Type Inference in ML (cont’d) • The type of fun is not specified. Typeinference yields any type for which'=' is legal (many of them !). • Result is polymorphic 'compare' method. • It's possible to underspecify the type: fun square (x) = x * x; (* int or float ? *) fun square (x:int) = x * x; (* ambiguity gone *)

More Related