Anda di halaman 1dari 14

Scope in Programming Languages

Amruth N. Kumar Eric Fernandes, Steve Obringer Ramapo College of New Jersey amruth@ramapo.edu

Introduction

Scope is an important concept in programming languages one cannot read or write large programs without understanding the concept of scope. The scope of a variable in a program is the lines of code in the program whe be accessed.

Historically, two different types of scope have been used in programming languages: static scope and dynam modern programming languages such as Pascal, C++ and Java use static scope. Some languages such as APL, Sn versions of LISP use dynamic scope. As students of Programming Languages, we will study both these types.

The converse of scope is referencing environment. The referencing environment of a procedure is the set of whose scope extends to the procedure. It may be divided into local and non-local environments. The local refere environment of a procedure consists of all the variables declared within the procedure, and includes any formal procedure. The non-local referencing environment consists of all the variables not declared in the procedure, b extends to the procedure.

The concept of scope applies not only to variable names but also to the names of procedures. The scope of th procedure determines all the procedures/functions in a program that can call the procedure.

Scope Courseware

This courseware addresses all these aspects of scope. It comprises of five modules addressing the following t 1. Static Scope of variables 2. Static Referencing Environment of a procedure 3. Dynamic Scope of variables 4. Dynamic Referencing Environment of a procedure 5. Callability of procedures - Scope of procedure names

Pascal is popularly used to illustrate the intricacies of static scope since it allows procedure definitions to be nest you compare and contrast static scope with dynamic scope, and to reduce the burden of having to learn new synta will use Pascal-like programs to illustrate dynamic scope also.

Contents of Each Module

Each of the five modules contains a tutorial and an applet. The applet is hyperlinked from the tutorial. The inform tutorial is organized under the following titles:

Definition: In this section, the definition of the concept is presented. Where applicable, the definition is clarified Pascal.

Example: This section includes the following items: 1. A sample program, and a problem based on the program; 2. Answer to the problem, along with explanation.

Pragmatics: In this section, additional questions are presented based on the earlier example. These questions are you consider other aspects of the problem, and extend what you have learned to other concepts.

Algorithms to determine Scope: Whereas the definition section describes the relevant theory, this section l that you may want to use to apply the theory to solve problems.

Test your understanding - Instructions: This section lists the following items: 1. Your options for solving problems using the applet; 2. The steps you must follow to solve each problem; 3. A screen shot illustrating these steps;

4. A hyperlink to the applet itself. Note that when you click on the hyperlink, the following two windows will be

a. A web page to record how many problems you have attempted and how many problems you have solve

b. The applet window that you will use to solve the problems. You may solve as many problems as you w

exiting the applet window. Please pay particular attention to the feedback provided by the applet for e

Once you exit the applet, you can re-launch it by clicking on the Create New Problem button on the acc page.

Acknowledgements

Partial support for this work was provided by the National Science Foundations Course, Curriculum and Labora Program under grant DUE-0088864, January 2001-December 2002.

CSE 341 -- Static and Dynamic Scoping


Scope rules define the visibility rules for names in a programming language. What if you have references to a variable named k in different parts of the program? Do these refer to the same variable or to different ones? Languages such as Algol, Ada, C, and Pascal are statically scoped. A block defines a new scope. Variables can be declared in that scope, and aren't visible from the outside. However, variables outside the scope -- in enclosing scopes -- are visible unless they are overridden. In Algol and Pascal (but not C or Ada) these scope rules also apply to the names of functions and procedures. Static scoping is also sometimes called lexical scoping.

Simple Static Scoping Example


begin integer m, n; procedure hardy; begin print("in hardy -- n = ", n); end; procedure laurel(n: integer); begin print("in laurel -- m = ", m);

print("in laurel -- n = ", n); hardy; end; m := 50; n := 100; print("in main program -- n = ", n); laurel(1); hardy; end;

The output is:


in in in in in main program -- n = 100 laurel -- m = 50 laurel -- n = 1 hardy -- n = 100 /* note that here hardy is called from laurel */ hardy -- n = 100 /* here hardy is called from the main program */

Blocks can be nested an arbitrary number of levels deep.

Scoping in Lisp
The default scope rule in lisp is static scoping.
(setf m 50) (setf n 100) (defun hardy () (format t "~&in hardy -- n = ~a" n)) (defun laurel (n) (format t "~&in laurel -- m = ~a" m) (format t "~&in laurel -- n = ~a" n) (hardy)) (format t "~&in main program -- n = ~a" n) (laurel 1) (hardy)

Output is the same as for Algol.

Dynamic Scoping
Common Lisp also supports dynamic scoping. Using this scoping rule, we first look for a local definition of a variable. If it isn't found, we look up the calling stack for a definition. (See page 435 of the Lisp book.) Dynamic scoping was the norm in versions of Lisp before Common Lisp, and is also used in some older, interpreted languages such as SNOBOL and APL.

We can declare a variable as dynamically scoped in Lisp using defvar. Example:


;; note the declaration of m and n as dynamically scoped (defvar m 50) (defvar n 100)

(defun hardy () (format t "~&in hardy -- n = ~a" n)) (defun laurel (n) (format t "~&in laurel -- m = ~a" m) (format t "~&in laurel -- n = ~a" n) (hardy)) (format t "~&in main program -- n = ~a" n) (laurel 1) (hardy)

The output is:


in in in in in main program -- n = 100 laurel -- m = 50 laurel -- n = 1 hardy -- n = 1 ;; NOTE DIFFERENCE -- here hardy is called from laurel hardy -- n = 100 ;; here hardy is called from the main program

Scopes and Procedures


In Algol, Pascal, Simula, and other languages in the Algol family, you can also nest procedure and function declarations inside of other procedure and function declarations. The same static scope rules apply. (You can't do this in Ada or C though.)
begin integer m, n; procedure laurel(n: integer); begin procedure hardy; begin print("in hardy -- n = ", n); end; print("in laurel -- m = ", m); print("in laurel -- n = ", n); hardy; end; m := 50; n := 100; print("in main program -- n = ", n); laurel(1); /* we can't call hardy here, since the name isn't visible */ end;

Nesting procedures inside of other procedures interacts in interesting ways with recursion:
begin

integer global, n; procedure laurel(n: integer); begin procedure hardy; begin print(global); print(n); end; if n<4 then laurel(n+1); else hardy; end; global := 99; n := 100; laurel(1); end;

Here the output is


99 4

Note that when we finally call hardy, there are 5 different n's on the stack: the global one (with value 100), then 4 different invocations of laurel (with n=1, n=2, n=3, and n=4).

Procedures as Parameters
In Algol, Pascal, and Lisp, you can pass procedures or functions as parameters. To pass a procedure as a parameter, the system passes a closure: a reference to the procedure body along with a pointer to the environment of definition of the procedure.
begin procedure test(n: integer, p: procedure); begin procedure rose; begin print("in procedure rose -- n="); print(n); end; print("in procedure test -- n="); print(n); p; if n<10 then begin if n=3 then test(n+1,rose) else test(n+1,p) end end; procedure violet; begin print("in procedure violet"); end;

test(1,violet); end;

Output:
in procedure test -- n=1 in procedure violet in procedure test -- n=2 in procedure violet in procedure test -- n=3 in procedure violet in procedure test -- n=4 in procedure rose -- n=3 in procedure test -- n=5 in procedure rose -- n=3 in procedure test -- n=6 in procedure rose -- n=3 in procedure test -- n=7 in procedure rose -- n=3 in procedure test -- n=8 in procedure rose -- n=3 in procedure test -- n=9 in procedure rose -- n=3 in procedure test -- n=10 in procedure rose -- n=3

In Algol and Pascal, we can only pass procedures in as parameters -- we can't return a procedure or a function as a value from another function. We can do this in Lisp, however -- it means that Lisp can't always use a stack for storage allocation for local variables. Blocks in Smalltalk also are lexically scoped, and include their environment of definition. Blocks can be returned from methods, assigned to global variables, and so forth -- so that storage for local variables can't always be allocated on a stack in Smalltalk either. Example:
| a sum | a := Array new: 3. a at: 1 put: 10. a at: 2 put: 20. sum := 0. a do: [:n | sum := sum+n].

a at: 3 put: 30.

More complicated example: suppose we evaluate the following Smalltalk code.


| k | B1 := [k]. B2 := [:n | k := n+2]. k := 100.

After we do this, the two global variables B1 and B2 are bound to blocks. The local variable k is no longer visible, but is still accessible and is shared by the two blocks. So B1 value will return 100. If we evaluate B2 value: 5, this will assign 7 to k. After that evaluating B1 value will return 7.

Paramerter transmission:

Chapter 9: Subprogram Control - Sharing Data Objects


Parameter transmission o Actual and formal parameters o Methods for transmitting parameters o Transmission semantics o Implementation of parameter transmission Explicit common environment

Exam-like questions

A.

Parameter transmission
Subprograms need mechanisms to exchange data. Arguments - data objects sent to a subprogram to be processed Obtained through o o parameters non-local references

Results - data object or values delivered by the subprogram

Returned through o o o 6. parameters assignments to non-local variables explicit function values

Actual and Formal Parameters


A formal parameter is a particular kind of local data object within a subprogram. It has a name, the declaration specifies its attributes. An actual parameter is a data object that is shared with the caller subprogram. Might be: a local data object belonging to the caller, a formal parameter of the caller, a nonlocal data object visible to the caller, a result returned by a function invoked by the caller and immediately transmitted to the called subprogram.

Establishing a Correspondence Positional correspondence pairing actual and formal parameters based on their respective positions in the actual- and formal- parameter lists. Correspondence by explicit name the name is paired explicitly by the caller. 7.

Methods for transmitting parameters


Call by name the actual parameter is substituted in the subprogram. Call by reference a pointer to the location of the data object is made available to the subprogram. The data object does not change position in memory. Call by value the value of the actual parameter is copied in the location of the formal parameter. Call by value-result same as call by value, however at the end of execution the result is copied into the actual parameter. Call by constant value if a parameter is transmitted by constant value, then no change in the value of the formal parameter is allowed during program execution. Call by result a parameter transmitted by result is used only to transmit a result back from a subprogram. The initial value of the actual-

parameter data object makes no difference and cannot be used by the subprogram. Note: Often "pass by" is used instead of "call by" . Examples:

Pass by name in Algol


procedure S (el, k); integer el, k; begin k:=2; el := 0 end; A[1] := A[2] := 1; i := 1; S(A[i],i);

Pass by reference in FORTRAN


SUBROUTINE S (EL, K) K = 2 EL = 0 RETURN END A(1) = A(2) = 1 I = 1 CALL S (A(I), I)

Pass by name: After calling S(A[i],i), the effect is as if the procedure were i := 2; A[i] := 0; As a result A[2] becomes 0. On exit we have i = 2, A[1] = 1, A[2] = 0. Pass by reference: Since at the time of call i is 1, the formal parameter el is linked to the address of A(1). Thus it is A(1) that becomes 0. On exit we have: i = 2, A(1) = 0, A(2) = 1

8.

Transmission semantics
Types of parameters: input information output information (the result) both input and output The three types can be accomplished by copying or using pass-byreference Return results: Using parameters Using functions with a return value

9.

Implementation of parameter transmission


Implementing formal parameters: Storage - in the activation record Type: Local data object of type T in case of pass by value, pass by value-result, pass by result Local data object of type pointer to T in case of pass by reference Call by name implementation: the formal parameters are subprograms that evaluate the actual parameters. Actions for parameter transmission: associated with the point of call of the subprogram each actual parameter is evaluated in the referencing environment of the calling program, and list of pointers is set up. associated with the entry and exit in the subprogram on entry: copying the entire contents of the actual parameter in the formal parameter, or copying the pointer to the actual parameter on exit: copying result values into actual parameters or copying function values into registers These actions are performed by prologue and epilogue code generated by the compiler and stored in the segment code part of the activation record of the subprogram.

Thus the compiler has two main tasks in the implementation of parameter transmission 3. It must generate the correct executable code for transmission of parameters, return of results, and each reference to a formalparameter name. 4. It must perform the necessary static type checking to ensure that the type of each actual-parameter data object matches that declared for the corresponding formal parameter B.

Explicit common environment


This method of sharing data objects is straightforward. Specification: A common environment that is similar to a local environment, however it is not a part of any single subprogram. It may contain: definitions of variables, constants, types. It cannot contain: subprograms, formal parameters. Implementation: as a separate block of memory storage. Special keywords are used to specify variables to be shared.

Exam-like questions
1. Describe each method of parameter transmission (see A.2). 2. What is the difference between pass by name and pass by reference methods of parameter transmission? 3. What is the difference between pass by value and pass by reference methods of parameter transmission? 4. What is the difference between pass by value-result and pass by result methods of parameter transmission? 5. Consider the following code in some imaginary language : /* main program */ .... integer i = 1,j = 2; subprog(i,j); print(i,j); ..... subprog(integer k, integer m); begin k = k + 1; m = m + i; print (i,j,k,m); end;

What values would be printed in the three modes of parameter transmission? Fill in the table below: print(i,j,k,m) in subprog Print(i,j) in main program i j

i Pass by reference Pass by value Pass by value result Solution

Anda mungkin juga menyukai