1 names, scopes and bindings and bindings. 2 high-level programming languages high-level features...
Post on 21-Dec-2015
222 views
TRANSCRIPT
11
Names, ScopesNames, Scopes
and Bindingsand Bindings
22
High-level programming languagesHigh-level programming languages
High-level features relative to assembly languageHigh-level features relative to assembly language ‘‘Highness’ = degree of abstractionHighness’ = degree of abstraction
machine independencemachine independence efficient implementation does not depend on a specific machine efficient implementation does not depend on a specific machine
instruction setinstruction set relatively easy goalrelatively easy goal
ease of programmingease of programming hard goalhard goal more aesthetics, trial and error than science ?more aesthetics, trial and error than science ?
Programming language designProgramming language design find the right abstractionsfind the right abstractions
33
NameName
Mnemonic character string to represent something elseMnemonic character string to represent something else usually identifiersusually identifiers some languages allow names like ‘+’ & ‘:=‘some languages allow names like ‘+’ & ‘:=‘
Enables programmers to Enables programmers to refer to variables refer to variables etc. etc. using using
symbolic names rather than symbolic names rather than low-level hardware addresseslow-level hardware addresses
abstract their control and data structuresabstract their control and data structures express purpose or function instead of implementationexpress purpose or function instead of implementation make programs manageablemake programs manageable control abstraction: subroutinescontrol abstraction: subroutines data abstraction: classes (for example)data abstraction: classes (for example)
44
Binding & Binding Time...Binding & Binding Time...
BindingBinding an association between a name and the thing that is namedan association between a name and the thing that is named
Binding timeBinding time the time at which an the time at which an implementation decision implementation decision is made to create a is made to create a
bindingbinding Language design timeLanguage design time
the design of specific program constructs (syntax)the design of specific program constructs (syntax) primitive typesprimitive types meaning (semantics)meaning (semantics)
Language implementation timeLanguage implementation time fixation of implementation constants such asfixation of implementation constants such as
numeric precisionnumeric precision run-time memory sizesrun-time memory sizes max identifier name lengthmax identifier name length number and types of built-in exceptions, etc.number and types of built-in exceptions, etc.
55
...Binding times...Binding times
Program writing timeProgram writing time programmer’s choice of algorithms and data structuresprogrammer’s choice of algorithms and data structures
Compile timeCompile time translation of high-level constructs to machine codetranslation of high-level constructs to machine code choice of memory layout for objectschoice of memory layout for objects
Link timeLink time multiple object codes (machine code files) and libraries are multiple object codes (machine code files) and libraries are
combined into one executablecombined into one executable Load timeLoad time
operating system loads the executable in memoryoperating system loads the executable in memory Run timeRun time
program executesprogram executes
66
Nature of bindingsNature of bindings
Static: things bound before executionStatic: things bound before execution Dynamic: execution-time bindingsDynamic: execution-time bindings Early bindingEarly binding
efficiency (e.g. addressing a global variable in C)efficiency (e.g. addressing a global variable in C) languages tend to be compiledlanguages tend to be compiled
Late bindingLate binding flexibility (e.g. polymorphism in Smalltalk)flexibility (e.g. polymorphism in Smalltalk) languages tend to be interpretedlanguages tend to be interpreted
Our current interestOur current interest binding of binding of identifiersidentifiers to to variablesvariables they name they name note: all data has not to be named (note: all data has not to be named (e.g.e.g. dynamic storage) dynamic storage)
77
Things we have to keep track ofThings we have to keep track of
distinguish between names and objects they refer todistinguish between names and objects they refer to creation creation
of objectsof objects of bindingsof bindings
references to variables etc. (which use bindings)references to variables etc. (which use bindings) deactivation and reactivation of bindingsdeactivation and reactivation of bindings destruction destruction
of bindingsof bindings of objectsof objects
If we don’t keep good track of them we getIf we don’t keep good track of them we get garbage: object that outlives it's binding andgarbage: object that outlives it's binding and dangling references: bindings that outlive their objectsdangling references: bindings that outlive their objects
88
LifetimeLifetime
Binding lifetimeBinding lifetime time between the creation and destructiontime between the creation and destruction
Object lifetimeObject lifetime defined similarly, but not necessarily the same defined similarly, but not necessarily the same
as binding lifetimeas binding lifetime e.g. objects passed as reference parameterse.g. objects passed as reference parameters generally corresponds to the generally corresponds to the storage storage
allocation allocation mechanism that is used to mechanism that is used to allocate/deallocate object’s spaceallocate/deallocate object’s space
99
Storage allocationStorage allocation
StaticStatic objects objects have absolute (and same) address through the have absolute (and same) address through the
program executionprogram execution space is ‘part of the program’space is ‘part of the program’
StackStack objects objects allocated/deallocated in LIFO order (usually) in allocated/deallocated in LIFO order (usually) in
conjunction of subroutine calls/exitsconjunction of subroutine calls/exits HeapHeap objects objects
can be allocated/deallocated at arbitrary timescan be allocated/deallocated at arbitrary times storage management more complex than with stackstorage management more complex than with stack
1010
Static objectsStatic objects
Global variablesGlobal variables Translated machine codeTranslated machine code
subroutine locations in particularsubroutine locations in particular ConstantsConstants
large ones in ‘constant pool’large ones in ‘constant pool’ small ones stored as part of instructionssmall ones stored as part of instructions
Subroutine variables that are declared staticSubroutine variables that are declared static Run-time support tables (produced by the compiler)Run-time support tables (produced by the compiler)
symbol table, dynamic type checking, exception handling, garbage symbol table, dynamic type checking, exception handling, garbage collection, ... collection, ...
Note: processor-supported memory protection is possible for Note: processor-supported memory protection is possible for constant dataconstant data
read-only memory (e.g., instructions, constants, tables)read-only memory (e.g., instructions, constants, tables)
1111
Static or non?Static or non?
Local variables in non-recursive languagesLocal variables in non-recursive languages e.g. early Fortrane.g. early Fortran all data (subroutines included) can be allocated all data (subroutines included) can be allocated
staticallystatically pros: faster executionpros: faster execution cons: wastes space, bad programming practicescons: wastes space, bad programming practices
Local constantsLocal constants compile-time constantscompile-time constants can be allocated statically can be allocated statically elaboration-time constants elaboration-time constants must be allocated from must be allocated from
stack stack each invocation may have a different valueeach invocation may have a different value
1212
Other information associated with Other information associated with subroutinessubroutines
Arguments and return valuesArguments and return values compilers try to place these in registers if possiblecompilers try to place these in registers if possible if not, then the stack is usedif not, then the stack is used
Temporary variablesTemporary variables hold intermediate values of complex calculationshold intermediate values of complex calculations registers / stackregisters / stack
Bookkeeping informationBookkeeping information return address (dynamic link)return address (dynamic link) saved registers (of the caller)saved registers (of the caller) ......
1313
1414
Why a stack?Why a stack?
Subroutine call / return is ‘stack-like’Subroutine call / return is ‘stack-like’ stack is the natural data structure to support stack is the natural data structure to support
data allocation & deallocationdata allocation & deallocation Allows recursionAllows recursion
several several instancesinstances of same subroutine can be of same subroutine can be activeactive
Allows re-using spaceAllows re-using space even when no recursion is usedeven when no recursion is used
1515
Maintaining the stackMaintaining the stack
Each subroutine call creates a Each subroutine call creates a stack framestack frame a.k.a a.k.a activation recordactivation record bottom of the frame: arguments and returnsbottom of the frame: arguments and returns
easy access for the callereasy access for the caller always at same offsetalways at same offset
top of the frame: local variables & tempstop of the frame: local variables & temps compiler decides relative orderingcompiler decides relative ordering
Maintenance of stack is done by (see Section 8.2)Maintenance of stack is done by (see Section 8.2) prologue & epilogueprologue & epilogue in the subroutine in the subroutine
saves space to do much heresaves space to do much here calling sequencecalling sequence in the caller in the caller
instructions immediately before/after call/returninstructions immediately before/after call/return may may save time to do much heresave time to do much here interprocedural optimizations possibleinterprocedural optimizations possible
1616
Addressing stack objectsAddressing stack objects
Offsets of variables Offsets of variables withinwithin a frame can be decided at a frame can be decided at compile-timecompile-time
Locations of frames themselves may vary during Locations of frames themselves may vary during executionexecution
Many machines have Many machines have a special a special frame pointer frame pointer register (fp)register (fp) load/store instructions supporting indirect addressing via fpload/store instructions supporting indirect addressing via fp
Address = fp + offset (Fig. 3.2)Address = fp + offset (Fig. 3.2) locals, temps: negative offsetlocals, temps: negative offset arguments, returns: positive offsetarguments, returns: positive offset stack grows ‘downward’ from high addresses to low onesstack grows ‘downward’ from high addresses to low ones push/pop instructions to manipulate both fp and datapush/pop instructions to manipulate both fp and data
1717
1818
Heap-Based allocationHeap-Based allocation Heap is here not a priority queueHeap is here not a priority queue
region of storage to support allocation/deallocation at arbitrary timesregion of storage to support allocation/deallocation at arbitrary times necessity for dynamic data structuresnecessity for dynamic data structures
dynamically allocated pieces of linked data structuresdynamically allocated pieces of linked data structures dynamically resized objects, e.g., fully general character strings, lists, setsdynamically resized objects, e.g., fully general character strings, lists, sets
Many space-management strategiesMany space-management strategies a part of your data structures course?a part of your data structures course? space & speed concerns; tradeoffsspace & speed concerns; tradeoffs space: internal & external space: internal & external fragmentationfragmentation
InternalInternal allocation of a block larger than requiredallocation of a block larger than required happens because of standard-sized blockshappens because of standard-sized blocks
ExternalExternal blocks are scattered around the heapblocks are scattered around the heap lot of free space but in small pieceslot of free space but in small pieces
1919
Maintain all unallocated blocks in one listMaintain all unallocated blocks in one list a.k.a a.k.a free listfree list at each allocation request, look for a block of appropriate sizeat each allocation request, look for a block of appropriate size
StrategiesStrategies First-fit: return first large enoughFirst-fit: return first large enough Best-fit: return smallest block large enoughBest-fit: return smallest block large enough Neither is better than other (depends on requests)Neither is better than other (depends on requests)
Both cases:Both cases: if the block found is much larger than the request, split it in 2 and if the block found is much larger than the request, split it in 2 and
return the other half to free listreturn the other half to free list DeallocationDeallocation
add to free list and merge with adjacent regions if possibleadd to free list and merge with adjacent regions if possible
2020
Reducing allocation timeReducing allocation time
Scanning the free list Scanning the free list takes linear time in the # of free blockstakes linear time in the # of free blocks maintain separate lists for different (standard) sizesmaintain separate lists for different (standard) sizes
Fast allocationFast allocation find appropriate size (constant time)find appropriate size (constant time) return the first block (constant time)return the first block (constant time)
Buddy systems & Fibonacci heapsBuddy systems & Fibonacci heaps block sizes powers of 2 or Fibo numbersblock sizes powers of 2 or Fibo numbers
2121
Garbage collectionGarbage collection
External fragmentation can not be avoidedExternal fragmentation can not be avoided ‘‘checkerboard’ the heapcheckerboard’ the heap we end up with a situation wherewe end up with a situation where
we have a lot of free spacewe have a lot of free space but no blocks large enoughbut no blocks large enough heap must be compacted by moving the heap must be compacted by moving the
allocated blocksallocated blocks complicated because all the references to these complicated because all the references to these
blocks must be updated, too!blocks must be updated, too!
2222
Explicit and implicit deallocationExplicit and implicit deallocation
Allocation is always triggered by some program Allocation is always triggered by some program actionaction
Deallocation can be eitherDeallocation can be either explicitexplicit
Pascal, CPascal, C simple, efficient, immediatesimple, efficient, immediate allows ‘hand-tailored’ storage managementallows ‘hand-tailored’ storage management
or implicit or implicit Java, C++, functional languagesJava, C++, functional languages garbage collector starts whenever space gets lowgarbage collector starts whenever space gets low complex, time-consumingcomplex, time-consuming
2323
GC or not to GC?GC or not to GC?
Explicit memory management is more efficientExplicit memory management is more efficient ButBut
manual deallocation errors are among the most common and manual deallocation errors are among the most common and costly bugscostly bugs
too soon deallocation too soon deallocation dangling references dangling references forgotten deallocation forgotten deallocation memory leaks memory leaks
Automatic GC is considered an essential feature of Automatic GC is considered an essential feature of modern languagesmodern languages GC algorithms have improvedGC algorithms have improved implementations are more complex in general (so adding GC implementations are more complex in general (so adding GC
plays not a big role)plays not a big role) large applications make benefits of GC greaterlarge applications make benefits of GC greater
2424
ScopeScope
Scope (of a binding)Scope (of a binding) the (textual) part of the program where the binding is the (textual) part of the program where the binding is
activeactive Scope (in general) is aScope (in general) is a
program section of maximal size in which program section of maximal size in which no bindings change or at leastno bindings change or at least no re-declarations are permittedno re-declarations are permitted
Lifetime and scope are not necessarily the sameLifetime and scope are not necessarily the same
2525
ElaborationElaboration Subroutine entrance Subroutine entrance new scope new scope opensopens
create bindings for new local variablescreate bindings for new local variables deactivate bindings for global variables that are redeclareddeactivate bindings for global variables that are redeclared
Subroutine exit Subroutine exit scope closes scope closes destroy bindings for local variablesdestroy bindings for local variables reactivate bindings for global variables that were deactivatedreactivate bindings for global variables that were deactivated
ElaborationElaboration process of creating bindings when entering a new scopeprocess of creating bindings when entering a new scope also other tasks, for example in Ada:also other tasks, for example in Ada:
storage allocationstorage allocation starting tasks (processes)starting tasks (processes) propagating exceptionspropagating exceptions
2626
Scope rulesScope rules
Referencing environmentReferencing environment of a statement of a statement the set of active bindingsthe set of active bindings corresponds to a collection of scopes that are examined (in corresponds to a collection of scopes that are examined (in
order) to find a bindingorder) to find a binding Scope rulesScope rules
determine that collection and its orderdetermine that collection and its order Static (lexical) scope rulesStatic (lexical) scope rules
scope is defined in terms of the physical (lexical) structure of the scope is defined in terms of the physical (lexical) structure of the programprogram
typically the most recent (active) binding is chosentypically the most recent (active) binding is chosen we study mostly (and first) these herewe study mostly (and first) these here
Dynamic scope rulesDynamic scope rules bindings depend on the current state of program executionbindings depend on the current state of program execution
2727
Static scopeStatic scope
Related to program structureRelated to program structure Basic: one scope (static & global)Basic: one scope (static & global) Fortran: global & local scopesFortran: global & local scopes
COMMON blocksCOMMON blocks aim: share global data in separately compiled subroutinesaim: share global data in separately compiled subroutines typing errors possibletyping errors possible
EQUIVALENCE of variablesEQUIVALENCE of variables aim: share (and save) spaceaim: share (and save) space predecessor of variant/union typespredecessor of variant/union types
lifetime of a local variable?lifetime of a local variable? semantically: execution of the subroutinesemantically: execution of the subroutine possible to SAVE variables (static allocation)possible to SAVE variables (static allocation) in practice in practice all all variables variables maymay behave as if SAVEd behave as if SAVEd bad programming bad programming
2828
Nested program structureNested program structure
Subroutines within subroutines within ... Subroutines within subroutines within ... scopes within scopes within ...scopes within scopes within ... thing X declared inside a subroutine thing X declared inside a subroutine thing X is thing X is notnot
visible outside that subroutinevisible outside that subroutine Algol 60, Pascal, Ada, ...Algol 60, Pascal, Ada, ...
Resolving bindingsResolving bindings closest nested scope ruleclosest nested scope rule subsequent declarations may subsequent declarations may hidehide surrounding ones surrounding ones
(temporarily)(temporarily) built-in/predefined bindings: special outmost scopebuilt-in/predefined bindings: special outmost scope
Example in Figure 3.4Example in Figure 3.4
2929
Non-local referencesNon-local references
Nested subroutine may refer to objects declared in other Nested subroutine may refer to objects declared in other subroutines (surrounding it)subroutines (surrounding it) example 3.4: P3 can access A1, X and A2example 3.4: P3 can access A1, X and A2 how to access these objects (they are in other stack frames)?how to access these objects (they are in other stack frames)? need to find the corresponding frame at run-timeneed to find the corresponding frame at run-time
DifficultyDifficulty deeply nested routine (like P3) can call any visible routine (P1)deeply nested routine (like P3) can call any visible routine (P1) caller’s scope is caller’s scope is notnot (always) the lexically surrounding scope (always) the lexically surrounding scope however, that surrounding scope however, that surrounding scope mustmust have a stack frame have a stack frame
somewhere below in the stacksomewhere below in the stack we can get to P3 only by making it visible firstwe can get to P3 only by making it visible first P3 gets visible after P1 & P2 have been calledP3 gets visible after P1 & P2 have been called
3030
3131
Accessing non-local stack objectsAccessing non-local stack objects
Parent frameParent frame most recent invocation of the lexically surrounding subroutinemost recent invocation of the lexically surrounding subroutine
Augment stack frame with Augment stack frame with static linkstatic link pointer to parent framepointer to parent frame outermost frame: parent = niloutermost frame: parent = nil links form a links form a static chain static chain through all scopesthrough all scopes
AccessingAccessing routine at nesting depth k refers to an object at depth jroutine at nesting depth k refers to an object at depth j follow k - j static links (k - j is known at compile-time)follow k - j static links (k - j is known at compile-time) use offset in that ancestor frame as usualuse offset in that ancestor frame as usual
Figure 3.5Figure 3.5
3232
3333
Holes in scopesHoles in scopes
Name-object binding N-O1Name-object binding N-O1 hidden by a nested declaration N-O2hidden by a nested declaration N-O2 has a has a hole hole in it’s scope (for the lifetime of that in it’s scope (for the lifetime of that
nested declaration)nested declaration) object O1 is inaccessible via Nobject O1 is inaccessible via N
Scope resolution operatorsScope resolution operators allow programmer to explicitly use ‘hidden’ allow programmer to explicitly use ‘hidden’
bindingsbindings a.k.a a.k.a qualifiersqualifiers Ada: Ada: My_Proc.X My_Proc.X ((X X declared in declared in My_ProcMy_Proc)) C++: C++: ::X::X (global X) (global X)
3434
Scopes without subroutinesScopes without subroutines Variable definitions in block statementsVariable definitions in block statements
either at the beginning of the block oreither at the beginning of the block or Algol, C, AdaAlgol, C, Ada{{
int temp = a;int temp = a;a = b;a = b;b = temp;b = temp;
}} anywhere where a statement may appearanywhere where a statement may appear
C++, JavaC++, Java scope extends to the end of the current blockscope extends to the end of the current block
space allocated from the stack framespace allocated from the stack frame no extra runtime operations neededno extra runtime operations needed space saved by letting allocations overlap each otherspace saved by letting allocations overlap each other
3535
Re-declaring bindingsRe-declaring bindings
Change bindings ‘on the fly’Change bindings ‘on the fly’ e.g. to fix bugs (rapid prototyping)e.g. to fix bugs (rapid prototyping) interactive languagesinteractive languages
New meaning replaces the old one immediately New meaning replaces the old one immediately everywhereeverywhere implemented using some search structure (name implemented using some search structure (name
meaning)meaning) Problems with ‘half-compiled’ languages (ML)Problems with ‘half-compiled’ languages (ML)
old (compiled) bindings may be preserved old (compiled) bindings may be preserved in subroutines that are already elaborated (using the in subroutines that are already elaborated (using the
old binding)old binding)
3636
ModulesModules
Great tool to divide programming effortGreat tool to divide programming effort information hidinginformation hiding
details are visible only to parts that really need themdetails are visible only to parts that really need them reduces the ‘cognitive load’ of programmersreduces the ‘cognitive load’ of programmers
minimize the amount of information required to understand any part minimize the amount of information required to understand any part of the systemof the system
changes & updates localized within single moduleschanges & updates localized within single modules Other benefitsOther benefits
reduces name clashesreduces name clashes data integrity: only routines inside a module update certain data integrity: only routines inside a module update certain
objectobject errors are localizederrors are localized
3737
Information hiding using Information hiding using subroutines?subroutines?
Hiding is limited to objects defined Hiding is limited to objects defined inside a routineinside a routine lifetime = execution of the routinelifetime = execution of the routine
Partial solution: use static local Partial solution: use static local objectsobjects C: C: staticstatic, Algol: , Algol: ownown, ..., ... Example: Figure 3.6Example: Figure 3.6 ‘‘subroutines with memory’subroutines with memory’ ‘‘single-routine data abstractions’single-routine data abstractions’
3838
3939
Module: multiple-routine abstractionModule: multiple-routine abstraction
Combine and hide several routines & data Combine and hide several routines & data structuresstructures e.g. stack type, push and pop operationse.g. stack type, push and pop operations Ada: package, Clu: cluster, Modula-2: moduleAda: package, Clu: cluster, Modula-2: module objects inside a module areobjects inside a module are
visible to each othervisible to each other not not visible to the outside visible to the outside unlessunless explicitly explicitly exportedexported
objects outside a module areobjects outside a module are not not visible to the inside visible to the inside unlessunless explicitly explicitly importedimported
Example: Figure 3.7Example: Figure 3.7
4040
4141
Modules and bindingsModules and bindings
Bindings made inside a moduleBindings made inside a module are inactive outside of itare inactive outside of it but but not not destroyeddestroyed module-level objects have ‘same lifetime they would have module-level objects have ‘same lifetime they would have
without the enclosing module’without the enclosing module’ same as the scope they appear insame as the scope they appear in
Restrictions on export declarationsRestrictions on export declarations possible in many module-based languagespossible in many module-based languages variables exported read-onlyvariables exported read-only types exported as opaque (Modula-2)types exported as opaque (Modula-2)
variables of the type may be declared, passed as arguments to the variables of the type may be declared, passed as arguments to the module’s subroutines, possibly compared or assigned to each othermodule’s subroutines, possibly compared or assigned to each other
4242
Headers and bodiesHeaders and bodies
Modules are often divided intoModules are often divided into header/declaration partheader/declaration part
definitions for users of the moduledefinitions for users of the module the the public public interface of the moduleinterface of the module may also contain private information (for compilation)may also contain private information (for compilation)
body/implementation partbody/implementation part definitions for the implementation of the moduledefinitions for the implementation of the module
Header and body parts can be compiled separatelyHeader and body parts can be compiled separately especially header can be compiled even if body does not exist especially header can be compiled even if body does not exist
(yet)(yet) and so can the users of the headerand so can the users of the header total recompilation unnecessary if only some modules are total recompilation unnecessary if only some modules are
updatedupdated
4343
Open and closed scopesOpen and closed scopes
Open scopeOpen scope no imports required (scope rules apply)no imports required (scope rules apply) Ada packages, nested subroutines in most Algol family Ada packages, nested subroutines in most Algol family
languageslanguages Closed scopeClosed scope
all names must be explicitly importedall names must be explicitly imported Modula-2 modules, Euclid subroutinesModula-2 modules, Euclid subroutines Clu: nonlocal references not possibleClu: nonlocal references not possible import lists import lists
document the program (nonlocal references are part of the document the program (nonlocal references are part of the interface)interface)
help the compiler to detect help the compiler to detect aliasingaliasing (Euclid, Turing) (Euclid, Turing)
4444
AliasingAliasing
AliasAlias extra name for something that already has a name (in the extra name for something that already has a name (in the
current scope)current scope) we may have severalwe may have several
How are they created?How are they created? Fortran: explicit declarations (equivalence)Fortran: explicit declarations (equivalence) variant/union structuresvariant/union structures languages using pointerslanguages using pointers reference parametersreference parameters
They are considered bad becauseThey are considered bad because they create confusion and hard-to-track errors (Fig. 3.8)they create confusion and hard-to-track errors (Fig. 3.8) compilers can optimize much better if they know there’s no compilers can optimize much better if they know there’s no
aliasingaliasing
4545
4646
Type manager modulesType manager modules
Modules support ‘naturally’ only the creation of Modules support ‘naturally’ only the creation of one single instance of a given abstractionone single instance of a given abstraction Figure 3.7 creates only one stackFigure 3.7 creates only one stack replicate code?replicate code?
Alternative organizationAlternative organization module is a module is a manager manager for the instances of the type it for the instances of the type it
implements (Fig. 3.9)implements (Fig. 3.9) additional routines to create/destroy instancesadditional routines to create/destroy instances additional parameter to each operation (the object in additional parameter to each operation (the object in
question)question) Clu: every module is a manager of some typeClu: every module is a manager of some type
4747
4848
Module typesModule types
Each module creates a new typeEach module creates a new type possible to declare (any number of) variables of that typepossible to declare (any number of) variables of that type Euclid, Simula, CluEuclid, Simula, Clu AutomaticAutomatic
initialization code andinitialization code and finalization code (e.g. to return objects to heap)finalization code (e.g. to return objects to heap)
Types and their operations are tightly bound to each Types and their operations are tightly bound to each otherother operations ‘belong’ to objects of the module typeoperations ‘belong’ to objects of the module type conceptuallyconceptually
type approach has a separate push for every stacktype approach has a separate push for every stack manager approach has one parameterized push for all stacksmanager approach has one parameterized push for all stacks
same implementation in practicesame implementation in practice
4949
5050
ClassesClasses
Object-oriented programmingObject-oriented programming Module types augmented with Module types augmented with inheritance inheritance
mechanismmechanism possible to define new modules ‘on top’ of possible to define new modules ‘on top’ of
existing ones (refinements, extensions)existing ones (refinements, extensions) objects inherit operations of other objects (no objects inherit operations of other objects (no
need to rewrite the code)need to rewrite the code)
5151
Module types and scopesModule types and scopes
Note: applies also to classes if we forget inheritanceNote: applies also to classes if we forget inheritance Every instance A of a module type hasEvery instance A of a module type has
a separate copy of the module variablesa separate copy of the module variableswhich are visible when executing one of A’s operationswhich are visible when executing one of A’s operations
Indirect visibility (within same type)Indirect visibility (within same type) the the instance variablesinstance variables of B may be visible of B may be visible
to another instance A of the same typeto another instance A of the same typeif B is passed as a parameter of A’s operationif B is passed as a parameter of A’s operation
binary operations of C++binary operations of C++ opinions vary whether this is a good thing or notopinions vary whether this is a good thing or not
5252
… … ClassesClasses
an extension of module typean extension of module type inheritance: new classes extensions or refinements of inheritance: new classes extensions or refinements of
existingexisting operations belonging to objects, new objects can inherit operations belonging to objects, new objects can inherit
operationsoperations example C++example C++
class stack {class stack {……
bool deeper ( stack other ) { // function declarationbool deeper ( stack other ) { // function declarationreturn ( top > other.top ) ;return ( top > other.top ) ;
}}……}}……if ( A.deeper(B)) …if ( A.deeper(B)) …
in object-oriented langauagesin object-oriented langauagesroots in Simula-67, Smalltalk, Eiffel, C++, Javaroots in Simula-67, Smalltalk, Eiffel, C++, Java
in non-object orientedin non-object orientedModula-3, Ada 95, OberonModula-3, Ada 95, Oberon
5353
Dynamic scope...Dynamic scope...
Name-object binding decided at run-timeName-object binding decided at run-time usually the last active declarationusually the last active declaration thus, derived from the order in which subroutines are thus, derived from the order in which subroutines are
called (Fig. 3.10)called (Fig. 3.10) flow of control is unpredictable flow of control is unpredictable compilation compilation
impossibleimpossible Example languagesExample languages
early functional languages (Lisp)early functional languages (Lisp) Perl (v5.0 gives also static scope)Perl (v5.0 gives also static scope) environment variables in command shellsenvironment variables in command shells
5454
...Dynamic scope...Dynamic scope
Dynamic scope Dynamic scope dynamic semantics dynamic semantics type checking in expressions and parameter passing type checking in expressions and parameter passing
must be deferred to run-timemust be deferred to run-time Simple implementationSimple implementation
maintain declarations in a stackmaintain declarations in a stack search stack top search stack top bottom to find bindings bottom to find bindings push/pop bindings when entering/leaving subroutinespush/pop bindings when entering/leaving subroutines quite slowquite slow
5555
5656
Dynamic scope is a bad idea?Dynamic scope is a bad idea? ConsCons
High run-time costsHigh run-time costs Non-local references are ‘unpredictable’Non-local references are ‘unpredictable’ Dynamic programs are hard to understandDynamic programs are hard to understand
5757
ProsPros Easy to customize subroutines ‘on the fly’Easy to customize subroutines ‘on the fly’ book examplebook example
print integers in different basesprint integers in different bases base = non-local (dynamic) referencebase = non-local (dynamic) reference
1.1. begin -- nested blockbegin -- nested block
print_base : integer := 16 -- use hexadecimalprint_base : integer := 16 -- use hexadecimal
print_integer (n)print_integer (n)
2.2. begin -- nested blockbegin -- nested block
print_base_save : integer := print_baseprint_base_save : integer := print_base
print_base := 16 -- use hexadecimalprint_base := 16 -- use hexadecimal
print_integer (n)print_integer (n)
print_base := print_base_saveprint_base := print_base_save
5858
Simulating dynamic scopeSimulating dynamic scope
Workaround 1Workaround 1 make separate routines for separate casesmake separate routines for separate cases default parameters (Ada) default parameters (Ada) one interface one interface overloading (C++) overloading (C++) same name same name but: calls made under the emulated ‘dynamic scope’ but: calls made under the emulated ‘dynamic scope’
do not ‘inherit’ the mimicked non-local bindingdo not ‘inherit’ the mimicked non-local binding Workaround 2Workaround 2
use a global/static variable instead of a non-local use a global/static variable instead of a non-local referencereference
store/restore before/after use of the routinestore/restore before/after use of the routine
5959
Symbol tablesSymbol tables a data abstraction used in statically scoped programsa data abstraction used in statically scoped programs maps names into the information the compiler knows maps names into the information the compiler knows
about themabout them insert – to place a new mapping (name to object insert – to place a new mapping (name to object
binding)binding) lookup – to retrieve nondestructively the information lookup – to retrieve nondestructively the information
on a given nameon a given name insert when entering a scope, remove when leaving a insert when entering a scope, remove when leaving a
scope, impracticalscope, impractical inner declarations may hide outer, so arbitrary number of inner declarations may hide outer, so arbitrary number of
mapping for a name neededmapping for a name needed records, nested, but fields become suddenly visible or records, nested, but fields become suddenly visible or
invisibleinvisible names used before declarednames used before declared
Algol 60, 68, forward references to labelsAlgol 60, 68, forward references to labelsPascal and other, forward declarations of subroutines, support Pascal and other, forward declarations of subroutines, support
mutual recursionmutual recursion
6060
symbolic debugger has access to the table, the symbolic debugger has access to the table, the table saved completellytable saved completelly
enter_scope and leave_scope to keep track of enter_scope and leave_scope to keep track of visibilityvisibility
Le Blanc - CookLe Blanc - Cook scopes are given successive numbers (0, 1, ...) as they scopes are given successive numbers (0, 1, ...) as they
are encounteredare encountered names into a single hash tablenames into a single hash table entries are the symbol name, category (variable, entries are the symbol name, category (variable,
constant, type, procedure, field name, parameter, ...), constant, type, procedure, field name, parameter, ...), scope number, type (a pointer to another symbol table scope number, type (a pointer to another symbol table entry), for imports/exports pointers to the real entries ...entry), for imports/exports pointers to the real entries ...
scope stackscope stack indicates, in order, the scopes that comprise the current indicates, in order, the scopes that comprise the current
referencing environmentreferencing environment entries contain the scope number, closed/opened, ...entries contain the scope number, closed/opened, ...
6161
6262
6363
Association lists and central Association lists and central reference tablesreference tables
in languages with dynamic scopingin languages with dynamic scoping association lists (A-lists)association lists (A-lists)
simple, ellegant, can be very inefficientsimple, ellegant, can be very inefficient functions as a stackfunctions as a stack
when execution enters a scope, bindings for names when execution enters a scope, bindings for names declared in the scope are pushed on the frontdeclared in the scope are pushed on the frontwhen execution leaves the scope, the bindings are when execution leaves the scope, the bindings are removedremoved
for a meaning of a name the list is searched from the for a meaning of a name the list is searched from the frontfront
each entry contains all data needed for semantic checkeach entry contains all data needed for semantic check problem: it may take a long time to find an entryproblem: it may take a long time to find an entry
6464
central reference tablescentral reference tables resemble Le Blank and Cook table, without the resemble Le Blank and Cook table, without the
scope stack, more work on scope entry and scope stack, more work on scope entry and exit, lookup much fasterexit, lookup much faster
a list (stack) of entries for each distinct name a list (stack) of entries for each distinct name in the program, most recent on the beginningin the program, most recent on the beginningwhen control enters a new scope, a new entry when control enters a new scope, a new entry is pushed on the beginning of the list for every is pushed on the beginning of the list for every (re)declared name(re)declared namewhen control leaves he scope, these entries when control leaves he scope, these entries are poppedare popped
more expensive, lookup much fastermore expensive, lookup much faster the space can be reclaimedthe space can be reclaimed
deep and shallow binding/access/searchdeep and shallow binding/access/search
6565
6666
Binding of referencing Binding of referencing environmentsenvironments
WHEN scope rules should be applied?WHEN scope rules should be applied? usually no problem (just apply scope rules)usually no problem (just apply scope rules) problematic case: references to subroutinesproblematic case: references to subroutines
e.g. function parameterse.g. function parameters these may have non-local references, too!these may have non-local references, too!
when the reference was created?when the reference was created? when the referred routine is (finally) used?when the referred routine is (finally) used?
In other wordsIn other words WHAT is the referencing environment of a subroutine WHAT is the referencing environment of a subroutine
reference?reference?
6767
6868
Shallow & deep bindingShallow & deep binding
Consider example of Fig. 3.16 (dynamic scoping)Consider example of Fig. 3.16 (dynamic scoping) print_routineprint_routine
should create its environment just before it’s usedshould create its environment just before it’s usedotherwise the ‘format trick’ would not workotherwise the ‘format trick’ would not work
this late binding is called this late binding is called shallow bindingshallow binding default in dynamically scoped languagesdefault in dynamically scoped languages
older_thanolder_than is designed to use the global is designed to use the global threshold threshold variablevariable
i.e. it is meant to be used in that one and only i.e. it is meant to be used in that one and only environmentenvironment
referencing environmentreferencing environmentshould be bound when should be bound when older_than older_than is passed as a parameteris passed as a parameterand used when it is finally calledand used when it is finally called
this early binding is called this early binding is called deep bindingdeep binding
6969
Implementing deep bindingImplementing deep binding
Subroutine Subroutine closureclosure bundles together bundles together pointer to subroutine code and it’spointer to subroutine code and it’s referencing environmentreferencing environment
Dynamic scoping Dynamic scoping environment implemented as a binding stackenvironment implemented as a binding stack
book calls this an book calls this an association list association list current top of stack defines the environmentcurrent top of stack defines the environment
when a routine is passed as a parameterwhen a routine is passed as a parameter save current top of the stack in the closure & pass closuresave current top of the stack in the closure & pass closure
when the referenced routine is calledwhen the referenced routine is called use saved pointer as the top of stackuse saved pointer as the top of stack if other functions are called, grow another ‘top’ for the stack from if other functions are called, grow another ‘top’ for the stack from
this point (list-implemented stack)this point (list-implemented stack)
7070
Deep binding & static scopeDeep binding & static scope
Deep binding is default in static scopeDeep binding is default in static scope shallow binding does not make much senseshallow binding does not make much sense
Does the binding time matter at all?Does the binding time matter at all? generally notgenerally not
name name lexical nesting lexical nesting nesting does not changenesting does not change
recursion!recursion! we must find the correct we must find the correct instanceinstance, too, too closure must capture the closure must capture the currentcurrent instance of every visible instance of every visible
object when it is createdobject when it is created this saved closure is then used when routines are usedthis saved closure is then used when routines are used example in Fig. 3.17example in Fig. 3.17
7171
7272
Some notesSome notes
Binding rules matter (with static scoping) Binding rules matter (with static scoping) onlyonly when referencing objects that are when referencing objects that are not not local local neitherneither
globalglobal irrelevant in irrelevant in
C: no nested structureC: no nested structure Modula-2: only top-level routines can be passed as Modula-2: only top-level routines can be passed as
parametersparameters and in all languages that do not permit passing subroutines and in all languages that do not permit passing subroutines
as argumentsas arguments
7373
Implementing deep bindingImplementing deep binding
Static links define referencing Static links define referencing environmentsenvironments pass: create closure with current static linkpass: create closure with current static link call: use the saved static link (instead of call: use the saved static link (instead of
creating a new one) when creating the frame creating a new one) when creating the frame recordrecord
static chain is now the same as at the time the static chain is now the same as at the time the parameter was passedparameter was passed
7474
Classes of objects (values)Classes of objects (values)
First-class objects can beFirst-class objects can be passed as parameterspassed as parameters returned from a subroutinereturned from a subroutine assigned to variablesassigned to variables e.g. integers in most languagese.g. integers in most languages
Second-class objectsSecond-class objects can only be passed as parameters, not returned from a can only be passed as parameters, not returned from a
subroutine, neither assigned into a variablesubroutine, neither assigned into a variable e.g. subroutines in most languages, arrays in C/C++e.g. subroutines in most languages, arrays in C/C++
Third-class objectsThird-class objects can not even be passed as a parametercan not even be passed as a parameter e.g. jump labels (in most languages that have a goto-statement)e.g. jump labels (in most languages that have a goto-statement)
7575
Subroutines & classesSubroutines & classes
First-classFirst-class functional languagesfunctional languages
note: these can even note: these can even create create new subroutinesnew subroutines Modula-2 & -3, Ada 95, C, C++Modula-2 & -3, Ada 95, C, C++
language-specific restrictions on uselanguage-specific restrictions on use
Second-classSecond-class almost all other languagesalmost all other languages Ada 83: third-classAda 83: third-class
7676
Problem with first-class Problem with first-class subroutines...subroutines...
Reference to a subroutineReference to a subroutine may live may live longerlonger than the scope that created it than the scope that created it referencing environment no longer exists when the referencing environment no longer exists when the
routine is calledroutine is called Functional languagesFunctional languages
unlimited extentunlimited extent of local objects of local objects frames are allocated from the heap (not stack)frames are allocated from the heap (not stack) garbage collected when no references remaingarbage collected when no references remain
7777
...Problem with first-class ...Problem with first-class subroutinessubroutines
Imperative languages Imperative languages wantwant to use the stack to use the stack limited extentlimited extent of local objects of local objects frames are deleted from the stack when execution leaves the subroutine frames are deleted from the stack when execution leaves the subroutine
dangling references if 1dangling references if 1stst class subroutines class subroutines Algol-family languages have different workaroundsAlgol-family languages have different workarounds
Modula-2: only top-level subroutines can be referenced toModula-2: only top-level subroutines can be referenced to Modula-3Modula-3
only top-level subroutines are 1only top-level subroutines are 1stst class, others are 2 class, others are 2ndnd class class Ada 95Ada 95
a nested routine can be returned (by a function) only to a scope that contains a nested routine can be returned (by a function) only to a scope that contains that routinethat routine
referencing environment will always be alivereferencing environment will always be alive C/C++: no problem (because they have no nested scopes)C/C++: no problem (because they have no nested scopes)
7878
OverloadingOverloading
Aliasing: multiple names for the same objectAliasing: multiple names for the same object Overloading: one name for several objectsOverloading: one name for several objects
in the same scopein the same scope semantic rules: context of the name must give enough semantic rules: context of the name must give enough
information to resolve the bindinginformation to resolve the binding most programming languages support at least some most programming languages support at least some
overloading (arithmetic operations)overloading (arithmetic operations) in symbol table lookup finds all possible entries with in symbol table lookup finds all possible entries with
the name and semantic analyzer choosesthe name and semantic analyzer chooses
7979
Overloading of ...Overloading of ...
Enumeration constantsEnumeration constants Ada example in Figure 3.18Ada example in Figure 3.18
dec & oct overloadeddec & oct overloaded print has not sufficient context print has not sufficient context explicit qualification required explicit qualification required
((print (month’(oct));print (month’(oct));)) Modula-3: each occurrence must be qualified (Modula-3: each occurrence must be qualified (month.decmonth.dec)) C, C++, Pascal: this kind of overloading is not allowedC, C++, Pascal: this kind of overloading is not allowed
SubroutinesSubroutines Ada, C++Ada, C++
arbitrary number as long as parameter types/number are differentarbitrary number as long as parameter types/number are different also arithmetic operators (syntactic sugar)also arithmetic operators (syntactic sugar)
Figure 3.19Figure 3.19
8080
8181
8282
Overloading is NOT coercionOverloading is NOT coercion CoercionCoercion
process in which the compiler process in which the compiler automaticallyautomatically converts an object X:T1 to another type T2converts an object X:T1 to another type T2 when X is used in a context where T2 is expectedwhen X is used in a context where T2 is expected
In overloadingIn overloading separate functions are selected by the compiler for different usesseparate functions are selected by the compiler for different uses
ADA:ADA:function abs (n : integer) return integer is ...function abs (n : integer) return integer is ...function abs (x : real) return real is ...function abs (x : real) return real is ...
In coercionIn coercion there is only one functionthere is only one function compiler makes the necessary type transformationscompiler makes the necessary type transformations
FORTRAN:FORTRAN:real function abs (x)real function abs (x)real xreal x......
C, C++, in Ada only explicit constants, subranges and C, C++, in Ada only explicit constants, subranges and sometimes arrayssometimes arrays
8383
Overloading is NOT polymorphismOverloading is NOT polymorphism
PolymorphismPolymorphism polymorphic objects may represent objects of polymorphic objects may represent objects of
more than one typemore than one type subroutines can manipulate the polymorphic subroutines can manipulate the polymorphic
parameters without any conversionsparameters without any conversions either all objects have some common either all objects have some common
characteristics (and only these are used)characteristics (and only these are used) or objects contain other information so the or objects contain other information so the
subroutine can customize itself appropriatelysubroutine can customize itself appropriately
8484
Examples of polymorphismExamples of polymorphism
abs(x) for any type that supportsabs(x) for any type that supports comparison ‘> 0’ andcomparison ‘> 0’ and negationnegation
counting the length of a list (of any type)counting the length of a list (of any type) only succ & empty –tests requiredonly succ & empty –tests required
Lisp, Scheme, SmalltalkLisp, Scheme, Smalltalk to a more limited extent in C++, Javato a more limited extent in C++, Java conformant array parametersconformant array parameters
very limited form of polymorphism (Pascal, Ada)very limited form of polymorphism (Pascal, Ada)
8585
Overloading is NOT genericsOverloading is NOT generics
Generic subroutines (or modules)Generic subroutines (or modules) parameterizedparameterized templates templates that can be that can be instantiatedinstantiated to create to create
concreteconcrete subroutines subroutines early C++ versions used cpp to do thisearly C++ versions used cpp to do this
Ada example in Fig. 3.20Ada example in Fig. 3.20 Generics is not polymorphismGenerics is not polymorphism
polymorphic routine is a polymorphic routine is a singlesingle object capable of accepting object capable of accepting multiple typesmultiple types
compiled to a single body of codecompiled to a single body of code generic routines are instantiated to create an own concrete generic routines are instantiated to create an own concrete
routine for each different useroutine for each different use compiled to several copies of the codecompiled to several copies of the code Ada allows these instance names to be overloadedAda allows these instance names to be overloaded C++ requires them to do soC++ requires them to do so
8686
8787
Naming-related pitfalls...Naming-related pitfalls... Redefinition of function name inside the functionRedefinition of function name inside the function
recursion impossiblerecursion impossible Pascal: function name is used to define the return Pascal: function name is used to define the return
value value strange problemsstrange problemsfunction foo : integerfunction foo : integer
......type foo = ...type foo = .........begin (* foo *)begin (* foo *)
......foo := 10; (*static semantic error! *)foo := 10; (*static semantic error! *)
most current languages use return-statement or some most current languages use return-statement or some special pseudo-variable for return valuesspecial pseudo-variable for return values
8888
Scope of a name Scope of a name entireentire block it is declared in (Pascal) block it is declared in (Pascal)
names must be declared before they are usednames must be declared before they are used strange consequences when names refer to each otherstrange consequences when names refer to each other do we use ‘external’ or ‘internal’ name?do we use ‘external’ or ‘internal’ name?const missing = -1;const missing = -1;......procedure foo;procedure foo;constconst
null = missing; (* static semantic error! *)null = missing; (* static semantic error! *)......
missing = 0;missing = 0;
or from the declaration to the end of the block? (Ada)or from the declaration to the end of the block? (Ada) or either to the end of the block or next re-definition or either to the end of the block or next re-definition
(ML)(ML)
8989
...Naming-related pitfalls...Naming-related pitfalls Recursive data typesRecursive data types
need to reference to the not-yet-defined typeneed to reference to the not-yet-defined type Pascal: pointers are an exception to the general Pascal: pointers are an exception to the general
‘declare before use’ rule‘declare before use’ rule pointer declaration makes a pointer declaration makes a forward referenceforward referencetypetype
Alink = ^A;Alink = ^A;A = recordA = record
next : Alink;next : Alink;data : ...data : ...
C, C++, AdaC, C++, Ada forward references are forbidden but forward references are forbidden but incomplete incomplete type type
definitions are alloweddefinitions are allowedtype A;type A;type Alink is access A;type Alink is access A;type A is recordtype A is record ADAADA
next : Alink;next : Alink;data : ...data : ...
9090
Mutually recursive subroutinesMutually recursive subroutines need to reference to a not-yet-defined subroutineneed to reference to a not-yet-defined subroutine Pascal: forward declarationsPascal: forward declarations
Modula-3: order of declarations does not matterModula-3: order of declarations does not matter Java, C++Java, C++
variables ‘declared before used’variables ‘declared before used’ classes can be used before they are (totally) declaredclasses can be used before they are (totally) declared order of routines does not matter (inside a class)order of routines does not matter (inside a class)