Names Scopes and Bindings Aaron Bloomfield CS 415

  • Slides: 33
Download presentation
Names, Scopes and Bindings Aaron Bloomfield CS 415 Fall 20051 1

Names, Scopes and Bindings Aaron Bloomfield CS 415 Fall 20051 1

Binding • A binding is an association between two things, such as a name

Binding • A binding is an association between two things, such as a name and the thing it represents • Example: int x – When this statement is compiled, x is bound to a memory space 2

Binding Time • The time at which the association between two items is created

Binding Time • The time at which the association between two items is created • There are many different binding times that can be implemented: – – – – Language design time Language implementation time Program writing time Compile time Link time Load time Run time 3

Binding Times • Language design time – These are control flow constructs, primitives, and

Binding Times • Language design time – These are control flow constructs, primitives, and other semantics – Think of reserved words: i. e. if, for, else, while, etc. • Language implementation time – These include I/O couplings – System dependent things such as max heap and stack sizes – Think of constants: MAX_INT, etc. – In Algol, this included the I/O procedure names 4

Binding Times • Program writing time – When you the programmer choose data structures

Binding Times • Program writing time – When you the programmer choose data structures and names • Compile time – The compiler maps high level constructs to machine code – Think of the assembly for a compiled procedure • Link time – Separate compilation means not every part of a program has to be compiled at the same time – Libraries are linked to your program and bound 5

Binding Times • Load time – For primitive operating systems – Binds physical addresses

Binding Times • Load time – For primitive operating systems – Binds physical addresses – Most OSes do this during link time with virtual addresses • Run time – Very broad term covering the span of execution – Values to variable bindings occur here 6

Binding Times • Very important to design and implementation of programming languages – Early

Binding Times • Very important to design and implementation of programming languages – Early bindings = greater efficiency – Later bindings = greater flexibility 7

Scope rules • The textual region of the program in which a binding is

Scope rules • The textual region of the program in which a binding is active is its scope • Static scoping is more common in modern programming langauges – Found in C, C++, Pascal 8

Static scope • All scoping can be determined at compile time • Most often

Static scope • All scoping can be determined at compile time • Most often this is done with a textual top-tobottom scan • Most basic static scope rule: everything has global scope 9

Fortran Implementation • Global scopes • Local scopes limited to their subroutines • Local

Fortran Implementation • Global scopes • Local scopes limited to their subroutines • Local variable scope extends through the execution of the subroutine unless the variable is saved 10

Nested Subroutines • Introduced in Algol 60 and is found in some modern languages

Nested Subroutines • Introduced in Algol 60 and is found in some modern languages – Pascal, Ada • Subroutines can be declared inside other subroutines – This confuses the scope rules even more 11

Closest Nested Scope Rule • A variable declared has its scope in the current

Closest Nested Scope Rule • A variable declared has its scope in the current subroutine, and any internally nested subroutines, unless there is a definition with the same name more locally 12

Closest Nested Scope Rule Example procedure level 1() variable x; procedure level 2() variable

Closest Nested Scope Rule Example procedure level 1() variable x; procedure level 2() variable x; begin (* level 2 code *) end begin (* level 1 code *) end procedure outside() begin (*outside code*) end 13

Dynamic Scope Rules • Generally less complicated to implement • The “current” binding for

Dynamic Scope Rules • Generally less complicated to implement • The “current” binding for a name is the one most recently encountered during execution, and not yet destroyed by returning from its scope • APL, Snobol, early dialects of Lisp, and Perl have dynamic scoping 14

Implications • Semantic rules are dynamic rather than static – Type checking is generally

Implications • Semantic rules are dynamic rather than static – Type checking is generally deferred until run time • To accommodate these rules, dynamically scoped languages are most often interpreted • Very easy for an interpreter to look up the meaning of a name – All that is needed is a stack of declarations • However, it makes it harder to understand programs – The modern consensus seems to be that dynamic scoping is usually a bad idea 15

Dynamic scope example int print_base = 10; print_integer (int n) { switch (print_base) {

Dynamic scope example int print_base = 10; print_integer (int n) { switch (print_base) { case 10: . . . case 8: . . . case 16: . . . case 2: . . . } } foo { print_integer (10); int print_base = 16; print_integer (10); print_base = 2; print_integer (4); } 16

Alternatives to achieve the same result • Overloading and optional parameters – print_integer takes

Alternatives to achieve the same result • Overloading and optional parameters – print_integer takes an optional parameter (one with a default value) that specifies the base – print_integer is overloaded: one form prints in decimal, the other form takes an additional parameter that specifies the base • Better or worse than dynamic scoping? 17

More implications • With dynamic scoping, no program fragment that makes use of non-local

More implications • With dynamic scoping, no program fragment that makes use of non-local names is guaranteed a predictable referencing environment 18

19

19

Referencing Environments • A referencing environment is the complete set of bindings in effect

Referencing Environments • A referencing environment is the complete set of bindings in effect at a given point in a program • Static scope rules: – Referencing environment nesting of program blocks dependent on lexical • Dynamic scope rules: – Referencing environment dependent on the order in which declarations are reached 20

What about references to functions? • When are dynamic scope rules applied? – When

What about references to functions? • When are dynamic scope rules applied? – When the function is called? • Shallow binding – When the reference is created? • Deep binding 21

int max_score; float scale_score (int raw_score) { return (float) raw_score / (float) max_score; }

int max_score; float scale_score (int raw_score) { return (float) raw_score / (float) max_score; } float highest_score (int[] scores, function_ptr scaling_function) { float max_score = 0; foreach score in scores { float percent = scaling_function (score); if ( percent > max_score ) max_score = percent; function is called } return max_score; } main() { reference is created max_score = 50; int[] scores =. . . print highest_score (scores, scale_score); } 22

Deep Binding • Generally the languages default in lexically scoped • Dynamically scoped languages

Deep Binding • Generally the languages default in lexically scoped • Dynamically scoped languages tend to use shallow binding 23

Implementing Deep Binding • Subroutine Closure 24

Implementing Deep Binding • Subroutine Closure 24

The Symbol Table • During compilation, keeps track of all the identifiers • Only

The Symbol Table • During compilation, keeps track of all the identifiers • Only matters in a statically scoped language! – Why? • Basic functions: lookup() and insert() • Must keep track of scope as well – Often by enter_scope() and leave_scope() functions 25

Activation records • When a subroutine starts, a number of things have to be

Activation records • When a subroutine starts, a number of things have to be stored: – – A copy of the parameters (pass by value) The return address when the subroutine exits Local variables in the subroutine Etc. • This data is called the activation record • Fortran (up until 90) only had space for one activation record – Thus, you couldn’t call more than one subroutine at a time 26

Recursive vs. Iterative • Ocaml will recognize tail recursion and convert it to a

Recursive vs. Iterative • Ocaml will recognize tail recursion and convert it to a while loop: let foo x = if x = 0 then 0 else 1 + foo (x-1); ; • A call to foo 1000000 would require one million activation records if called recursively – That’s many, many megs of memory! – In addition to the time spent creating them and branching to the next recursive call of the subroutine • An iterative solution avoids all that – Although there is still the branch for the loop 27

Lifetimes Lifetime = time from creation to deletion • Bindings • Objects 28

Lifetimes Lifetime = time from creation to deletion • Bindings • Objects 28

Storage Management • Static - absolute address, retained throughout program • Stack - LIFO,

Storage Management • Static - absolute address, retained throughout program • Stack - LIFO, subroutine calls • Heap – allocation/deallocation at arbitrary times 29

Heap Management • Free list 30

Heap Management • Free list 30

Who Manages the Heap? • User • System 31

Who Manages the Heap? • User • System 31

Garbage Collection • Mark and Sweep • Reference Counting 32

Garbage Collection • Mark and Sweep • Reference Counting 32

Aliases 33

Aliases 33