290 likes | 435 Views
This material explores the concept of type checking in programming languages, discussing static and dynamic type checking, the implications of strong typing, and how type mismatches are handled. It covers how different languages approach type coercion, conversion, subtyping, and type equality. The examples provided illustrate concepts in languages such as C and Pascal, revealing how static scoping and dynamic scoping affect variable accessibility. This comprehensive overview will help readers understand the importance of type checking in ensuring correct program behavior.
E N D
Programming Language Concepts (CIS 635) Elsa L Gunter 4303 GITC NJIT, www.cs.njit.edu/~elsa/635
Type Checking • When is op(arg1,…,argn) allowed? • Type checking assures that operations are applied to the right number of arguments of the right types • Right type may mean same type as was specified, or may mean that there is a predefined implicit coercion that will be applied • Used to resolve overloaded operations
Type Checking • Type checking may be done statically at compile timeor dynamically at run time • Untyped languages (eg LISP, Prolog) do only dynamic type checking • Typed languages can do most type checking statically
Dynamic Type Checking • Performed at run-time before each operation is applied • Types of variables and operations left unspecified until run-time • Same variable may be used at different types
Dynamic Type Checking • Data object must contain type information • Errors aren’t detected until violating application is executed (maybe years after the code was written)
Static Type Checking • Performed after parsing, before code generation • Type of every variable and signature of every operator must be known at compile time
Static Type Checking • Can eliminate need to store type information in data object if no dynamic type checking is needed • Catches many programming errors at earliest point
Strongly Typed Language • When no application of an operator to arguments can lead to a run-time type error, language is strongly typed • Depends on definition of “type”
Strongly Typed Language • C is “strongly typed” but type coercions may cause unexpected (undesirable) effects; no array bounds check (in fact, no runtime checks at all) • SML “strongly typed” but still must do dynamic array bounds checks, arithmetic overflow checks
How to Handle Type Mismatches • Type checking to refuse them • Apply implicit function to change type of data • Coerce int into real • Coerce char into int
Conversion Between Types: • Explicit: all conversions between different types must be specified • Implicit: some conversions between different types implied by language definition • Implicit conversions called coercions
Coercion Examples Example in Pascal: var A: real; B: integer; A := B • Implicit coercion - an automatic conversion from one type to another
Coercions Versus Conversions • When A has type int and B has type real, many languages allow coercion implicit in A := B • In the other direction, often no coercion allowed; must use explicit conversion: • B := round(A); Go to integer nearest A • B := trunc(A); Delete fractional part of A
Subtypes • A is a subtype of B if every value of A is a value of B (or more accurately it appears to be) • Frequently candidate for coercion • In C many things are subtypes of integer – many things can be implicitly coerced into a integers
Type Equality (aka Type Compatibility) • When are two types “the same”? • Name equivalence: two types equal only if they have the same name • Simple but restrictive • Usually loosened to allow two types to be equal when one is defined with the name of the other (declaration equivalence)
Type Equality • Structure equivalence: Two types are equivalent if the underlying data structures for each type are the same • Problem: how far to go – are two records with the same number of fields of same type, but different labels equivalent?
Scope of Variable • Range of program that can reference that variable (ie access the corresponding data object by the variable’s name) • Variable is local to program or block if it is declared there • Variable is nonlocal to program unit if it is visible there but not declared there
Static Scoping • Scope computed at compile time, based on program text • To determine the variable of a name used must find statement declaring variable
Static Scoping • Subprograms and blocks generate hierarchy of scopes • Subprogram or block that declares current subprogram or contains current block is its static parent
Static Scoping • General procedure to find declaration: • First see if variable is local; if yes, done • If nonlocal to current subprogram or block recursively search static parent until declaration is found • If no declaration is found this way, undeclared variable error detected
program main; var x : integer; procedure sub1; var x : integer; begin { sub1 } … x … end; { sub1 } begin { main } … x … end; { main } Example
Dynamic Scope • Now generally thought to have been a mistake • Main example of use: original versions of LISP • Common LISP uses static scope • Perl allows variables to be decalred to have dynamic scope
Dynamic Scope • Determined by the calling sequence of program units, not static layout • Name bound to corresponding variable most recently declared among still active subprograms and blocks
program main; var x : integer; procedure sub1; begin { sub1 } … x … end; { sub1 } procedure sub2; var x : integer; begin { sub2 } … call sub1 … end; { sub2 } … call sub2… end; { main } Example
program main; var x : integer; procedure sub1; begin { sub1 } … x … end; { sub1 } procedure sub2; var x : integer; begin { sub2 } … call sub1 … end; { sub2 } … call sub2… end; { main } Example: Static Scope
program main; var x : integer; procedure sub1; begin { sub1 } … x … end; { sub1 } procedure sub2; var x : integer; begin { sub2 } … call sub1 … end; { sub2 } … call sub2… end; { main } Example: Dynamic Scope
Referencing Environment • The referencing environment of a program point is the set of all variables (names bound to data objects) visible to that program point • In a static scoped language referencing environment is all local variables (declared so far) together with all declared variables of all static ancestors minus those that have been hidden
program main; var x, y : integer; procedure sub1; var z : integer begin { sub1 } … point1 … end; { sub1 } procedure sub2; var w, x : integer; begin { sub2 } … point2 … end; { sub2 } …point3 … end; { main } Example (Static Scope)
Example • Referencing Envirnoments: • Point1: main.x main.y sub1.z • Point2: main.y sub2.x sub2.w • Point3: main.x main.y