480 likes | 489 Views
Explore different control structures in programming languages, including selection, iteration, and transfer of control mechanisms. Learn their characteristics and common syntax.
E N D
Programming Languages Lecture 2
Control Structures • Any mechanism that departs from straight-line execution: • Selection: if-statements • Multiway-selection: case statements • Unbounded iteration: while-loops • Definite iteration: for-loops • Iterations over collections • transfer of control: gotos (considered harmful!) • unbounded transfer of control: exceptions, backtracking • Characteristic of Imperative languages • All you need for a universal machine: increment, decrement, branch on zero. All the rest is programmer convenience! • Not efficient on modern pipelined processors
Selection • if Condition then Statement else Statement -- Pascal, Ada • if (Condition) Statement else Statement -- C, C++ Java • Selection Expression: Condition ? Expression : Expression -- C • Characteristic of functional languages • To avoid ambiguities, use end marker: end if, fi, or bracketing { } • To deal with several alternatives, use keyword or bracketing: --Ada /* C */ if Condition then if (Condition) { Statements Statements} elsif Condition then else if (Condition) { Statements Statements} elseelse { Statements Statements} end if;
Statement Grouping • Pascal introduces begin-end pair to mark sequence • C/C++/Java abbreviate keywords to { } • Ada dispenses with brackets for sequences, because keywords for the enclosing control structure are sufficient: • for J in 1 .. N loop … end loop; • More writing => more readable • The use of grouping in C++/Java is just syntactic tradition • Another possibility (ABC, Python): make indentation significant • Nesting groups of statements if Condition thenif (Condition) if Condition thenif (Condition) { Statements Statements end if; } else else { Statements Statements end if; }
Short-Circuit Evaluation • If x is more than five times greater than y, compute z: • if x / y > 5 then z := … -- but what if y is 0? • if y /= 0 and x/ y > 5then z := … -- but operators evaluate their arguments • Solutions: • a lazy evaluation rule for logical operators (LISP, C, etc) • a control structure with a different syntax • C1 && C2 does not evaluate C2 if C1 is false • if C1 andthen C2 thenditto • C1 || C2 does not evaluate C2 if C1 is true • if C1 or else C2 thenditto
Multiway selection • Generalization of condition if from boolean to any discrete type • Can be simulated with a sequence of if-statements, but logic can become obscured. case (X) is-- any integer value (discrete but large) when integer’first .. 0 => Put_Line (“negative”); when 1 => Put_Line (“unit”); when 3 | 5 | 7 | 11 => Put_Line (“small prime”); when 2 | 4 | 6 | 8 | 10 => Put_Line (“small even”); when 21 => Put_Line (“house wins”); when 12 .. 20 | 22 .. 99 => Put_Line (“manageable”); when others => Put_Line (“Irrelevant”); end case; • All choices must be computable at compile-time
Loops • Definite Loops • for J in Integerrange 1 .. 10 loopstatementsendloop; • Indefinite Loops • while condition loopstatementsend loop; • loopstatementsend loop; • All loops can be expressed as while-loops (e.g., in C) for (i = 0; i <10; i++) … equivalent to: i=0; while (i<10) { … i++;} • Condition is evaluated at each iteration • If condition is initially false, loop is never executed while Condition loop .. end loop; • equivalent to if Condition then while Condition loop … end loop; end if;
What if we want to execute at least once? • Pascal introduces until-loop. • C/C++ use different syntax with while: while (Condition) { … } do { … } while (Condition) • Can always simulate with a boolean variable: done := False; while (not done) loop … if Condition then done := True; end loop;
Unstructured flow (Duff’s device) void send (int* to, int* from, int count) { int n = (count + 7 ) / 8; switch (count % 8) { case 0 : do { *to++ = *from++; case 7 : *to++ = *from++; case6 : *to++ = *from++; case 5 : *to++ = *from++; case 4 : *to++ = *from++; case 3 : *to++ = *from++; case 2 : *to++ = *from++; case 1 : *to++ = *from++; } while(--n >0); } What does this do? Why bother?
Breaking out • More common is the need for an indefinite loop that terminates in the middle of an iteration. • C/C++/Java: break • Break out of while, do, for, switch statements • Ada : exit statement loop-- infinite loop compute_first_part; exit when got_it; compute_some_more; end loop;
Breaking out of Nested Loops • Within nested loops, useful to specify exit from several of them • Ada solution: give names to loops • Otherwise: use a counter (Modula) or use a goto. • Outer: while C1 loop ... • Inner: while C2 loop... • Innermost: while C3 loop... • exit Outer when Major_Failure; • exit Inner when Small_Annoyance; • ... • end loop Innermost; • end loop Inner; • end loop Outer;
Definite loops • Counting loops are iterators over discrete domains: • for J in 1..10 loop … • for (int I = 0; I < N; I++ ) .. • Design issues: • Evaluation of bounds (only once, ever since Algol60) • Scope of loop variable • Empty loops • Increments other than one • Backwards iteration • non-numeric domains
The loop variable • Best if local to loop and treated as constant • Avoids issue of value at termination, and value on abrupt exit • counter : integer := 17; -- outer declaration • ... • for counter in 1 ..10 loop • do_something; -- 1 <= counter <= 10 • end loop; • … • -- counter is still 17
Different increments • The universal Algol60 form: for J from Exp1 to Exp2 by Exp3 do… • Too rich for most cases. Exp3 is most often +1, -1. • What is meaning if Exp1 > Exp2 and Exp3 < 0 ? • In C/ C++ for (int J = Exp1; J <= Exp2; J = J + Exp3) … • In Ada: for J in 1 .. N loop-- increment is +1 for J in reverse 1 .. N loop-- increment is -1 • Everything else can be programmed with while-loop
Non-numeric domains • Ada form generalizes to discrete types: for M in months loop … • General pattern for other data-types: define iterator class with primitive operations: hasNext(), next() Iterator it = Collection.Iterator(); while (it.hasNext) { element = it.next(); … } • APL avoids the need for iterators by automatically extending scalar operations over composite data types a 1 2 3 b 3 2 1 1 + a is 2 3 4 a + b is 4 4 4
Recursion • Example: int fib(int n) { return (n <= 1) ? 1 : fib(n-1) + fib(n-2); } • Tail Recursion – when function returns immediately after recursive call – can be automatically transformed into a loop • List processing with recursion int max(List<Integer> list) { if (list.isEmpty()) { return Integer.min(); } else { if (list.first() > max(list.deleteHead) { return list.first(); } else { return max(list.deleteHead(); }}}
Assignment • Assignment always produces a side effect • variable := expression; lvalue := rvalue • lvalue (left hand value) must be an address or reference. e.g., x, x[i] but not (x + 1) • rvalue (right hand value) is a value • Types must match • In Ada, assignment is a statement • In C, C++, and Java it is an expression • Initialization vs. Assignment • Combination Assignment • X = X + 1 -- a mathematical absurdity • X += 1 -- simpler and clearer
Precedence & Associativity • Most languages enforce standard mathematical rules • APL doesn’t. Evaluation is always right to left • Same for Smalltalk • C++ has 18 levels of precedence • Even if you know them all, the next maintenance programmer might not • Use parentheses
Continuations • A Continuation represents a point in the computation, including all of the state information at that point • All control structures (function calls, loops, if, exceptions, goto, etc.) can be described using continuations • Scheme supports continuations as 1st class objects
What’s ADA all about • Designed by committee for DoD • Key goals: • Readability • Strong typing • Detection of errors at compile time • Programming in the Large – Packages • Encapsulation • Separate compilation • Data Abstraction • Run-time Error Handling – Exceptions • Reliable multi-Tasking • Generic Units – parameterized types • Emphasis on Programming as a Human Activity
Hello, World • A simple Ada Program, hello.ada with text_IO; procedure hello is use text_IO; begin put(“Hello, World”); end hello;
Basic Structure of an ADA Program • Program Units • Packages, subprograms and tasks • Subprograms • Procedures (do not return a value) • Functions (return a value) • Packages • Collection of related data types functions and procedures • Provides services to clients • May use services of other packages • Defined in two parts • Package Specification (.ads, .spc) • Package Body (.adb, .bdy)
Package Specification • Contain Declarations • package X isdeclarations types subprogram specs (but not subprogram bodies)end X; • Specification provides public interface for users of the package, but no implementation details • Specification is like a contract between the package and its clients
Subprogram Specification procedure Print_In_Hex (X : Integer); function Max (A, B : Integer) return Integer; • Similar to signatures in C and C++ header files. • Headers can be generated automatically from the source code • Java does this automatically with import statement • A subprogram spec has everything you need to know to use the subprogram • A client sees only the specification • Implementation details are hidden • Implementation can be changed without affecting clients
Procedure Body • procedure H (M : Integer) isdeclarationsbeginstatementsreturn;end H; • Typical use is procedure Main is … which defines the main program • File name must match main procedure name
Function Body • function Max (A : Integer; B : Integer)return Integeris Result : Integer;beginif A > B then Result := A;else Result := B;end if;return Result;end Max;
Package Bodies • Contain Definitions • packagebody X isdeclarations subprograms local to body variables/constants local to body subprogram bodies for subprogram specs appearing in the package specbegininitialization statementsend X;
How to be a Client of a package • To access a package, use WithandUse statements:with Calendar, Text_IO;useText_IO;procedure Main is Today : Calendar.Time; put(“Today is” ); …end Main; • Use eliminates the need to specify the package name, as in Calendar.Time, when using a package member
Package Clients • Package Bodies with Calendar; package body Julian_Calendar_Stuff is … end Julian_Calendar_Stuff; • Package implemented using another package • Package Specifications • with Calendar;use Calendar;package To_Do_List is …procedure Enter (T : Time; M : String); -- Enter new item in todo list. Time is -- deadline. M is description.end To_Do_List; • Package To_Do_List extends Calendar interface
Using Ada • Write your program using any text editor • Save it in a file named myprog.adb, where myprog is the name of the main procedure in the program. • Compile your program: gnat make myprog.adb • On windows this produces a file myprog.exe, which you can execute • On Unix you will have to make the file executable using chmod a+x myprog • Ada resources on the Web: • http://www.adapower.com • http://www.adahome.com • ftp://cs.nyu.edu/pub/gnat
Writing an ADA Program • Write the package specifications • Verify that specification is usable by intended clients • Write the body • Write the clients • Last two activities are completely independent (and should not talk to one another except “via” the spec)
Ada Operators Logical Operators: and or xor Relational Operators: = /= < <= > >= Additive Operators: + – & & is concatenation on vectors and strings Unary Operators: + – not Multiplicative Operators: * / mod rem Exponentiation Operator: **
Integer Types • Type Integer is built in – But you don’t want to use it! • In ADA types are defined according to use type Day_In_Year is range 1 .. 366;type Age is range 0 .. 130;type Temperature is range -20 .. +180; • Now we can define variables of the type Today_Day : Day_In_Year;Employee_Age : Age;Machine_Room_Temp : Temperature; • Type Attributes • Integer’last, Year’last • Integer’first, Age’first • for A in Age’first … Age’last loop
Strong Typing • No dependence on implementation -- Unlike type int in C • Range of types matches problem • Get an error or warning at compile time • Age := 200; • Or an exception at runtime • Age := Age + 1000; • Cannot mix integer types: Current_Temp : Temperature; OK Current_Pressure : Pressure; OK Current_Temp := Current_Pressure + 1; Error Current_Temp := Current_Temp + Current_Pressure; Error • Type Errors detected at Compile Time
Integer Subtypes • A subtype creates a limited range • But is still the same type • subtype OK_Operating_Range is Temperature range 70 .. 80;Room_Temp : Temperature;Machine_Room_Temp : OK_Operating_Range…Machine_Room_Temp := Room_Temp; • Raises exception if Room_Temp out of range
Enumeration Types • An enumeration type is a sequence of ordered enumeration literals: • Type State is (Off, Powering_Up, On); • Type Coloris (Red, Orange, Yellow, Blue, Green); • Not integers (as in C++) S1, S2 : State; S1 := S1 + 1; – Error, but State’Pred (On) – OK, Powering_UpState’Succ (On) – OK, but raises constraint_error • Predefined enumeration type • type Boolean is (False, True); • Other Attributes include: T’First, T’Last, T’Val(n) where n is a value in T
Character Types • Built in types • Character (8-bit Latin-1) • Wide_Character (16-bit Unicode/ISO 10646) • Good enough for most purposes, but you can define your own types: • type My_Character is (‘A’, ‘B’, ‘C’, ….);
String Types • A string type is an array whose elements are a character type. • Two standard built in string types • type String is array (Natural range <>) of Character;type Wide_String is array (Natural range <>) of Wide_Character;S : String (1 .. 5) := “Hello”; • Note: Natural is a predefined subtype of Integer with bounds 0 .. Integer’Last;
Array Types • Arrays can have 1 or more subscripts • type Vector is array (Integer range 1 .. 10) of Integer;type Matrix isarray (Integer range 0 .. 10, Character range ‘A’ .. ‘Z’) of Vector; VV : Vector; MM : Matrix;…MM (5, ‘C’) := VV;
Array Attributes • A’First(N), A’Last(N), A’Length(N), A’Range(N) • N is the attribute for the Nth index • N must be static • Without a parameter, attributes refer to the first index - A’First, etc. • We can use the array range in loops for x in A’Range loop result := result + A[x]; end loop;
Unconstrained Arrays • Unconstrained array type has no bounds • type UA is array (Int range <>) of Int;-- cannot use UA to declare a variable-- instead must build a subtypesubtype UA5 is UA (1 .. 5);UAV5 : UA5 := (6,5,4,3,2);-- can also set bounds for a variableUAV2 : UA (1 .. 2);
Access Types • Access types function like pointers • But are not necessarily implemented that way • type r is access integer; • Allocate an object using new • typeAI is access all integer;Ptr : AI;…Ptr := new Integer; -- uninitializedPtr := new Integer’(12); -- initialized • To obtain value dereference: • V : Integer;…V := Ptr.all;
Declaring and Handling Exceptions • Declaring an exception • Error, Disaster : exception; • Raising an exception • raise Disaster;-- strips stack frames till a handler is found • Handling an exception • exceptionwhen Disaster => statements
Catching Exceptions • You can catch an exception at run time • begin … Machine_Room_Temp := Room_Temp …exceptionwhen Constraint_Error => recovery stuffwhen Meltdown_Error => recovery stuff …end;
Block Statement • Block statement can be used anywhere • declare -- declare section optionaldeclarationsbeginstatementsexception -- exception section optionalhandlersend;
Access Types • Access types function like pointers • But are not necessarily implemented that way • type r is access integer; • Allocate an object using new • type AI is access all integer;Ptr : AI;…Ptr := new Integer; -- uninitializedPtr := new Integer’(12); -- initialized • To obtain value dereference: • V : Integer;…V := Ptr.all;