You are on page 1of 85

Expression evaluation

An expression generally consists of either


simple object or An operator or Function applied to a collection of operands or argument

Each in turn is an expression In most of imperative languages, function calls consist of a function name followed by a parenthesized , comma-separated list of arguments as in sum(a,b) In Ada a + b is short for +(a,b)

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Expression evaluation
In general , language may specify that function call employ

prefix, infix , or prefix notation . These indicates appearance of function name prefix op a b or op(a , b) or (op a b) infix a op b postfix a b op. Most of imperative languages use infix notation for binary and prefix for unary and other functions

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Lisp uses prefix notation for all functions

( Cambridge polish notation ) ex: (op a b) A few languages like ML(meta-language) and the R scripting languages allows to create new infix operator Smalltalk uses infix notation for all functions C and its descendants uses pre, post increment or decrements.

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Expression evaluation requires :

precedence and associativity Assignment Initialization Ordering with in expressions Short circuit evaluation

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Precedence and associativity


Most language provides rich set of built in arithmetic and

logical operators When written in infix notation, without parentheses , these operators lead to ambiguity as to what is an operand of what
Ex: a + b * c ** d ** e/f how this expression is evaluated ?. The choice among alternative evaluation orders depends on precedence and associativity of operators.

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Precedence and associativity


Precedence and associativity do not arise in prefix and postfix Precedence rule specify that certain operators, in the absence of

parentheses, group more tightly than other operators. The precedence structure of C is substantially richer than that of most other languages. Pascal has flat precedence APL ,smalltalk all operators are of equal precedence Parentheses must be used to specify grouping.

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Precedence and associativity

Associativity rule specify weather sequence of operators of equal

precedence group to the right or left EX: 9-5-3 if right ans:7 left ans:1 The basic arithmetic operators almost always associate left to right so ans is 1 In Fortran exponentiation (**) operator associate right to left so 2**3**2 is 512 and not 64 In ADA exponentiation is not associative

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Expression evaluation requires : precedence

and associativity Assignment Initialization Ordering with in expressions Short circuit evaluation

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Assignment
In purely functional language, expression are the building blocks

of the program, and computation consists entirely of expression evaluation The effect of any individual expression on the overall computation is limited to the value that expression provides to its surrounding context. In imperative computation typically consists of an ordered series of changes to the values of variables in memory. Assignment provide the principal by which to make the changes

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Assignment
Each assignment takes pair of argument a value and a reference A programming language is said to have Side effect if it

influences subsequent computation in any way other than by returning a value for use in the surrounding context. Assignment is perhaps the most fundamental side effect Many imperative language distinguish between expression(always produces value) and statement(executed solely)

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Assignment
functional languages have no side effects If an expression yields certain value at a one point of time , it is

guaranteed to yield the same value at any point in time Expression in purely functional languages are said to referentially transparent Haskell and Miranda are purely functional languages ML and LISP are mixed(functional and assignment)

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Assignment
The difference between reference and values is invisible, but

requires to understand about it(pointers) an lvalue is an object reference and an rvalue is a value. ex: d = a; a=b+c; In the first statement, the right hand side of an assignment refers to the value of a, which we wish to place into d In the second statement refers to location of a

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Assignment
An lvalue always has a defined region of storage, so you can

take its address. An rvalue does not necessarily have any storage associated with it. An lvalue is expression that denotes locations are referred as lvalue Expression that denote values are referred as r-values Not all expressions are l-value Variables in c are value model

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Assignment
Some languages like algol,clu,lisp,ml,haskell,smalltalk variables

are named reference to a value EX: b := 2 c := b a := b + c We put value 2 in b, and then copy into c, we then read these values and placing a result 4 in a we let b refer to 2 and let c refer to it also, we pass these reference to + operator, and let a refer to the result namely 4

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Assignment
A language that uses reference model , every variable is an L-value When it appears in context that expects an r-value,it must be

dereferenced to obtain the value to which it refers. In most of the languages which use a variable as reference model in that ,dereference is automatic. In ML we need to explicitly dereference is required. Java uses a value model for built in type and reference model for user defined types

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Assignment

A drawback of using a value model for built-in types is that they can

be passed uniformly to methods that expect class typed. Early versions of Java, required the programmer to wrap objects of built-in types inside corresponding predefined class types in order to insert them in standard container(collection) classes More recent versions of Java perform automatic boxing and unboxing operations that avoid the need for wrappers in many cases

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Orthogonality: One of the principal design goals of Algol 68 was to make the various features of the language as orthogonal as possible. Orthogonality means that features can be used in any combination, the combinations all make sense, and the meaning of a given feature is consistent, regardless of the other features with which it is combined. The name is meant to draw an explicit analogy to orthogonal vectors in linear algebra

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Combination of assignment : Because they rely so heavily on side effects, imperative programs must frequently Updating assignments a = a + 1; or worse, b.c[3].d = b.c[3].d * e; Such statements are not only cumbersome to write and to read they also result in redundant address calculations If the address calculation has a side effect, then we may need to write a pair of statements instead.

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

C provides 10 different assignment operators, one for each of its

binary arithmetic and bit-wise operators. C also provides prefix and postfix increment and decrement operations. When prefixed to an expression, the ++ or -- operator increments or decrements its operand before providing a value to the surrounding context. In the postfix form, ++ or -updates its operand after providing a value. Several languages allow to write multi way assignment like a = b= c like clu,ML,perl phython ruby. It is also possible to write a,b = c,d here comma in the right hand side tuple consisting of multiple r-values The effect of assignment is to copy c into a and d into b
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Expression evaluation requires :

precedence and associativity Assignment Initialization Ordering with in expressions Short circuit evaluation

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Initialization
Assignment statement provides to set the value to variable

imperative languages do not always provide a means of specifying an initial value for a variable in its declaration. There are at least two reasons, however, why such initial values may be useful:

1.

In the case of statically allocated variables an initial value that is specified in the context of the declaration can be placed into memory by the compiler. If the initial value is set by an assignment statement instead, it will generally incur execution cost at run time.

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Initialization
2. One of the most common programming errors is to use a

variable in an expression before giving it a value. One of the easiest ways to prevent such errors is to give every variable a value when it is first declared. Some languages (e.g., Pascal) have no initialization facility at all; all variables must be given values by explicit assignment statements.

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Initialization
To avoid the expense of run-time initialization of

statically allocated variables, many Pascal implementations provide initialization as a language extension, generally in the form of a := expr immediately after the name in the declaration. It should be emphasized that initialization saves time only for variables that are statically allocated. variables allocated in the stack or heap at run time must be initialized at run time. If a variable is not given an initial value explicitly in its declaration, the language may specify a default value.
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Initialization
In C, for example, statically allocated variables for which

the programmer does not provide an initial value are guaranteed to be represented in memory as if they had been initialized to zero. The programmer can specify an initial value if desired; Most scripting languages provide a default initial value for all variables, of all types, regardless of scope or lifetime Instead of giving every uninitialized variable a default value, a language or implementation can choose to define the use of uninitialized variable as a dynamic semantic error , can catch these errors at runtime
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Initialization
The advantage of these semantic checks is that they will

often identify the program bug that is masked by the presence of a default value For local variables of methods java and C# defines a notion of define assignment statement that precludes the use of uninitialized variables . This notion is based on the control flow of program, and can be statically checked by compiler. Many object oriented languages allow the programmer to define types for which initialization of dynamically allocated variables occurs automatically ,even no initial value is specified inits declaration
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Initialization
This is interpreted as a call to constructor

function for the variable type with the initial value as argument Difference between assignment and initialization is assignment is deallocate the space consumed by old value of the string before allocating space for the new value Initialization of the string simply allocate space
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Expression evaluation requires :

precedence and associativity


Assignment
Initialization

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Ordering

with in expressions Short circuit evaluation

Ordering with in expression


While precedence and associativity rules define the order

in which binary infix operators are applied with in expression , they do not specify the order in which the operands of a given operator is evaluated Ex: a f(b) c * d We dont know whether a f(b) Will be evaluated before or after c*d F(a,g(b),h(d)) we dont the order in which the arguments are evaluated
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Ordering with in expression


Order is important for two reasons

1. Side effects 2. Code improvement

Side effects: if f(b) may modify c then the value of a f(b) c * d will depend on whether first subtraction or the multiplication is performed first Code improvement: the order of evaluation of sub expression has an impact on both register allocation and instruction scheduling
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Ordering with in expression


In the expression a f(b) c * d , its probably desirable

to call f(b) before evaluating a* b because the product , if calculated first , would need to be saved during the call to f , and f might want to use all registers in which it might be saved Because of the importance of code improvement, most language manual says that the order of evaluation of operands and argument is undefined (java and C#)

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Ordering with in expression


Some language implementations allow the compiler to re

arrange expressions involving operators whose mathematical abstractions are commutative , associative, distributive in order to generate faster code
a = b + c

d=c+e+b some compilers will rearrange them as a = b + c d = b + c + e

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Ordering with in expression


they can then recognize the common sub expression in

the first and second statement and generate code equivalent to


a=b+c d=a+e

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Expression evaluation requires :

precedence and associativity Assignment Initialization Ordering with in expressions Short circuit evaluation

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Short circuit evaluation


Boolean expression provide a special and important

opportunity for code improvement and increased readability Consider the expression (a > b) and (b < C) If a is greater than b, there is no point in checking to see whether b is less than c we know that overall expression must be false A compiler perform short circuit evaluation of boolean expressions will generate code that skips the second half of both of these computations when the overall value can be determined from first half

Short circuit evaluation can save significant amount of time

in certain situation Short circuit changes the semantics of boolean expressions Some situations requires short circuit evaluation , some does not requires it A few languages provides both regular and short circuit boolean operators In c the bitwise & and | operators can be used non short circuit alternatives to && and || when their arguments are logical values In algol 68 allows arbitrary control flow constructs can be used inside expression

Structured and Unstructured Flow


Control flow in assembly language is achieved by means

of conditional and unconditional jumps Early versions of Fortran rely heavily on goto Ada and C# allows goto only in limited situations Modula , clu, Eiffel and java does not allow them at all The abandonment of gotos was part of a larger revolution in software engineering known as structured programming

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Structured and Unstructured Flow


Structured programming was the hot trend of 1970 Structured programming emphasizes top-down design

These may be expressed with only sequencing ,selection

and iteration Many of the structured control-flow construct familiar to modern programmers were pioneered by algol60 These includes if then else, enumeration(for), and logically controlled loops

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Structured and Unstructured Flow

Structured alternatives to GOTO: A goto might have been used to jump to the end of the current sub routine, most modern languages provides an explicit return statement A goto might have been used to escape from the middle of the loop, most of the modern languages provides the break or exit statement for this purpose. Several languages allow a program to return from a nested chain of subroutine calls in a single operation, and most provide away to raise an exception that propagates out to some surrounding context Multilevel returns: Returns and (local) gotos allow control to return from the current subroutine. On occasion it may make sense to return from a surrounding routine.
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Structured and Unstructured Flow


for example, that we are searching for an item matching

some desired pattern with a collection of files. The search routine might invoke several nested routines, or a single routine multiple times, once for each place in which to search. In such a situation certain historic languages, including Algol 60, PL/I, and Pascal, permit a goto to branch to a lexically visible label outside the current subroutine: in the event of non-local goto, the language implementation must guarantee to repair the run-time stack of subroutine call information. This repair operation is known as unwinding It requires not only that the implementation deallocate the stack frames of any subroutines from which we have escaped, but also that it perform any bookkeeping operations, such as restoration of register contents, that would have been performed when returning from those routines
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Error and other exceptions


The notion of a multilevel return assumes that the callee knows

what the caller expects, and can return an appropriate value. In a related and arguably more common situation, a deeply nested block or subroutine may discover that it is unable to proceed with its usual function and, moreover, lacks the contextual information it would need to recover in any graceful way. The only recourse in such a situation is to back out of the nested context to some point in the program that is able to recover. Conditions that require a program to back out are usually called exceptions.

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

The most straightforward but generally least satisfactory way to

cope with exceptions is to use auxiliary Boolean variables within a subroutine (if still_ok then ...) and to return status codes from calls: The auxiliary Booleans can be eliminated by using a nonlocal goto or multilevel return, but the caller to which we return must still inspect status codes explicitly. As a structured alternative, many modern languages provide an exception handling mechanism for convenient, nonlocal recovery from exceptions. Typically the programmer appends a block of code called a handler to any computation in which an exception may arise. The job of the handler is to take whatever remedial action is required to recover from the exception. If the protected computation completes in the normal fashion, execution of the handler is skipped.
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

The notion of nonlocal gotos that unwind the stack can be

generalized by defining what are known as continuations. In low-level terms, a continuation consists of a code address and a referencing environment to be restored when jumping to that address. In higher-level terms, a continuation is an abstraction that captures a context in which execution might continue. Continuations are fundamental to denotational semantics Continuation support in Scheme takes the form of a general purpose function called call-with-current-continuation, sometimes abbreviated call/cc. This function takes a single argument, f , which is itself a function. It calls f , passing as argument a continuation c that captures the current program counter and referencing environment.
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Control flow constructs


Sequencing Selection Iteration Procedural abstractions

Recursion
Concurrency

Exception handling
Nondeterminacy
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

sequencing
Like assignment , sequencing is central to imperative languages It is the principal means of controlling the order in which

side effect occurs when one statement follows another in the program text, the first statement executes before the second. In most imperative languages, lists of statements can be enclosed with begin. . . end or {. . . } delimiters and then used in any context in which a single statement is expected. Such a delimited list is usually called a compound statement. A compound statement preceded by a set of declarations is sometimes called a block. In languages like algol68, which eliminate distinction between statement and expression, the value of statement is the value of its final element.
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Sequencing
In common lisp, the programmer can choose to return the

value as first, second or last Sequencing is useless operation unless the sub expression that do not play part in return value have side effect In Euclid and Turing functions are not permitted to have side effect Among other thing side effect freedom ensures that a Euclid or Turing function is always idempotent means that if called repeatedly with the same set of arguments , it will always return the same value and the number of calls will not affect the subsequent execution There are some situations in which side effects in function are highly desirable Ex: random number generation
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

selection
A selection statement provide the means of choosing between

two or more execution paths in program Selection are categorized to two ways
Two way Multi way

Selection in most imperative languages employ some variant of

the if . Then . Else notation introduced in algol60 if condition then statement else if condition then statement else if condition then statement ... else statement
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

selection
In Algol60 and pascal both the then clause and else clause are

defined to contain a single statement. Algol 68 Fortran 77 allowing statement list to follow either then or else , with a terminating key word at the end of the construct Modula2 provide special terminator of elseif as elsif or elif LISP: ex:
(cond ((= A B) Modula: IF a = b THEN ... ELSIF a = c THEN ... ELSIF a = d THEN ... ELSE ... END (...)) ((= A C) (...))

((= A D)
(...)) (T (...))) Here condition takes arguments a sequence of pair First is condition and second is expression

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Short circuited condition


While the condition in if ..then..else statement is boolean

expression there is usually no need for evaluation of that expression to result in a boolean value in the register The purpose of the boolean expression in a selection statement is not to compute value to be stored , but to cause control to branch to various locations. This observation allows to generate partially efficient code (Jump code) . Jump code is applicable not only to selection statement such as if then.else but to logically controlled loops as well

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

if ((A > B) and (C > D)) or (E F) then

then clause
else

else clause

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Short circuiting
In the above examples first one is example for the language

which is not using short circuiting In that the boolean value is stored in the register Where as in second one boolean condition never explicitly placed in to the register .rather it is implicit in the flow of control Moreover for most values of A,B,C,D,E, the execution path through the jump code is shorter and therefore faster than the straight line code that calculates the value of every sub expression

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Case/Switch statement
The case statement of algolW and its decedents provide an alternate syntax for a special case

of nested if then else When each condition compares to same integer expression to a different compile time constant, then the following code

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

i := ... (* potentially complicated expression *) IF i = 1 THEN

CASE ... (* potentially complicated expression *) OF 1: clause A clause A | 2, 7: clause B ELSIF i IN 2, 7 THEN | 3..5: clause C clause B | 10: clause D ELSIF i IN 3..5 THEN ELSE clause E clause C END ELSIF (i = 10) THEN Clause A,clause B, clause CE are called arms of the case clause D statement ELSE The list of constants in front of clause E colons are CASE statement END labels. QIS INSTITUTE OF TECHNOLOGY, ONGOLE

The constants in label must be disjoint and

must be of type compatible with the tested expression Most languages allow this type to be anything whose values are discrete The case statement version of code less verbose then if then else The if then else statement translated as follows

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

r1 := . . . calculate tested expression if r1 = 1 goto L1

T:

clause A
goto L6 L1: if r1 = 2 goto L2 if r1 7 goto L3 L2: clause B goto L6 L3: if r1 < 3 goto L4 if r1 > 5 goto L4

clause C
goto L6 L4: if r1 10 goto L5

&L1 tested expression = 1 &L2 &L3 &L3 &L3 &L5 &L2 &L5 &L5 &L4 tested expression = 10

clause D
goto L6 L5: clause E L6:

L6: r1 := . . . calculate tested expression if r1 < 1 goto L5 if r1 > 10 goto L5 L5 is the else arm r1 := 1 subtract off lower bound r2 := T[r1] goto *r2 L7:

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

goto L6 jump to code to compute address

L1: clause A goto L7 L2: clause B goto L7 L3: clause C goto L7 ... L4: clause D goto L7 L5: clause E goto L7 L6: r1 := . . . computed target of branch goto *r1 L7:
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Rather than tests its expression sequentially

against series of possible values, the case statement is meant to compute an address to which it jumps in a single instruction The code at L6 can take any of several form The most common form of these simply index into array here code at label T is actually table of addresses, known as jump table It contains one entry between lowest and highest values, inclusive, found among case statement labels. The code at L6 checks to make sure that the tested expression is with in the bounds of array , if then fetches the corresponding entry from the table and branches to it
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

A linear jump table is fast


It is also space efficient when the overall set

of case statement label is dense and does not contain large ranges It can consumes large amount of space however, if the set of labels is nondense, or include large range values Alternate methods to compute the address to which to branch includes sequential, hashing and binary search Sequential is the method of choice if the total number of case statement labels is small

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Iteration
Iteration and recursion are the two mechanisms that allow a

computer to perform similar operations repeatedly. Iteration and recursion makes computer useful Programmers in imperative languages tend to use iteration more than they use recursion Recursion is more common in functional languages In most languages, iteration takes the form of loops. Like the statements in a sequence, the iterations of a loop are generally executed for their side effects: their modifications of variables. Loops come in two principal varieties; these differ in the mechanisms used to determine how many times they iterate.
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Iteration
An enumeration-controlled loop is executed once for every value

in a given finite set. The number of iterations is therefore known before the first iteration begins. A logically controlled loop is executed until some Boolean condition changes value. The two forms of loops share a single construct in Algol 60. They are distinct in most later languages

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Enumeration controlled loop


Enumeration-controlled loops are as old as Fortran. The Fortran syntax and semantics have evolved considerably

over time. In Fortran I, II, and IV a loop looks loop something like this: do 10 i = 1, 10, 2 ... 10 continue The number after the do is a label that must appear on some statement later in the current subroutine; the statement it labels is the last one in the body of the loop: The variable name after the label is the index of the loop.
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Enumeration controlled loop


The comma separated values after the equals sign indicate the

initial value of the index, the maximum value it is permitted to take, and the amount by which it is to increase in each iteration (this is called the step size). A bit more precisely, the loop above Meaning of a do loop is equivalent to i=1 10 ... i=i+2 if i <= 10 goto 10 Index variable i in this example will take on the values 1, 3, 5, 7, and 9 in successive loop iterations.
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Enumeration controlled loop


Compilers can translate this loop into very simple, fast code for

most machines. The loop bounds and step size (1, 10, and 2 in our example) were required to be positive integer constants or variables: no expressions were allowed. Fortran 77 removed this restriction, allowing arbitrary positive and negative integer and real expressions. Fortran 90 takes back the ability to use real numbers for loop bounds and step sizes. The problem with reals is that limited precision can cause comparisons
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Code generation for FOR loops


FOR i := first TO last BY step DO ... END can be translated as r1 := first r2 := step r3 := last L1: if r1 > r3 goto L2 . . . loop body; use r1 for i r1 := r1 + r2 goto L1 L2: A slightly better if less straightforward translation is r1 := first r2 := step r3 := last goto L2 L1: . . . loop body; use r1 for i r1 := r1 + r2 L2: if r1 r3 goto L1

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

The rt version is likely to be faster, because each of the

iterations a single conditional branch, rather than a conditional branch at the top and unconditional branch at the bottom Both of these translations employ a loop ending test that is fundamentally directional (values of index smaller than last) There may be some situation where we require to use reverse of test of end of loop Commonly, step is required to be compile time constant Ada actually limits to +1 Several languages, including Ada and pascal requires special syntax that iterates backward for i in reverse 1..10 do ... for i := 10 downto 1 do ...
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Modula-2 andModula-3 do not require special syntax for

backward loops, but insist that step be a compile-time constant so the compiler can tell the difference
In Fortran 77 and Fortran 90, which have neither a special

backward syntax nor a requirement for compile-time constant


steps, the compiler can use an iteration count variable to control the loop

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

r1 := first r2 := step r3 := max((last first + step)/step, 0) iteration count NB: this calculation may require several instructions. It is guaranteed to result in a value within the precision of the machine, but we have to be careful to avoid overflow during its calculation. if r3 0 goto L2 L1: . . . loop body; use r1 for i r1 := r1 + r2 r3 := r3 1 if r3 > 0 goto L1 i := r1 L2:
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

The use of iteration count is fundamentally depend on being

able to predict the number of iterations before the loop begins to execute This prediction is possible in languages like fortran and Ada It is not possible in other language like C and its descendants If you want to leave the loop early most languages allow break/exit statement Fortran IV allow a goto to jump into the loop Most languages specifies that bound is computed only once, before the first iteration, and kept in temporary location Subsequent changes to variables used to compute the bound have no effect on how many times that loop is iterate Many languages prohibit changes to the loop index with in the body of loop
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

If control escape the loop with break/exit, the natural value of

the index would be the current at the time of escape For normal termination index is to be the first one that executes the loop bound The header of the loop is considered to contain a declaration of the index Its type is inferred from the bounds of loop, and its scope is loop body Because index is not visible to outside, its value is not an issue Some languages specify to use arbitrary number of enumerator Common LISP provides more powerful facility with four separate set of clauses, initialize index ,test for loop, evaluate body expression and clean up at loop termination C for loop semantically logical controlled loop
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

for (i = first; i <= last; i += step) { ... } C defines this to be roughly equivalent to i = first; while (i <= last) { ... i += step; }

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

This definition means that it is the programmers responsibility to

worry about the effect of overflow on testing of the terminating condition. It also means that both the index and any variables contained in the terminating condition can be modified by the body of the loop, or by subroutines it calls, and these changes will affect the loop control. This, too, is the programmers responsibility. Any of the three sub statements in the for loop header can be null (the condition is considered true if missing). Alternatively, a sub statement can consist of a sequence of comma-separated expressions. The advantage of the C for loop over its while loop equivalent is compactness and clarity.
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

C for loop eliminate the ambiguity about index variable

It is convenient to make the index local to the body of the loop,

by declaring at headers initialization clause. For( int i= first; i<=last; i +=step){} here i is not visible to out side For loop iterates over the elements of an arithmetic sequence We may wish to iterate over the elements of any well defined set We may wish to iterate over the elements of any well-defined set Clu, python, ruby and c# allow any container abstraction to provide an iterator that enumerates its items In phython for i in range(first,last,step): Here range is built in iterator that yields the integer from first to last

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Most imperative languages, iteration involves both a special form

of for loop and a mechanism to enumerate values for loop An iterator is an ordinary object that provides methods for initialization, generation of next index value, and testing for completion for (Iterator<Integer> it = myTree.iterator(); it.hasNext();) { Integer i = it.next(); System.out.println(i); }

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Logically controlled loop


In comparison to enumeration-controlled loops, logically

controlled loops have many fewer semantic subtleties. The only real question to be answered is where within the body of the loop the terminating condition is tested. The most common approach is to test the condition before each iteration The while loop syntax in algol while condition do statement The body of the loop to be a statement list, most modern languages use an explicit concluding key word end Some language use {}

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

It is handy to be able to test the terminating condition at the

bottom of the loop Pascal introduced special syntax for this type, which was retained in modula but dropped in Ada The difference between these constructs is particularly important when the body of the loop is integer The post test loop always execute once C provides post test loop It is some times appropriate to test the terminating condition in the middle of the loop Many languages midtest can be accomplished with a special statement nested inside conditional exit in Ada, break in C

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Logically controlled loop


for (;;) { line = read_line(stdin); if (all_blanks(line)) break; consume_line(line); } Here the missing condition in the for loop header is assumed to always be true; for some reason, C programmers have traditionally considered this syntax to be stylistically preferable to the equivalent
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Recursion
Unlike control-flow, recursion requires no special syntax In any language that provide subroutines all that is required is to

permit function to call themselves or to call other function then that call back them back Recursion and iteration equally powerful means of computing Fortran 77 and certain other languages do not permit recursion A few functional languages do not permit recursion Most modern languages provides both mechanisms Iteration is more natural in imperative languages, because it is based on the repeated modification of variables Recursion is more natural in functional languages, because it does not change variable QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Recursion
To compute a value defined

by a recurrence,
int gcd(int a, int b) { /* assume a, b > 0 */ if (a == b) return a; else if (a > b) return gcd(a-b, b); else return gcd(a, b-a);

int gcd(int a, int b) { /* assume a, b > 0 */ while (a != b) { if (a > b) a = a-b; else b = b-a; } return a; }

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Tail recursion
It is sometimes argued that iteration is more efficient than

recursion It is more accurate to say that implementation of iteration is usually more efficient than implementation of recursion If a subroutine performs a tail call to itself, it is called tailrecursive For such a function dynamically allocated stack space is unnecessary Tail calls are significant because they can be implemented without adding a new stack frame to the call stack. Even functions that are not tail recursive simple transformation can produce tail-recursive code
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

The general case of the transformation employs conversion to

what is known as continuation-passing style Some specific transformations (not based on continuation-passing) are often employed by skilled users of functional languages. Detractors of functional programming sometimes argue, incorrectly, that recursion leads to algorithmically inferior

programs.
Some algorithms takes exponential time, when a linear time is

possible
int fib(int n) { int f1 = 1; int f2 = 1; int i; for (i = 2; i <= n; i++) { int temp = f1 + f2; f1 = f2; f2 = temp;}return f2;}

QIS INStITUTE OF TECHNOLOGY, ONGOLE

Applicative and normal


In applicative order execution all procedure arguments are

evaluated before passing them to a subroutine. In normal order execution, procedure arguments are evaluated after applying the procedure, and then only if the result is needed to complete the evaluation of the procedure. Scheme is an applicative-order language all the arguments to Scheme procedures are evaluated when the procedure is applied. Applicative Order: evaluate all arguments, then apply operator Normal Order: pass unevaluated expression to function evaluate only when needed for primitive operation
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

(define (square x) (* x x))

(define (sum-of-squares x y) (+ (square x) (square y))) (define (f x) (sum-of-squares x (+ x 1)))


In Applicative Order Evaluation arguments to functions get

evaluated (reduced as much as possible) before being passed to a function. Here's a trace of what would happen do a function call f defined above with arguments of 3 and (+ 3 1). (f 3) (sum-of-squares 3 (+ 3 1)) (sum-of-squares 3 4) (+ (square 3) (square 4)) (+ (* 3 3) (* 4 4)) (+ 9 16) 25 In Normal Order Evaluation a full expansion of all the function application happens first and then the arguments are evaluated. (f 3) (sum-of-squares 3 (+ 3 1)) (+ (square 3) (square (+ 3 1)) (+ (* 3 3) (* (+ 3 1) (+ 3 1))) (+ 9 (* 4 4)) (+ 9 16) 25
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

lazy evaluation or call-by-need is an evaluation strategy which

delays the evaluation of an expression until the value of this is actually required (non-strict evaluation) and which also avoids repeated evaluations (sharing) The benefits of lazy evaluation include: Performance increases due to avoiding unnecessary calculations and avoiding error conditions in the evaluation of compound expressions. The capability of constructing potentially infinite data structures The capability of defining control structures as abstractions instead of as primitives. A delayed expression is sometimes called a promise. The mechanism used to keep track of which promises have already been evaluated is sometimes called memoization
QIS INSTITUTE OF TECHNOLOGY, ONGOLE

Non-determinacy
A nondeterministic construct is one in which the choice between

alternatives (i.e., between control paths) is deliberately unspecified. in most languages, operator or subroutine arguments may be evaluated in any order. Some languages, notably Algol 68 and various concurrent languages, provide more extensive non-deterministic mechanisms, which cover statements as well.

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

QIS INSTITUTE OF TECHNOLOGY, ONGOLE

You might also like