Expressions vs statements Every expression results in a value (+side-effects?): 1+2, str.length(), f(x)+1 Imperative prg: Statements have just side-effects, no value: (for, if, break) Assignment is statement/expression depending on language (a=b=c) Often expression can act as a statement, result is discarded (1+2;) Functional prg: No side-effects no statements, just expressions (Haskell: let x = if x>0 then x else -x) 148
Expression evaluation Common subexpressions can usually be optimized, as can constant expressions Intermediate results use memory too! Precedence does not determine execution order! Side-effects can complicate evaluation (common mistake in C++) 149
How many control structures are needed at minimum? 1: Conditional jump [goto-statement] 2: Choice of two control-flows [if-statement] Logically controlled iteration [whilestatement] Many languages have several To improve readability and writability If the language is large, only some subset is often used 150
Pascal: C/C++: casestructure case E of L1: S1; L2: S2;... Ln: Sn; end switch ( E ) { case L1: S1; case L2: S2; break;... case Ln: Sn; } Conditional statements based on equality case labels (possible values) Design issues: Type of the expression? Values of the case labels? constants? Enumerated types? Mutually exclusive? Other options executed? default, else, others -branching 151
Implementing conditionals If-statement compiling: Condition truth value used in conditional jump case-statement: Small number of case-tags Compile as if-then-elsif Reasonable number of tags that cover the set of values Jump address table Empty values use the default address Large number of tags, and even larger set of values Hash-table or other dictionary 152
Implementing if Pascal: if ( ( A > B ) and ( C > D ) ) or ( E <> F ) then then_clause else else_clause Resulting pseudoassembly: r1 := A r2 := B r1 := r1 > r2 r2 := C r3 := D r2 := r2 > r3 r1 := r1 & r2 r2 := E r3 := F r2 := r2 <> r3 r1 := r1 r2 if r1 = 0 goto L2 L1: then_clause goto L3 L2: else_clause L3: 153
Jump address table Each case-tag corresponds to an index Index points to an address for jumping when condition evaluates as the case-tag Code is found in the address case E of 1: S1; 2: S2; 3: S3; 4: S4; end 1 2 3 4... S1 S2 S3 S4... 154
ML and Haskell: piecewise functions Peculiarities of choice fun fact(0) = 1 fact(n : int) : int = n * fact(n-1); fact 0 = 1 fact n = n * fact(n-1) Smalltalk boolean objects Boolean inherited classes True and False Their methods iftrue and iffalse, conditional code as parameter, either executed or not i < 2 iftrue: [ Transcript show: 'It is small' ]. 155
Repetition statements generalisation (Ada): loop -- statements exit when cond; -- statements end loop; Definite/bounded iteration [counter] The number of repetitions is known before starting Indefinite/unbounded iteration [logical condition] Number of iterations is determined during the iteration Test of ending at the end or the beginning 156
Definite/ bounded iteration Contains loop index (loop counter) for index from expr1 to expr2 do stmt end Semantics vary between languages Is the index value defined after execution? Can the index value be changed within the body? Are upper and lower values evaluated only once? Iterating an array 157
Indefinite/ unbounded iteration End condition evaluation beginning 0 n iterations end 1 n iterations Ending logic: while: continue if true until: end if true Pascal: s := 0; Read ( nm ); while nm >= 0 do begin s := s + nm; Read ( nm ); end; s := 0; Read ( nm ); repeat s := s + nm; Read ( nm ); until luku < 0; 158
Peculiarities of iteration Smalltalk iteration is an intermediate method, code block as parameter, with the value of the index as its parameter Interval from: 1 to: 10 do: [ i Transcript show: i ] Undefined iteration is a method of a code block [ Transcript show i. i := i-1. i > 0 ] whiletrue. [ i > 0 ] whiletrue: [ Transcript show i. i := i-1. ] 159
Loop control Ada: OUTER_LOOP: for row in 1..max_rows loop INNER_LOOP: for col in 1..max_cols loop sum := sum + mat ( row, col ); exit OUTER_LOOP when sum > 1000; end loop INNER_LOOP; end loop OUTER_LOOP; C/C++: while ( sum < 1000 ) { getnext ( value ); if ( value < 0 ) continue; sum += value; } while ( sum < 1000 ) { getnext ( value ); if ( value < 0 ) break; sum += value; } 160
Loops and data structures Ada: C++ Java: C#: type Days is ( Mon, Tue, Wed, Thu, Fri, Sat, Sun ); for Index in Days loop... end loop; int[] tbl = {1, 2, 3}; // C++: int tbl[] = {1, 2, 3}; for (int i : tbl) {... } String [ ] strlist = { Bob, Carol, Ted }; foreach ( String name in strlist ) Console.WriteLine ( Name:, name ); Lambdas and library functions used as loops Haskell: let tbl = [1, 2, 3] in map (\x -> x*x + 1) tbl 161
Generators (Python) Functions are "single-use": parameters in, return value out Generators are "multi-use": they can produce multiple values (when needed) Generator is an iterator, which is used to access (and calculate) the values Generator functions return generators (iterators) (Or: normal data structures can be viewed as generator functions with pre-calculated values, accessed through iterators) 162
Generators, example def firstn(n): num = 0 while num < n: yield num # "return", ready to continue num += 1 i = firstn(10) print(next(i)) ; print(next(i)) j = (x*x for x in i) print(next(j)) 163
Benefits of generators Avoid creating big data structures, create values when necessary Allow lazy evaluation (almost) Allow pipeline programming: actions (generators) are chained together, feeding values to next action (generator) 164