Chapter 5 Names Bindings Type Checking and Scopes
Chapter 5 Names, Bindings, Type Checking, and Scopes ISBN 0 -321 -33025 -0
Chapter 5 Topics • • • Introduction Names Variables The Concept of Binding Type Checking Strong Typing Type Compatibility Scope and Lifetime Referencing Environments Named Constants Copyright © 2006 Addison-Wesley. All rights reserved. 1 -2
Introduction • Imperative languages are abstractions of von Neumann architecture – Memory (instructions & data) – Processor • Variables characterized by attributes – must consider scope, lifetime, type checking, initialization, and type compatibility Copyright © 2006 Addison-Wesley. All rights reserved. 1 -3
Names • Design Issues Length Case sensitive Keyword/Reserved Length – Tradeoffs: Name should be connotative, but want reasonable length for symbol table I think 1 character is long enough for a variable name What in the world does L stand for? FORTRAN I: maximum 6 COBOL: maximum 30 FORTRAN 90 and ANSI C: maximum 31 Ada and Java: no limit, and all are significant C++: no limit, but implementers often impose one Copyright © 2006 Addison-Wesley. All rights reserved. 1 -4
Names (continued) Design Issues Length Case sensitive Keyword/Reserved • Case sensitivity – Disadvantage: readability because names that look alike are different – C, C++, and Java names are case sensitive – The names in many other languages are not – “Camel” notation – my. Item - embedded uppercase – is a style choice, not a language decision, although if predefined methods/classes use camel style it's forced on users (e. g. , Array. Index. Out. Of. Bounds). Copyright © 2006 Addison-Wesley. All rights reserved. 1 -5
Names (continued) Design Issues Length Case sensitive Keyword/Reserved • Special words – A keyword is a word that is special only in certain contexts, e. g. , in Fortran – Real Var. Name (Real is a data type followed with a name, therefore Real is a keyword) – Real = 3. 4 (Real is a variable) – A reserved word is a special word that cannot be used as a user-defined name. Generally less confusing. Copyright © 2006 Addison-Wesley. All rights reserved. 1 -6
Variables Attributes Design Issues Name Address Values Type Lifetime Scope • Name - not all variables have them • Address - the memory address with which it is associated – Sometimes called the l-value – A variable may have different addresses at different times during execution (e. g. , local variable in subprogram) – If two variable names can be used to access the same memory location, they are called aliases – Aliases are created via pointers, reference variables, C and C++ unions (ch 6) – Aliases are harmful to readability (program readers must remember all of them) and reliability Copyright © 2006 Addison-Wesley. All rights reserved. 1 -7
Variables Attributes (continued) Design Issues Name Address Values Type Lifetime Scope • Type - determines the range of values of variables and the set of operations that are defined for values of that type; in the case of floating point, type also determines the precision • Value - the contents of the location with which the variable is associated (r-value) Copyright © 2006 Addison-Wesley. All rights reserved. 1 -8
The Concept of Binding • A binding is an association, such as between an attribute and an entity (e. g. , type of a variable), or between an operation and a symbol (e. g. , meaning of *), or a function and its definition • Binding time is the time at which a binding takes place. • Type binding may be static or dynamic, explicit or implicit Copyright © 2006 Addison-Wesley. All rights reserved. 1 -9
Possible Binding Times • Language design time -- bind operator symbols (e. g. , +) to operations • Language implementation time-bind type to a representation • Compile time -- bind a variable to a type • Link time – bind library subprogram to code int sum=0; int count; sum = sum + count; cout << sum; • Load time -- bind a FORTRAN 77 variable to a memory cell (or a C static variable) • Runtime -- bind a nonstatic local variable to a memory cell Copyright © 2006 Addison-Wesley. All rights reserved. 1 -10
Static and Dynamic Binding • A binding is static if it first occurs before run time and remains unchanged throughout program execution. • A binding is dynamic if it first occurs during execution or can change during execution of the program • NOTE: doesn't consider paging etc. which is at the hardware level Copyright © 2006 Addison-Wesley. All rights reserved. 1 -11
Explicit/Implicit Declaration • An explicit declaration is a program statement used for declaring the types of variables: int count; • An implicit declaration is a default mechanism for specifying types of variables (the first appearance of the variable in the program) • Both create static bindings to types (i. e. , type doesn’t change during execution of program) • FORTRAN, PL/I, BASIC, and Perl provide implicit declarations – Advantage: writability – Disadvantage: reliability Copyright © 2006 Addison-Wesley. All rights reserved. 1 -12
Perl • • • Begin with $ is scalar (string or numeric) Begin with @ is array Begin with % is hash Different namespaces Advantage: can tell from name what type of data it is • Contrast Fortran: first initial gave data type for implicit, but could have explicit which didn't follow convention Copyright © 2006 Addison-Wesley. All rights reserved. 1 -13
Dynamic Type Binding • Type not specified by declaration, not determined by name (Java. Script and PHP) • Specified through an assignment statement e. g. , Java. Script list = [2, 4. 33, 6, 8]; list = 17. 3; – Advantage: flexibility (generic program units) – Disadvantages: • High cost (dynamic type checking requires run-time descriptors, normally interpreted) • Type error detection by the compiler is difficult Copyright © 2006 Addison-Wesley. All rights reserved. 1 -14
Dynamic Type Issue i = x; // desired i = y; // typed accidentally, y is array • Later uses of i expect a scalar, but it is now an array so incorrect results occur. With static binding, i = y; would generate an error, easier to find problem. Copyright © 2006 Addison-Wesley. All rights reserved. 1 -15
Variable Attributes - Lifetime Design Issues Name Address Values Type Lifetime Scope • Storage Bindings & Lifetime – Allocation - getting a cell from some pool of available cells – Deallocation - putting a cell back into the pool • The lifetime of a variable is the time during which it is bound to a particular memory cell Heap allocate Var lifetime oc eall ate d Copyright © 2006 Addison-Wesley. All rights reserved. 1 -16
Categories of Variables by Lifetimes Static • bound to memory cells before execution begins and remains bound to the same memory cell throughout execution, e. g. , all FORTRAN 77 variables, C static variables (not C++ class variables) void my. Fn() { static int count=0; … } • Advantages: efficiency (direct addressing), history-sensitive subprogram support • Disadvantage: lack of flexibility (no recursion), storage can't be shared among subprograms Copyright © 2006 Addison-Wesley. All rights reserved. 1 -17
Categories of Variables by Lifetimes Stack-dynamic— • Storage bindings created when execution reaches code • Allocated from the run-time stack • Variables may be allocated at the beginning of a method, even though declarations may be spread throughout • Advantage: allows recursion; conserves storage • Disadvantages: Overhead of allocation and deallocation (not too bad, since all memory allocated/ deallocated together), Subprograms cannot be history sensitive, Inefficient references (indirect addressing) Copyright © 2006 Addison-Wesley. All rights reserved. void my. Fn 2(int parm) { int temp; … } int temp 2; sp local 1 -18
Categories of Variables by Lifetimes Explicit heap-dynamic • Allocated and deallocated by explicit directives during runtime. • Referenced only through pointers or references, e. g. dynamic objects in C++ (via new and delete), all objects in Java • Advantage: provides for dynamic storage management • Disadvantage: inefficient and unreliable, C# methods that void my. Fn 3() { int* nums = new int[5]; … } public void my. Fn 4() { Point point = new Point(); } define a pointer must include reserved word unsafe Copyright © 2006 Addison-Wesley. All rights reserved. 1 -19
Categories of Variables by Lifetimes Implicit heap-dynamic • Allocation and deallocation caused by assignment statements list = [2, 4. 33, 6, 8]; • all variables in APL; all strings and arrays in Perl and Java. Script • Advantage: flexibility • Disadvantages: Inefficient because all attributes are dynamic, loss of error detection Copyright © 2006 Addison-Wesley. All rights reserved. 1 -20
Type Checking Design Issues Name Address Values Type Lifetime Scope • Type checking is the activity of ensuring that the operands of an operator are of compatible types • A compatible type is one that is either: – legal for the operator – allowed under language rules to be implicitly converted (coerced), by compiler- generated code, to a legal type • A type error is the application of an operator to an operand of an inappropriate type Copyright © 2006 Addison-Wesley. All rights reserved. 1 -21
Type Checking (continued) • Concept of type checking can be generalized to include: – subprograms (e. g. , operands are parameters) – assignment • A programming language is strongly typed if type errors are always detected (even memory cells that can hold various types) Copyright © 2006 Addison-Wesley. All rights reserved. 1 -22
Strong Typing • Advantage of strong typing: allows the detection of the misuses of variables that result in type errors • Coercions weaken type checking system • C++ has many coercions. Java has fewer, but still more than Ada • Language classification: – – FORTRAN 77 is not: parameters, EQUIVALENCE Pascal is not: variant records C and C++ are not: unions are not type checked Ada is, almost (UNCHECKED CONVERSION is loophole, doesn't actually “convert” just uses bits as new type) Copyright © 2006 Addison-Wesley. All rights reserved. 1 -23
Type Equivalence • For user-defined types, coercion is rare and the issue is not type compatibility but type equivalence • If two variables are equivalent then either one can have its value assigned to the other • Two approaches are name type equivalence and structure type equivalence Copyright © 2006 Addison-Wesley. All rights reserved. 1 -24
Type Equivalence • Name type equivalence means the two variables have equivalent types if they are in either the same declaration or in declarations that use the same type name – double x, y; // same declaration – int count; – int size; // count & size use same type name • Easy to implement but highly restrictive • Structure type equivalence means that two variables have equivalent types if their types have identical structures • More flexible, but harder to implement Are these equivalent? Not in C: it uses struct date { struct date 2 { name equivalence for struct, int month, int m, enum & union – unless defined int day, int d, in different files! C++ removed int year }; int y}; different file exception. Copyright © 2006 Addison-Wesley. All rights reserved. 1 -25
Variable Attributes: Scope Design Issues Name Address Values Type Lifetime Scope • The scope of a variable is the range of statements over which it is visible • The nonlocal variables of a program unit are those that are visible but not declared there • Static scoping: Algol, Pascal, C-type • Dynamic scoping: Bash • Programmer choice: Perl, Lisp Copyright © 2006 Addison-Wesley. All rights reserved. 1 -26
Don’t confuse static scope with static lifetime! Static Scope (aka lexical scope) • Based on program text • Search declarations, first locally, then in increasingly larger enclosing scopes procedure Big is X : Integer; procedure Sub 1 is Scope of Sub 1 X : Integer; begin. . . end; Scope of Big procedure Sub 2 is Scope of Sub 2 begin. . X. . end; begin // Big. . . end; Reference to X in Sub 2 refers to X in static parent Big. The X in Sub 1 is not a static ancestor of Sub 2. What language use static scope? Pascal, Ada, C, ML, Haskell C & C++ do not allow nested procedures. Nor does Java. Inner classes may accomplish some of same goals Copyright © 2006 Addison-Wesley. All rights reserved. 1 -27
Scope (continued) • Variables can be hidden from a unit by having a "closer" variable with the same name int count; Notice that blocks also create static scopes while (. . . ) { int count; . . . } – illegal in Java and C#, legal in C and C++ • C++ and Ada allow access to these "hidden" variables – In Ada: unit. name – In C++: class_name: : name, : : name for global Copyright © 2006 Addison-Wesley. All rights reserved. 1 -28
Evaluation of Static Scoping • Assume MAIN calls A and B A calls C and D B calls A and E MAIN A C A B D C B D E E Copyright © 2006 Addison-Wesley. All rights reserved. 1 -29
Static Scope Potential Call Graph potential calls desired calls MAIN A C MAIN B D A E C B D E What if E needs access to variables in A? Could move it. But if need access to variables in A and B, may resort to globals (or variables in main). Overall design may end up with too many globals. What if E needs to call D? May move it to the same level as A and B. Static scoping issues led to design of better encapsulation structures. Copyright © 2006 Addison-Wesley. All rights reserved. 1 -30
Dynamic Scope • Based on calling sequences of program units, not their textual layout (temporal versus spatial) • References to variables are connected to declarations by searching back through the chain of subprogram calls that forced execution to this point. Must be determined at runtime. Copyright © 2006 Addison-Wesley. All rights reserved. 1 -31
Scope Example MAIN declaration of x SUB 1 declaration of x. . . call SUB 2. . . reference to x. . . main body Copyright © 2006 Addison-Wesley. All rights reserved. Static scoping • Reference to x in SUB 2 is to MAIN's x Dynamic scoping • Reference to x depends on call sequence MAIN calls SUB 1 calls SUB 2 uses x - declared in SUB 1 MAIN calls SUB 2 uses x - declared in MAIN 1 -32
Quick Example var y = "global"; function print-y() { print(y); } function test-scope() { var y = "local"; print-y(); } test-scope(); // static languages print "global" // dynamic languages print "local" print-y(); // all languages should print "global" Copyright © 2006 Addison-Wesley. All rights reserved.
Scope and Lifetime • Scope and lifetime are sometimes closely related, but are different concepts • Scope and lifetime for local variable in Java method with no method calls very closely related (i. e. , local variables exists for duration of method, scope is in method) • Scope and lifetime for a static variable in a C or C++ function are different. Lifetime is entire program execution, but scope is just that function. We’ll do a quick exercise with static variables Copyright © 2006 Addison-Wesley. All rights reserved. 1 -34
Referencing Environments • The referencing environment of a statement is the collection of all names that are visible in the statement • In a static-scoped language, it is the local variables plus all of the visible variables in all of the enclosing scopes • In a dynamic-scoped language, the referencing environment is the local variables plus all visible variables in all active subprograms • Referencing Environment concept is important because data structures must be created to provide access to all nonlocal variables (covered in Chapter 10) How does this relate to closures? Copyright © 2006 Addison-Wesley. All rights reserved. 1 -35
Referencing Environments Static Example procedure Example is A, B : Integer; . . . procedure Sub 1 is X, Y : Integer; begin – #a. . . end; procedure Sub 2 is X : Integer; . . . procedure Sub 3 is X : Integer; begin - #b end; begin - …#c end; // Sub 2 begin -. . . #d end. Copyright © 2006 Addison-Wesley. All rights reserved. Point a env: X and Y of Sub 1, A and B of Example Point b env: X of Sub 3 (X of Sub 2 is hidden), A and B of Example Point c env: X of Sub 2, A and B of Example Point d env: A and B of Example 1 -36
Referencing Environments Dynamic Example void sub 1() { int a, b; #X } void sub 2() { int b, c; #Y } sub 1; int main() { int c, d; #Z } sub 2(); Copyright © 2006 Addison-Wesley. All rights reserved. Assume main calls sub 2, which calls sub 1: • Point #X env: – a and b of sub 1 – c of sub 2 – d of main (c of main and b of sub 2 hidden) • Point #Y env: – b and c of sub 2 – d of main (c of main hidden) • Point #Z env: – c and d of main We’ll do a scoping exercise 1 -37
Named Constants • A named constant is a variable that is bound to a value at the same time it is bound to storage • Advantages: readability and maintainability • The binding of values to named constants can be either static (called manifest constants) or dynamic • Languages: – – FORTRAN 90: constant-valued expressions Ada, C++, and Java: expressions of any kind Ex: const int result = 2 * width + 1; C# has const (static) and readonly (dynamic) Copyright © 2006 Addison-Wesley. All rights reserved. 1 -38
Variable Initialization • The binding of a variable to a value at the time it is bound to storage is called initialization • Initialization is often done on the declaration statement, e. g. , in Java int sum = 0; Copyright © 2006 Addison-Wesley. All rights reserved. 1 -39
Summary • Case sensitivity and the relationship of names to special words represent design issues of names • Variables are characterized by the sextuples: name, address, value, type, lifetime, scope • Binding is the association of attributes with program entities • Scalar variables are categorized as: static, stack dynamic, explicit heap dynamic, implicit heap dynamic • Strong typing means detecting all type errors Copyright © 2006 Addison-Wesley. All rights reserved. 1 -40
Exercise • Static and dynamic scoping exercise Copyright © 2006 Addison-Wesley. All rights reserved.
- Slides: 41