1 / 39

4 Bindings and Scope

4 Bindings and Scope. Bindings and environments. Scope, block structure, and visibility. Declarations. Blocks. © 2004, D.A. Watt, University of Glasgow. Bindings and environments.

duke
Download Presentation

4 Bindings and Scope

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. 4Bindings and Scope • Bindings and environments. • Scope, block structure, and visibility. • Declarations. • Blocks. © 2004, D.A. Watt, University of Glasgow

  2. Bindings and environments • PL expressions and commands contain identifiers, which are declared elsewhere. Their meanings depend on these declarations. • A binding is a fixed association between an identifier and an entity such as a value, variable, or procedure. • Each declaration produces one or more bindings. • An environment (or name space) is a set of bindings. • Each expression or command is interpreted in a particular environment. Each identifier used in the expression or command must have a binding in that environment.

  3. Example: Ada environments • Ada program outline: procedure p is z: constant Integer := 0; c: Character; procedure q (x: in Float) is c: constant Float := 3.0e6; b: Boolean;begin…end q; begin…end p; Environments: { b a Boolean variable,c the floating-point number 3.0106,p a procedure with no parameter,q a procedure with a Float parameter,x a Float variable,z the integer 0 } { c a Character variable,p a procedure with no parameter,q a procedure with a Float parameter,z the integer 0 }

  4. Scope • The scope of a declaration (or of a binding) is the portion of the program text over which it has effect. • In some early PLs (such as Cobol), the scope of each declaration was the whole program. • In modern PLs, the scope of each declaration is controlled by the program’s block structure.

  5. Block structure • A block is a program construct that delimits the scope of any declarations within it. • Each PL has its own forms of blocks: • C: block commands ({ … }), function bodies, compilation units. • Java: block commands, method bodies, class declarations, packages. • Ada: block commands (declare … begin … end;), procedure bodies, packages, tasks, etc. • A PL’s block structure is the way in which blocks are arranged in the program text.

  6. Example: Ada block structure • Ada program outline: procedure P is… begin…declare…begin…end;…end P; procedure Q is…begin…end Q;

  7. declaration of x declaration of x declaration of y declaration of y declaration of z declaration of z scope of declarations of x, y, z Monolithic block structure • Some PLs (such as Cobol) have monolithic block structure: the whole program is a single block. The scope of every declaration is the whole program.

  8. declaration of y scope of decl-aration of y declaration of x declaration of x declaration of x scope of decl-aration of x declaration of y declaration of y declaration of y declaration of y declaration of z declaration of z declaration of z declaration of z scope of decl-aration of z declaration of z Flat block structure • Some PLs (such as Fortran) have flat block structure: the program is partitioned into non-overlapping blocks.

  9. declaration of x declaration of x scope of decl-aration of x declaration of y declaration of y declaration of y scope of decl-aration of y declaration of z scope of decl-aration of z declaration of z declaration of z Nested block structure • Modern PLs have nested block structure: blocks may be nested within other blocks.

  10. Scope and visibility • A binding occurrence of identifier I is an occurrence of I where I is bound to some entity X. • An applied occurrence of identifier I is an occurrence of I where use is made of the entity X to which I is bound. • At this applied occurrence, we say that IdenotesX. • If the PL is statically scoped (see later), every applied occurrence of I should correspond to exactly one binding occurrence of I.

  11. Example: Ada binding and applied occurrences • Ada program outline: procedurepis z : constant Integer := 0;c : Character; procedureq (x : in Float) isc : constant Float := 3.0e6;b : Boolean;begin… b … c … x … z …end q; begin… c … z …end p;

  12. declaration of x declaration of x declaration of x declaration of x Hiding • If identifier I is declared in two different blocks, I denotes a different entity in each block. • If identifier I is declared in two nested blocks, I denotes one entity in the outer block and a different entity in the inner block. The inner declaration hides the outer one. Here the outer declaration of x is hidden.

  13. Static vs dynamic scoping (1) • A PL is statically scoped if the body of a procedure is executed in the environment of the procedure definition. • We can decide at compile-time which binding occurrence of an identifier corresponds to a given applied occurrence. • A PL is dynamically scoped if the body of a procedure is executed in the environment of the procedure call. • We cannot decide until run-time which binding occurrence of an identifier corresponds to a given applied occurrence, since the environment may vary from one procedure call to another.

  14. Example: static vs dynamic scoping (1) • Program in Ada (which is statically scoped): s : constant Integer := 2; function f (x : Integer) return Integer isbeginreturn s * x;end f; procedure q (y : Integer) isbegin put(f(y));end q; procedure q (z : Integer) iss : constant Integer := 3;beginput(f(z));end q; The value of s here is always 2.

  15. Example: static vs dynamic scoping (2) • Same program in a hypothetical dynamically scoped PL: s : constant Integer := 2; function f (x : Integer) return Integer isbeginreturn s * x;end f; procedure q (y : Integer) isbegin put(f(y));end q; procedure q (z : Integer) iss : constant Integer := 3;beginput(f(z));end q; The value of s here depends on the call site. multiplies value of y by 2 multiplies value of z by 3

  16. Static vs dynamic scoping (2) • Dynamic scoping fits badly with static typing. • In the previous slide, what if the two declarations of s had different types? • Nearly all PLs (including C, Java, and Ada) are statically scoped. • Only a few PLs (such as Smalltalk and Lisp) are dynamically scoped.

  17. Declarations (1) • A declaration is a program construct that will be elaborated to produce binding(s). • A declaration may have side effects (such as creating a variable). • A definition is a declaration whose only effect is to produce binding(s).

  18. The repertoire of simple declarations depends on the PL. The repertoire of simple declarations depends on the PL. The repertoire of simple declarations depends on the PL. The repertoire of simple declarations depends on the PL. The repertoire of simple declarations depends on the PL. Declarations (2) • Forms of declarations: • type declarations • constant declarations • variable declarations • procedure definitions • … • collateral declarations • sequential declarations • recursive declarations.

  19. Type declarations • A type declaration binds an identifier to a type. • A type definition binds an identifier to an existing type. • Alternatively, a type declaration may introduce a new type, distinct from all existing types.

  20. bound to new types bound to new types Example: C type declarations • “typedef …” binds an identifier to an existing type: typedefchar* Alpha; Alpha s; char* t; s = t; bound to exist-ing type char* legal • But “enum …”, “struct …”, or “union …” binds an identifier to a new type: structBook {Alpha title, int edition};structAuthor {Alpha name, int age}; Book b; Author a; a = b; illegal

  21. bound to new types bound to new types bound to new types Example: Ada type declarations • Every Ada type declaration introduces a new and distinct type: typeAlphaisarray (1 .. 32) of Character; typeBookisrecord title: Alpha; edition: Integer;endrecord;typeAuthorisrecord name: Alpha; age: Integer;endrecord; b: Book; a: Author; a := b; illegal

  22. Constant declarations • A constant declaration binds an identifier to a (constant) value. • In Ada, a constant declaration has the form: I : constantT := E; This binds I to the value of the expression E, which must be of type T. • Some PLs restrict the expression E to be a literal, or an expression that can be evaluated at compile-time. • Some PLs restrict the constant’s type T.

  23. Variable declarations • A variable declaration binds an identifier to a variable. • In Ada, ordinary variable declarations have the form: I : T := E; This creates a variable of type T, binds I to that variable, and initialises it to the value of the expression E. • In Ada, renaming variable declarations have the form: I : TrenamesV; This binds I to the existing variable V.

  24. Example: Ada renaming variable declaration • Ada code: type Country is (UK, FR, …);pop : array (Country) of Natural; declare c : Country := …;p : Integer renames pop(c);begin… p := p + 1;…end; bound to existing variable pop(c) more efficient thanpop(c):=pop(c)+1;

  25. Procedure definitions • A procedure definition binds an identifier to a procedure. • In most PLs, we can define both proper procedures and function procedures.

  26. Example: C++ procedure definitions • Function procedure definition: booleven (int n) {return (n % 2 == 0);} bound to a function proced-ure that tests whether its Integer argument is even • Proper procedure definition: voiddouble (int& n) { n *= 2;} bound to a proper proced-ure that doubles its Integer argument

  27. Collateral declarations • A collateral declaration is a group of subdeclarations that are elaborated independently of one another. • A subdeclaration may not use bindings produced by any other subdeclaration. • Collateral declarations are found in functional PLs, but not in C or Ada.

  28. Sequential declarations • A sequential declaration is a group of subdeclarations that are elaborated one after another. • A subdeclaration may use bindings produced by previous subdeclarations, but not those produced by following subdeclarations. • Sequential declarations are found in all imperative and OO PLs.

  29. Recursive declarations • A recursive declaration is one that uses the bindings it produces itself. • Ada type declarations: • A single type declaration may be recursive. • A sequence of type declarations may be made mutually recursive, if preceded by “incomplete type declarations”. • Ada procedure declarations: similarly. • Java method definitions: • One or more method definitions may be (mutually) recursive.

  30. Example: Ada recursive type declarations • Mutually recursive type declarations: typeIntNode;typeIntListisaccess IntNode;typeIntNodeisrecord head: Integer; tail: IntList;endrecord; incomplete type declaration: binds IntNode to an unknown type completes the binding of IntNode

  31. Example: Ada recursive procedure definitions (1) • Recursive procedure definition: procedureprint (n: Natural) isbeginif n < 10 then put(digit(n));else print(n/10); put(digit(n mod 10));endif;end;

  32. Example: Ada recursive procedure definitions (2) • Mutually recursive procedure definitions: procedureparse_expression; procedureparse_primaryisbeginif acceptable('(') loop accept('('); parse_expression; accept(')');else parse_variable;endif;end; binds parse_expression to an unknown procedure

  33. Example: Ada recursive procedure definitions (3) • Mutually recursive procedure definitions (continued): procedureparse_expressionisbegin parse_primary;while acceptable('+') loop accept('+'); parse_primary;endloop;end; completes the binding of parse_expression

  34. Blocks • A block is a program construct that delimits the scope of any declarations within it. • Kinds of blocks: • block commands • block expressions.

  35. Block commands • A block command is a form of command that contains a local declaration (or group of declarations) D and a subcommand C. • The bindings produced by D are used only for executing C. These bindings override any bindings for the same identifiers in the environment outside the block. • Block commands are common in imperative and OO PLs. • In C and Java: { DC } • In Ada: declareDbeginCend;

  36. block command(scope of declaration of z) Example: Java block command • To sort the values of int variables x and y into ascending order: if (x > y){ intz = x; x = y; y = z;}

  37. Block expressions • A block expression is a form of expression that contains a local declaration (or group of declarations) D and a subexpression E. • The bindings produced by D are used only for evaluating E. These bindings override any bindings for the same identifiers in the environment outside the block. • Block expressions are uncommon in imperative and OO PLs, but common in functional PLs. • Form of block expression in Haskell: letDinE

  38. Example: Haskell block expression • To compute the area of a triangle whose sides have lengths a, b, c: lets = (a + b + c)/2.0in sqrt(s*(s-a)*(s-b)*(s-c)) • The only way to achieve the same effect in Ada (or C) is to declare and call a suitable function: function area (a, b, c: Float)return Float iss: constant Float := (a + b + c)/2.0;beginreturn sqrt(s*(s-a)*(s-b)*(s-c));end;

  39. The Qualification Principle • A blockcommand is a command containing a local declaration D and a subcommandC, the binding produced by D being used only for executingC • A blockexpression is an expression containing a local declaration D and a subexpressionE, the binding produced by D being used only for evaluatingE • The Qualification Principle • It is possible to include a block in any syntactic category, provided that the constructs in that syntactic category specify some kind of computation A block declaration is …

More Related