advanced programming names, scopes and bindings. binding time the binding of a program element to a...
Post on 22-Dec-2015
232 views
TRANSCRIPT
Advanced ProgrammingAdvanced Programming
Names, Scopes and BindingsNames, Scopes and Bindings
Binding TimeBinding Time
The The bindingbinding of a program element to a particular of a program element to a particular property is the choice of the property from a set property is the choice of the property from a set of possible propertiesof possible properties
The time during program formulation or The time during program formulation or processing when this choice is made is the processing when this choice is made is the binding timebinding time
There are many classes of bindings in There are many classes of bindings in programming languages as well as many programming languages as well as many different binding timesdifferent binding times
Included within the concepts of binding and Included within the concepts of binding and binding times are the properties of program binding times are the properties of program elements that are determined by the definition of elements that are determined by the definition of the language or its implementationthe language or its implementation
Binding Time (Cont.)Binding Time (Cont.)
Binding times include:Binding times include: Run time (execution time):Run time (execution time):– On entry to a subprogram or block
• Binding of formal to actual parameters• Binding of formal parameters to storage locations
– At arbitrary points during execution• binding of variables to values• binding of names to storage location in Scheme.
– e.g. (define size 2)
Binding Time (Cont.)Binding Time (Cont.)
Compile time (translation time)Compile time (translation time)– Bindings chosen by the programmer• Variable names• variable types• program statement structure
– Chosen by the translator• Relative location of data objects
– Chosen by the linker• Relative location of different object modules
Binding Time (Cont.)Binding Time (Cont.)
Language Implementation time (i.e. when the Language Implementation time (i.e. when the compiler or interpreter is written)compiler or interpreter is written)
• Representation of numbers. Usually determined by the underlying computer, but not always (e.g. Java defines the representation to guarantee portability)
• Use of implementation-specific features preclude portability– e.g. in Fortran’s expression x*f(y), function f does not have
to be called when x is 0. If the function has side effects, different implementations produce different results.
Language definition timeLanguage definition time• Alternative statement forms
• Data structure types
• Array storage layout
Binding Time (Cont.)Binding Time (Cont.)
Consider xConsider x=x + 10=x + 10– Names: ‘x=’, ‘x=x’, ‘x +’, ‘x’, ‘+’, ’10’– Type of x
• At translation time in C• At run time in Scheme/JavaScript
– Set of possible values of x• At implementation time. If x is real it could be
– the IEEE floating point standard (almost always the choice)
– the implementation of a specific machine– a software-based “infinite precision” representation
– Value of x• Changed at run time
char bar[] = { ‘a’, ‘b’, ‘c’, 0};char bar[] = { ‘a’, ‘b’, ‘c’, 0};char* foo = “abc”;char* foo = “abc”;char* x = foo + 2;char* x = foo + 2;char* y = bar + 2;char* y = bar + 2;bar = bar + 2;bar = bar + 2;
int* g = {1, 2, 3, 0};int* g = {1, 2, 3, 0};g += 2;g += 2;g[2]= 4;g[2]= 4;
Binding Time (Cont.)Binding Time (Cont.)
– Properties of operator +• At compilation time (depending on the type of the
operands because of overloading)– If x is declared integer + means one thing
– if x is declared real means something else– + can also be overloaded by the programmer.
In C++ it is possible to specify that + operates on strings:
string operator +(string& a, string& b) { return a.append(b); }
Binding Time (Cont.)Binding Time (Cont.)
Many of the most important and subtle Many of the most important and subtle differences between languages involve differences between languages involve differences in binding timedifferences in binding time
The trade off is between efficient The trade off is between efficient execution and flexibilityexecution and flexibility– When efficiency is a consideration (Fortran, C)
languages are designed so that as many bindings as possible are performed during translation
– Where flexibility is the prime determiner, bindings are delayed until execution time so that they may be made data dependent
Objects lifetimeObjects lifetime
Key events in the life of an object:Key events in the life of an object:Creation of an object
Destruction of an object
Creation of a binding
Destruction of a binding Dangling reference if these two times are interchanged
Program
execution time
Object lifetim
e
Binding
lifetime
Storage ManagementStorage Management
Three storage allocation Three storage allocation mechanismsmechanisms– Static– Stack – Heap
Static AllocationStatic Allocation
Global variablesGlobal variables ConstantsConstants– manifest, declared (parameter variables in
Fortran) or identified by the compiler
Variables identified as Variables identified as constconst in C can be a in C can be a function of non constants and therefore function of non constants and therefore cannot be statically allocatedcannot be statically allocated
Constant tables generated by the compiler Constant tables generated by the compiler for debugging and other purposesfor debugging and other purposes
int global;int global;
int increment () {int increment () {static int count = 0;static int count = 0;return count + 1;return count + 1;
}}
Foo(int x) {Foo(int x) {double count = 3.14;double count = 3.14;
……}}
X = 5X = 5Foo(3);Foo(3);3 = 53 = 5#define NULL (void*)0#define NULL (void*)0
foo(int x) { …}foo(int x) { …}
bar(float y, int x) { .. }bar(float y, int x) { .. }
xx
yy
x(2)x(2)
Common /gruppo1/ x, y, zCommon /gruppo1/ x, y, z
Return from fooReturn from foo
Static Allocation (Cont.)Static Allocation (Cont.)
In the absence of recursion, all variables In the absence of recursion, all variables can be statically allocatedcan be statically allocated
Also, can be statically allocated:Also, can be statically allocated:– Arguments and return values (or their
addresses). Allocation can be in processor registers rather than in memory
– Temporaries – Bookkeeping information
• return address• saved registers• debugging information
f(x) [x in loc 37]f(x) [x in loc 37]
g(x+1)g(x+1)
g(x) [x in loc 345]g(x) [x in loc 345]
h(x+2)h(x+2)
int f(int x) { int z = 2 * x; return g(z, z) int f(int x) { int z = 2 * x; return g(z, z) *z;*z;
}}
int g(int x, int y) { int z = x * y; return int g(int x, int y) { int z = x * y; return f(x) * z;f(x) * z;
}}
Static Allocation (Cont.)Static Allocation (Cont.)
Stack-based Allocation (Cont.)Stack-based Allocation (Cont.)
Needed when language permits recursionNeeded when language permits recursion Useful in languages without recursion because it Useful in languages without recursion because it
can save spacecan save space Each subroutine invocation creates a frame or Each subroutine invocation creates a frame or
activation recordactivation record– arguments– return address– local variables– temporaries– bookkeeping information
Stack maintained byStack maintained by– calling sequence– prologue– epilogue
Stack-based Allocation (Cont.)Stack-based Allocation (Cont.)
Heap-based AllocationHeap-based Allocation
Region of storage in which blocks of Region of storage in which blocks of memory can be allocated and deallocated memory can be allocated and deallocated at arbitrary timesat arbitrary times
Because they are not allocated in the Because they are not allocated in the stack, the lifetime of objects allocated in stack, the lifetime of objects allocated in the heap is not confined to the subroutine the heap is not confined to the subroutine where they are createdwhere they are created– They can be assigned to parameters (or to
components of objects accessed via pointers by parameters)
– They can be returned as value of the subroutine/function/method
Find the errors in this codeFind the errors in this code
int* foo(int size)int* foo(int size){{
float z;float z;int a[size];int a[size];char* z;char* z;a[0] = 666;a[0] = 666;z = “abc”;z = “abc”;return &a;return &a;
}}
Heap-based Allocation (Cont.)Heap-based Allocation (Cont.)
Several strategies to manage space in the Several strategies to manage space in the heapheap
FragmentationFragmentation– Internal fragmentation when space allocated is
larger than needed– External fragmentation when allocated blocks
are scattered through the heap. Total space available might be more than requested, but no block has the needed size
Heap-based Allocation (Cont.)Heap-based Allocation (Cont.)
One approach to maintain the free One approach to maintain the free memory space is to use a free listmemory space is to use a free list
Two strategies to find a block for a give Two strategies to find a block for a give requestrequest– First fit: use first block in the list large enough
to satisfy the request– Best fit: search the list to find the smallest
block that satisfy the request The free list could be organized as an The free list could be organized as an
array of free lists where each list in the array of free lists where each list in the array contain blocks of the same sizearray contain blocks of the same size– Buddy system– Fibonacci heap (better internal fragmentation)
Garbage collectionGarbage collection
Programmers can mange memory Programmers can mange memory themselves with explicit themselves with explicit allocation/deallocationsallocation/deallocations
However, garbage collection can be However, garbage collection can be applied automatically by the run-time applied automatically by the run-time system to avoid memory leaks and system to avoid memory leaks and difficult to find dangling referencesdifficult to find dangling references– Lisp– Java
The disadvantage is costThe disadvantage is cost
ScopeScope
VariableVariable
A A variablevariable is a is a locationlocation (AKA (AKA referencereference) that can be associated ) that can be associated with a value.with a value.
Obtaining the value associated with Obtaining the value associated with a variable is called a variable is called dereferencingdereferencing, , and creating or changing the and creating or changing the association is called association is called assignmentassignment. .
Formal ModelFormal Model
Store: Var Store: Var → Val→ Val
Env: Name → DenotationEnv: Name → Denotation
Eval: Exp Eval: Exp Env Env Store → Val Store → Val
Typically:Typically:
Val = Int + Real + …Val = Int + Real + …
Denotation = Val + Var + Fun + …Denotation = Val + Var + Fun + …
Exp = Id + Const + Arith + …Exp = Id + Const + Arith + …
Formal Model GraphicalFormal Model Graphical
xyz3.14“abc”sfun
Names Env
12343.21
Store
xy
zxsfun
“abc”
Scope and extentScope and extent
The The scopescope of a variable describes of a variable describes where in a program’s text, the where in a program’s text, the variable may be usedvariable may be used
The The extentextent (or (or lifetimelifetime) describes ) describes when in a program's execution a when in a program's execution a variable existsvariable exists
The scope of a variable is a property The scope of a variable is a property of the name of the variable, and the of the name of the variable, and the extent is a property of the variable extent is a property of the variable itselfitself
Typed VariablesTyped Variables
In In statically-typedstatically-typed languages, a languages, a variable also has a variable also has a typetype, meaning , meaning that only values of a given type can that only values of a given type can be stored in itbe stored in it
In In dynamically-typeddynamically-typed languages, languages, values, not variables, have typesvalues, not variables, have types
x = xx = x
foo(x)foo(x)
Modello Fondamenti ProgrammazioneModello Fondamenti Programmazione
From: http://www.di.unipi.it/~paolo/FP/materiale.htmlFrom: http://www.di.unipi.it/~paolo/FP/materiale.html
State: Frame State: Frame → Env→ Env StateState FrameFramexx IdId
(()()(xx) = ) = vv
xx, , →→expexp vv
Scope rulesScope rules
The region of the program in which a The region of the program in which a binding is active is its scopebinding is active is its scope
Most languages today are lexically Most languages today are lexically scopedscoped
Some languages (e.g. Perl, Lisp) Some languages (e.g. Perl, Lisp) have both lexical and dynamic have both lexical and dynamic scopingscoping
Static ScopeStatic Scope
A single global scope (Basic, awk)A single global scope (Basic, awk)A separate scope for each program A separate scope for each program
unit (main program, subroutines, unit (main program, subroutines, functions) in FORTRANfunctions) in FORTRAN
Static Scope - Nested SubroutinesStatic Scope - Nested Subroutines
In most languages any constant, type, In most languages any constant, type, variables or subroutines declared variables or subroutines declared within a subroutine are not visible within a subroutine are not visible outside the subroutineoutside the subroutine
Closest nested scope ruleClosest nested scope rule::a name is known in the scope in which it is declared unless it is hidden by another declaration of the same name
Static Scope - Nested Subroutines (2)Static Scope - Nested Subroutines (2)procedure P1(A1: T1);var X: real; … procedure P2(A2: T2); … procedure P3(A3: T3); … begin … (*body of P3 *) end; … begin … (* body of P2 *) end; … procedure P4(A4: T4); … function F1(A5: T5) : T6; var X: integer; … begin … (* body of F1 *) end; … begin … (* body of P4 *) end; … begin … (* body of P1 *) end;
Static Scope - Nested Subroutines (3)Static Scope - Nested Subroutines (3)
To find the frames of surrounding To find the frames of surrounding scopes where the desired data is a scopes where the desired data is a static link could be usedstatic link could be used
Static LinkStatic Link
procedure Aprocedure Aprocedure Bprocedure B
procedure C begin end;procedure C begin end;procedure Dprocedure D beginbegin E();E(); end;end;
beginbeginD();D();
end;end;procedure Eprocedure E
beginbeginB();B();
end;end;beginbegin
E();E();end.end.
Static Scope - Nested Subroutines (4)Static Scope - Nested Subroutines (4)
Static Scope - Nested Subroutines (5)Static Scope - Nested Subroutines (5)
ARB4
ARB1
ARB2
ARB3
{ /* B1 */
{ /* B2 */
{ /* B3 */
{ /* B4 */
}
}
}}
Static Scope - Nested Subroutines (6)Static Scope - Nested Subroutines (6)
P1(){ x : real; { /* B1 */ P2() { x : int; P3() } { /* B2 */ { /* B3 */ P2() } } } P3() { x := ..; P3() } }
ARP3
ARP1
ARB1
ARB2
ARB3
ARP2
ARP3
LispLisp
(defun foo (y) (if (= y 0) (print x) (foo (1- y))(defun foo (y) (if (= y 0) (print x) (foo (1- y))(defun bar (x) (foo x))(defun bar (x) (foo x))(bar 3)(bar 3)
(defun eval (e env)(defun eval (e env)(if (symbolp e) (env e)(if (symbolp e) (env e)……..
))(setq x 10)(setq x 10)(defun zed (f) (let (x 8) (bar 3) (f 0)))(defun zed (f) (let (x 8) (bar 3) (f 0)))(zed (function foo))(zed (function foo))env = ((x1 . v1) (x2. v2) ….)env = ((x1 . v1) (x2. v2) ….)((y . 0) (y. 1) (y . 2) (y . 3) (x . 3))((y . 0) (y. 1) (y . 2) (y . 3) (x . 3))(x 3)(x 3)(y 0 1 2 3)(y 0 1 2 3)
PerlPerl
$x = 0;$x = 0;
sub f { return $x; }sub f { return $x; }
sub stat { my $x = 1; return f(); }sub stat { my $x = 1; return f(); }
print “static: “.stat()."\n";print “static: “.stat()."\n";
sub dyn { local $x = 1; return f(); }sub dyn { local $x = 1; return f(); }
print “dynamic: “.dyn()."\n"; print “dynamic: “.dyn()."\n";
(defun pair (x y)(defun pair (x y)
(lambda (op)(lambda (op)
(if (= op ‘left) x y)))(if (= op ‘left) x y)))
(setq p (pair 3 4))(setq p (pair 3 4))
<(lambda (op)…. , ((x . 3) (y . 4))><(lambda (op)…. , ((x . 3) (y . 4))>
(p ‘left)(p ‘left)
p.leftp.left
class Outer {class Outer {int x;int x;class Inner {class Inner {
//int x;//int x;void foo() { x; }void foo() { x; }
}}
void bar() { Inner i = new Inner();void bar() { Inner i = new Inner();int x;int x;i.foo();i.foo();
}}}}
GNU MIPSGNU MIPS
gcc MIPSgcc MIPS
gcc x386gcc x386
sp
fp
arg1
arg2
...
argn
return addrold fp
local m
local m-1
...
local 1
ExampleExample
int foo(int x, int y)int foo(int x, int y)
{{
return xreturn x
+ y; + y;
}}
pushpush %ebp %ebp
movmov %esp,%ebp %esp,%ebp
movmov 0x8(%ebp),0x8(%ebp),%eax%eax
addadd 0xc(%ebp),0xc(%ebp),%eax%eax
movmov %ebp,%esp %ebp,%esp
poppop %ebp %ebp
ret ret
Example: invocationExample: invocation
int a = 3;int a = 3;
int i;int i;
i = foo(a, 256);i = foo(a, 256);
pushpush $0x100$0x100
pushpush $0x3$0x3
callcall 0x0 <foo>0x0 <foo>
movmov %ebp,%esp%ebp,%esp
ExampleExample
int baz(int x, int y)int baz(int x, int y){{ char buf[256];char buf[256]; {{ int z = y + 1;int z = y + 1; x += z;x += z; }} return x + y; return x + y; }}
pushpush %ebp%ebpmovmov %esp,%ebp%esp,%ebpsubsub $0x108,%esp$0x108,%espmovmov 0xc(%ebp),%edx0xc(%ebp),%edxlealea 0x1(%edx),%eax0x1(%edx),%eaxaddadd 0x8(%ebp),%eax0x8(%ebp),%eaxaddadd %edx,%eax%edx,%eaxmovmov %ebp,%esp%ebp,%esppoppop %ebp%ebpret ret
foo(int n, …) {foo(int n, …) {
va_start(n, args);va_start(n, args);
va_arg(int, args, x);va_arg(int, args, x); int x = *args++;int x = *args++;
va_arg(int, args, y);va_arg(int, args, y); int y = *args++;int y = *args++;
}}
Pascal 68000Pascal 68000
Parameter PassingParameter Passing
Parameter PassingParameter Passing
Call by valueCall by valueCall by referenceCall by referenceCall by result, value/resultCall by result, value/resultC++ referencesC++ referencesClosures as parametersClosures as parametersCall by nameCall by nameLabel parametersLabel parametersVariable number of argumentsVariable number of argumentsFunction returnsFunction returns
TerminologyTerminology
Expressions evaluate to R-valuesVariables and components of
variables of structured types also have an L-value, that is, an address where their R-value is stored
The assignment statement requires an L-value on the left-hand side (L stands for “left”) and an R-value on the right-hand side (R stands for “right”)
int x = 3;int x = 3;x = x;x = x;int v[40];int v[40];v[3] = v[3]v[3] = v[3]
(x == 3) =(x == 3) =3 = 3 = int foo();int foo();
foo = ….foo = ….point.x = 12;point.x = 12;
Value model, reference modelValue model, reference model
b = 2;b = 2;
c = b; b = b +1;c = b; b = b +1;
a = b + c;a = b + c;
5
2
2
a
b
c
a
b
c
Value model Reference model 6
3 2 3
ExampleExample
class Point { int x, y; }class Point { int x, y; }
p = new Point(3, 4);p = new Point(3, 4);
Point p2 = p;Point p2 = p;
p.x = 5;p.x = 5;
p2.x ?p2.x ?
foo(p);foo(p);
CC
void foo (int* x) {void foo (int* x) {*x = 3;*x = 3;}}
Struct Point { int x, y};Struct Point { int x, y};
void bar(Point* p) { p->x = 3; }void bar(Point* p) { p->x = 3; }Point p; p.x = 5;Point p; p.x = 5;Point* p2 = &p;Point* p2 = &p;bar(p2);bar(p2);
Reference modelReference model
In language using reference model, In language using reference model, every variable is a L-valueevery variable is a L-value
When it appears in a R-value context, When it appears in a R-value context, it must be it must be dereferenceddereferenced
Usually dereference is implicitUsually dereference is implicitExamples:Examples:– Algol68, Lisp, ML, Haskell, SmallTalk
Java: mixed (value for built-in types)Java: mixed (value for built-in types)
Call by valueCall by value
The value of the R-value of the actual The value of the R-value of the actual parameter is copied into the formal parameter is copied into the formal parameter at invocationparameter at invocation
Call by resultCall by result
The value of the formal parameter is The value of the formal parameter is copied into the actual parameter copied into the actual parameter (which must have an L-value) at (which must have an L-value) at procedure return.procedure return.
Call by value/resultCall by value/result
The parameter is treated as in value The parameter is treated as in value mode during invocation and as in mode during invocation and as in result mode during return.result mode during return.
foo (inout x) { … x …}foo (inout x) { … x …}
foo1 (ref x) { … x … }foo1 (ref x) { … x … }
foo1(v[3]);foo1(v[3]);
s = “asdasd”;s = “asdasd”;
foo1(s);foo1(s);
void foo (ref int x) {void foo (ref int x) {
x = x+ 3;x = x+ 3;
X = x/0;X = x/0;
} }
int z = 2;int z = 2;
foo(z);foo(z);
Call by referenceCall by reference
The L-value of the formal parameter The L-value of the formal parameter is set to the L-value of the actual is set to the L-value of the actual parameter.parameter.
The address of the formal parameter The address of the formal parameter is the same as the address of the is the same as the address of the actual parameter. Any assignment to actual parameter. Any assignment to the formal parameter immediately the formal parameter immediately affects the actual parameter.affects the actual parameter.
NoteNote
void foo(int& x) { x += 1; }void foo(int& x) { x += 1; }
int a[3];int a[3];
a[0] = 0;a[0] = 0;
foo(a[0]);foo(a[0]);
foo(p);foo(p);
Call by nameCall by name
Every use of the formal parameter causes Every use of the formal parameter causes the actual parameter to be freshly the actual parameter to be freshly evaluated in the referencing environment evaluated in the referencing environment of the invocation point.of the invocation point.
If the formal parameter’s L-value is needed If the formal parameter’s L-value is needed (for example, the parameter appears on (for example, the parameter appears on the left-hand side of an assignment), the the left-hand side of an assignment), the actual parameter’s L-value must be freshly actual parameter’s L-value must be freshly evaluated.evaluated.
If the formal parameter’s Rvalue is needed, If the formal parameter’s Rvalue is needed, the actual parameter’s R-value must be the actual parameter’s R-value must be freshly evaluated.freshly evaluated.
Call by name: exampleCall by name: example
int sum(name int expr, ref int j, int size)int sum(name int expr, ref int j, int size)
{{
int tot = 0;int tot = 0;
for (; j < size; j++)for (; j < size; j++)
tot += expr;tot += expr;
return tot;return tot;
}}
sum(A[i], i, n); /* sum of vector elements */sum(A[i], i, n); /* sum of vector elements */
{ int i;{ int i;
int[] A;int[] A;
&int thunk() { return &A[i]; }&int thunk() { return &A[i]; }
sum(thunk, i, n);sum(thunk, i, n);
}}
Call by macroCall by macro
Every use of the formal parameter Every use of the formal parameter causes the text of the actual causes the text of the actual parameter to be freshly evaluated in parameter to be freshly evaluated in the referencing environment of the the referencing environment of the use point.use point.
Parameter passing modesParameter passing modes
ImplementatioImplementationn
OperationsOperations Change to Change to actual?actual?
Alias?Alias?
ValueValue ValueValue RWRW NoNo nono
In, constIn, const Value, Value, referencereference
RORO NoNo MaybeMaybe
Out (C#, Ada)Out (C#, Ada) Value, Value, referencereference
WOWO YesYes MaybeMaybe
Value/resultValue/result ValueValue RWRW YesYes NoNo
Var, refVar, ref ReferenceReference RWRW YesYes YesYes
SharingSharing Value, Value, referencereference
RWRW YesYes MaybeMaybe
In outIn out Value, Value, referencereference
RWRW YesYes MaybeMaybe
NameName ClosureClosure RWRW YesYes yesyes
EsercizioEsercizio
swap(x, y) usando solo call-by-valueswap(x, y) usando solo call-by-value
void swap(int x, int y) {void swap(int x, int y) { int temp;int temp; temp = x;temp = x; x = y;x = y; y = temp;y = temp;};};
Does not work.Does not work.
swap(x, y) usando solo call-by-valueswap(x, y) usando solo call-by-value
int b[10]; swap(i, b[i]);int b[10]; swap(i, b[i]);
void swap(name int x, name int y) {void swap(name int x, name int y) {
int temp;int temp;
temp = i;temp = i;
i = b[i];i = b[i];
b[i] = temp;b[i] = temp;
};};
NoteNote
List l = new List();List l = new List();
Student s = new Student();Student s = new Student();
l.add(s);l.add(s);
float pi = 3.14;float pi = 3.14;
l.add(pi);l.add(pi);
(new Integer(314)).toString();(new Integer(314)).toString();
s.toString();s.toString();
NoteNote
int a = 3;int a = 3;int b = 5;int b = 5;swap(a[i], i);swap(a[i], i);
a=3, b=5; a=5, b=5; a=5, b=3;a=3, b=5; a=5, b=5; a=5, b=3;void swap(inout int x, inout int y) {void swap(inout int x, inout int y) { int temp;int temp; temp = a;temp = a; a = b;a = b; b = temp;b = temp;};};
ExerciseExercise
swap(x, y) using just call-by-nameswap(x, y) using just call-by-name
swap(a, b) => {swap(a, b) => {
int temp; temp = a; a = b; b = temp;int temp; temp = a; a = b; b = temp;
}}
Does it work?Does it work?
Call by nameCall by name
Counter example:Counter example:
swap(i, A[i])swap(i, A[i])
(i=3, A[3] = 4) => (i=4, A[4] = 3, A[3] (i=3, A[3] = 4) => (i=4, A[4] = 3, A[3] unchanged)unchanged)
Call by value/resultCall by value/result
swap(i, A[i])swap(i, A[i])works even in case (i=2, A[2]= 99)works even in case (i=2, A[2]= 99)
Call by valueCall by value
Copies argumentCopies argument Special cases:Special cases:
– array– struct
typedef struct { int x, y} Pair;Pair q;zed(q);
Pair foo() { Pair p; return p; }Pair p = foo();int [200000] v;bar(v);std::string s; bad(s);
int* foo() {int* foo() {
int v[100];int v[100];
return v;return v;
}}
Downward Closure in PascalDownward Closure in Pascal
Static Scope - ModulesStatic Scope - Modules
Modularization depends on Modularization depends on information hidinginformation hiding
Functions and subroutines can be Functions and subroutines can be used to hide information. However, used to hide information. However, this is not flexible enough.this is not flexible enough.
One reason is that persistent data is One reason is that persistent data is usually needed to create abstraction. usually needed to create abstraction. This can be addressed in some This can be addressed in some cases using statically allocated cases using statically allocated valuesvalues
Homework 1Homework 1
Design an implementation of Design an implementation of malloc/freemalloc/free
Implementazione efficiente stringhe Implementazione efficiente stringhe condivisecondivise
Marcatura di albero binario:Marcatura di albero binario:– senza uso di stack o altre strutture
aggiuntive
Static Scope - Modules (Cont.)Static Scope - Modules (Cont.)
Static Scope - Modules (Cont.)Static Scope - Modules (Cont.)
But modularization often requires a But modularization often requires a variety of operations on persistent variety of operations on persistent data.data.
Static Scope - Modules (Cont.) Static Scope - Modules (Cont.)
Objects inside a module are visible Objects inside a module are visible to each otherto each other
Objects inside can be hidden Objects inside can be hidden explicitly (using a keyword like explicitly (using a keyword like private) or implicitly (objects are only private) or implicitly (objects are only visible outside if they are exported)visible outside if they are exported)
In some language objects outside In some language objects outside need to be imported to be visible need to be imported to be visible within the modulewithin the module
Static Scope - ModulesStatic Scope - ModulesModula-2 examplesModula-2 examples
VAR a,b: CARDINAL;VAR a,b: CARDINAL;
MODULE M;MODULE M;
IMPORT a; EXPORT w,x;IMPORT a; EXPORT w,x;
VAR u,v,w; CARDINAL;VAR u,v,w; CARDINAL;
MODULE N;MODULE N;
IMPORT u; EXPORT IMPORT u; EXPORT x,y;x,y;
VAR x,y,z: CARDINAL;VAR x,y,z: CARDINAL;
(* x,u,y,z visible (* x,u,y,z visible here *)here *)
END N;END N;
(* a,u,v,w,x,y visible here (* a,u,v,w,x,y visible here *)*)
END M;END M;
(* a,b,w,x visible here *)(* a,b,w,x visible here *)
MODULE M;MODULE M;
VAR a: CARDINAL;VAR a: CARDINAL;
MODULE N1;MODULE N1;
EXPORT b;EXPORT b;
VAR b: CARDINAL;VAR b: CARDINAL;
(* only b visible here (* only b visible here *)*)
END N1;END N1;
MODULE N2;MODULE N2;
EXPORT c;EXPORT c;
VAR c: CARDINAL;VAR c: CARDINAL;
(* only c visible here (* only c visible here *)*)
end N2;end N2;
MODULE N3;MODULE N3;
IMPORT b,c;IMPORT b,c;
(* b,c visible here *)(* b,c visible here *)
END N3;END N3;
END M;END M;
Modules as typesModules as types
Dynamic scopeDynamic scope
In early Lisp systems variables were In early Lisp systems variables were bound dynamically rather than bound dynamically rather than staticallystatically
In a language with dynamic binding, In a language with dynamic binding, free variables in a procedure get free variables in a procedure get their values from their values from the environment in the environment in which the procedure is calledwhich the procedure is called rather rather than than the environment in which the the environment in which the procedure is definedprocedure is defined
Dynamic scope (Cont.)Dynamic scope (Cont.)
Consider the programConsider the program (define (sum-powers a b n)(define (sum-powers a b n)
(define (nth-power x)(define (nth-power x)
(expt x n))(expt x n))
(sum nth-power a b))(sum nth-power a b))
Where sum is defined as followsWhere sum is defined as follows(define (sum functor a b)(define (sum functor a b)
(if (> a b)(if (> a b)
0 0 (+ (functor a)(+ (functor a)
(sum functor (1+ a) b))))(sum functor (1+ a) b))))
Dynamic scope (Cont.)Dynamic scope (Cont.)
The free variable The free variable nn in in nth-powernth-power would get whatever would get whatever nn had when sum had when sum called itcalled it
Since sum does not rebind Since sum does not rebind nn, the , the only definition of only definition of nn is still the one is still the one from from sum-powerssum-powers
Exchanging variable namesExchanging variable names
(define (sum-powers a n b)(define (sum-powers a n b)
(define (nth-power x)(define (nth-power x)
(expt x b))(expt x b))
(sum nth-power a n))(sum nth-power a n))
(sum-powers 2 10 5)(sum-powers 2 10 5)
Dynamic scope (Cont.)Dynamic scope (Cont.)
But if we had used But if we had used nn instead of instead of bb in the in the definition of definition of sumsum, then , then nth-powernth-power’s free ’s free variable would refer to variable would refer to sumsum’s third ’s third argument, which is not what we intendedargument, which is not what we intended
Dynamic binding violates the principle Dynamic binding violates the principle that a procedure should be regarded as a that a procedure should be regarded as a “black box”“black box”
Changing the name of a parameter Changing the name of a parameter throughout a procedure’s definition throughout a procedure’s definition should not change the procedure behaviorshould not change the procedure behavior
Dynamic scope (Cont.)Dynamic scope (Cont.)
In a statically bound language, the In a statically bound language, the sum-powerssum-powers program must contain program must contain the definition of the definition of nth-powernth-power as a as a local procedure.local procedure.
If If nth-powernth-power represents a common represents a common pattern of usage, its definition must pattern of usage, its definition must be repeated as an internal definition be repeated as an internal definition in many contexts.in many contexts.
Dynamic scope (Cont.)Dynamic scope (Cont.)
It should be attractive to be able to move It should be attractive to be able to move the definition of the definition of nth-powernth-power to a more global to a more global context, where it can be shared by many context, where it can be shared by many proceduresprocedures
(define (sum-powers a b n) (define (sum-powers a b n) (sum nth-power a b))(sum nth-power a b))
(define (product-powers a b n) (define (product-powers a b n) (product nth-power a b))(product nth-power a b))
(define (nth-power x)(define (nth-power x) (expt x n))(expt x n))
The attempt to make this work is what The attempt to make this work is what motivated the development of dynamic motivated the development of dynamic binding disciplinebinding discipline
Dynamic scope (Cont.)Dynamic scope (Cont.)
Dynamically bound variables can be Dynamically bound variables can be helpful in structuring large programshelpful in structuring large programs
They simplify procedure calls by acting as They simplify procedure calls by acting as implicit parametersimplicit parameters
For example, a low-level procedure For example, a low-level procedure nprintnprint called by the system called by the system printprint procedure for printing numbers might procedure for printing numbers might reference a free variable called reference a free variable called radixradix that that specifies the base in which the number is specifies the base in which the number is to be printedto be printed
Procedures that call Procedures that call nprintnprint, need not to , need not to know about this featureknow about this feature
Dynamic scope (Cont.)Dynamic scope (Cont.)
On the other hand, a user might want to temporarily On the other hand, a user might want to temporarily change the change the radixradix
In a statically bound language, In a statically bound language, radixradix would have to would have to be a global variablebe a global variable
After setting After setting radixradix to a new value, the user would to a new value, the user would have to explicitly reset ithave to explicitly reset it
The dynamic binding mechanism could accomplish The dynamic binding mechanism could accomplish this setting and resetting automatically, in a this setting and resetting automatically, in a structured waystructured way
(define print-in-new-radix number radix)(define print-in-new-radix number radix) (print number))(print number)) (define (print frob)(define (print frob) < expressions that involve nprint>)< expressions that involve nprint>) (define (nprint number)(define (nprint number) ...... radixradix ...)...)
Symbol TablesSymbol Tables
Symbol tables are used to keep track of Symbol tables are used to keep track of scope and binding information about scope and binding information about names.names.
The symbol table is searched every time a The symbol table is searched every time a name is encountered in the source textname is encountered in the source text
Changes occur when a new name or new Changes occur when a new name or new information about a name is discoveredinformation about a name is discovered
The abstract syntax tree will contain The abstract syntax tree will contain pointers to the symbol table rather than pointers to the symbol table rather than the actual names used for objects in the the actual names used for objects in the source textsource text
Symbol Tables (Cont.)Symbol Tables (Cont.)
Each symbol table entry contains Each symbol table entry contains – the symbol name– its category (scalar variable, array, constant,
type, procedure, field name, parameter, etc.)– scope number– type (a pointer to another symbol table entry)– and additional, category specific fields (e.g.
rank and shape for arrays) To keep symbol table records uniform, it To keep symbol table records uniform, it
may be convenient for some of the may be convenient for some of the information about a name to be kept information about a name to be kept outside the table entry, with only a pointer outside the table entry, with only a pointer to this information stored in the entryto this information stored in the entry
Symbol Tables (Cont.)Symbol Tables (Cont.)
The symbol table may contain the The symbol table may contain the keywords at the beginning if the keywords at the beginning if the lexical scanner searches the symbol lexical scanner searches the symbol table for each nametable for each name
Alternatively, the lexical scanner can Alternatively, the lexical scanner can identify keywords using a separate identify keywords using a separate table or by creating a separate final table or by creating a separate final state for each keywordstate for each keyword
Symbol Tables (Cont.)Symbol Tables (Cont.)
One of the important issues is handling One of the important issues is handling static scopestatic scope
A simple solution is to create a symbol A simple solution is to create a symbol table for each scope and attach it to the table for each scope and attach it to the node in the abstract syntax tree node in the abstract syntax tree corresponding to the scopecorresponding to the scope
An alter native is to use a An alter native is to use a additional additional data data structure to keep track of the scope. This structure to keep track of the scope. This structure would resemble a stack:structure would resemble a stack:
procedure new_id(id)procedure new_id(id)
for index=top to scope_marker(LL - 1) by -1for index=top to scope_marker(LL - 1) by -1
if id == symbol_table(additional(index)).name then if id == symbol_table(additional(index)).name then error()error()
k = new_symbol_table_index()k = new_symbol_table_index()
symbol_table(k).name=idsymbol_table(k).name=id
additional(top++) = kadditional(top++) = k
procedure old_id(id)procedure old_id(id)
for index= top to 0 by -1for index= top to 0 by -1
if id == symbol_table(additional(index)).name then if id == symbol_table(additional(index)).name then return additional(index)return additional(index)
error()error()
procedure scope_entry ()procedure scope_entry ()
scope_marker(LL++)=topscope_marker(LL++)=top
procedure scope_exit()procedure scope_exit()
top = scope_marker(--LL)top = scope_marker(--LL)
A
C
A
Badditional
0
2
scope_marker
4 top
2 LL
symbol table
Symbol Tables (Cont.)Symbol Tables (Cont.)
A hash table can be added to the previous A hash table can be added to the previous data structure to accelerate the search.data structure to accelerate the search.
Elements with the same name are linked Elements with the same name are linked from top to bottom.from top to bottom.
Search start at the entry of the hash table Search start at the entry of the hash table and proceeds through the linked list until and proceeds through the linked list until the end of the list is reached (the end of the list is reached (old_idold_id) or ) or until the link list refers to an element below until the link list refers to an element below scope_marker(LL - 1) (new_idscope_marker(LL - 1) (new_id))
Symbol Tables (Cont.)Symbol Tables (Cont.)
This approach does not work in some cases.This approach does not work in some cases. Consider the with statement of Pascal and Consider the with statement of Pascal and
Modula 2.Modula 2.Date = RECORD day: [1..31];Date = RECORD day: [1..31]; mo: month;mo: month; yr: CARDINALyr: CARDINAL ENDENDd1: Date;d1: Date;
WITH d1 DOWITH d1 DO day:=10; mo:=Sep; yr:=1981day:=10; mo:=Sep; yr:=1981ENDEND
is equivalent tois equivalent to
d1.day:=10; d1.mo:=Sep; d1.yr:=1981d1.day:=10; d1.mo:=Sep; d1.yr:=1981
Symbol TablesSymbol Tables
Symbol Tables (Cont.)Symbol Tables (Cont.)
Association Lists and Central Association Lists and Central Reference TablesReference Tables
The binding of referencing The binding of referencing environmentsenvironments
Shallow binding: the referencing Shallow binding: the referencing environment of a routine is not created environment of a routine is not created until the subroutine is actually calleduntil the subroutine is actually called
Deep binding: the program binds the Deep binding: the program binds the environment at the time the subroutine is environment at the time the subroutine is passed as a parameterpassed as a parameter
Deep binding is implemented by creating Deep binding is implemented by creating an explicit representation of a referencing an explicit representation of a referencing environment and bundling it together with environment and bundling it together with a reference to the subroutine. a reference to the subroutine. ClosureClosure
ARP1
ARB1
ARB2
ARB3
ARP2
ARP3
P1(){ REAL X { /* B1 */ { /* B2 */ { /* B3 */ P2(P3) }
P3() { x } } P2(PX) { PX() }
}}
PX