
Structure of Programming Languages { Lecture 6 CSCI 6636 { 4536 March 10, 2020 CSCI 6636 { 4536 Lecture 6. 1/39 March 10, 2020 1 / 39 Outline 1 Expressions and Evaluation 2 Goto Statements 3 Structured Control What Kinds of Control are Needed? Structured Control Conditionals Repetition Exceptions 4 Control Expressions Conditional Expressions 5 Homework CSCI 6636 { 4536 Lecture 6. 2/39 March 10, 2020 2 / 39 Expressions and Evaluation Arithmetic Expression Syntax All programming languages support arithmetic expressions. The four primary arithmetic operations: +; −; ∗, and = are always supported. Javascript uses ∗∗, for exponentiation. APL has symbols for dozens of things. Parentheses are used to influence the order of evaluation. CSCI 6636 { 4536 Lecture 6. 3/39 March 10, 2020 3 / 39 Expressions and Evaluation Arithmetic Expression Semantics The syntax for expressions is not enough to define their meaning. We must also know the evaluation rules: In most languages, the semantics of arithmetic expressions are defined by the rules for precedence and associativity. However, these rules differ from language to language. Some languages (Lisp, Scheme) are written in fully-parenthesized prefix form. Forth is written in non-parenthesized postfix form. APL is (was) evaluated right to left, modified by parenthesized subexpressions. It very very difficult to comprehend the meaning of a complex APL expression. CSCI 6636 { 4536 Lecture 6. 4/39 March 10, 2020 4 / 39 Expressions and Evaluation Order of Evaluation: Compile Time vs. Run Time Precedence and associativity govern the order in which operands are parsed and added to the computation tree at compile time. They do NOT always govern evaluation order at run time. The order in which the run-time system evaluates the two operands of an operator, or the arguments in a function call, is defined in some languages, undefined in others. CSCI 6636 { 4536 Lecture 6. 5/39 March 10, 2020 5 / 39 Expressions and Evaluation Semantics: Order of Evaluation. In Scheme, the language semantics specify that the evaluation order is not constrained. However, it must not matter what order is used, and the result of the operation (given the same arguments) must always be the same. In C/C++, the operands/arguments can be evaluated in any order that is convenient for the compiler. This leaves freedom for an optimizer to work. The result of relying on any particular evaluation order is undefined. In Java, the order is left-to-right. In C#, the order is left-to-right. CSCI 6636 { 4536 Lecture 6. 6/39 March 10, 2020 6 / 39 Expressions and Evaluation Lazy vs. Strict Evaluation Strict Evaluation: Evaluate the expressions and statements in the order they are given in the program. Evaluate the argument-expressions before you call a function, and bind the results to the parameter name within the function. Lazy Evaluation: Do not evaluate an expression unless it is needed to produce the output. Do not evaluate a parameter until you need it. CSCI 6636 { 4536 Lecture 6. 7/39 March 10, 2020 7 / 39 Expressions and Evaluation In Praise of Laziness A result from Lambda Calculus: Outside-in evaluation is strictly more powerful than inside-out: if ( x != 0) answer = z/x; else answer = z; O-I: Evaluate if (x != 0) first, then choose one clause. I-O: Evaluate z/x first and bomb with a divide-by-zero error. Every programming language evaluates conditionals outside in. Most languages evaluate everything else inside-out. Modern functional languages use outside-in evaluation consistently; it is called lazy evaluation. Nothing is evaluated until and unless the result is needed. CSCI 6636 { 4536 Lecture 6. 8/39 March 10, 2020 8 / 39 Goto Statements Jumps and Gotos A goto statement transfers control to some other labelled statement in the program. A jump transfers control forward or backward a defined distance in the executable code. Of course, assembly languages rely on goto for conditionals and loops. The Forth assembler uses jumps to implement conditionals and loops. In Basic, all lines were given numbers reflection their proper order. The target of the goto could be any specific line number. In Fortran, labels were arbitrary identifiers, declared at the top of a program unit. InC #, statement labels are alphabetic, and written at the beginning of a line. You can also goto a case statement within a switch. A C/C++ goto is like C#, but the target cannot be a case label. CSCI 6636 { 4536 Lecture 6. 9/39 March 10, 2020 9 / 39 Goto Statements Go to considered harmful. In 1966, a paper by Boehm and Jacopini, proved that a language that provides sequencing, selection, and iteration is sufficient to write a program to compute any computable function. In 1968 Edgar Dijkstra published \Go to considered harmful". It described the relatively poorer quality of programs written by programmers who relied on goto's. Dijkstra advocated using if-then-else and while or repeat control structures because they mirror the structure of the process better than multiple go-to's. Donald Knuth responded with an article \Go to considered harmful considered harmful", which was a defense of the need for goto's to achieve larger-scale error handling and responsive execution. Dijkstra and Knuth are two of the great men in Computing, and this debate is still famous. CSCI 6636 { 4536 Lecture 6. 10/39 March 10, 2020 10 / 39 Goto Statements Structured Programming For the next ten years, textbooks pushed the idea of programming with \structured style". Using any other control statements was considered \poor technique". Fortran textbooks were published that contained clumsy, inefficient implementations of while loops and if-then-else instead of the native control statements. One-in / one-out control structures became sacred cows: essential to avoid \spaghetti code". Boolean status flags were used to control execution instead of goto's. Then C was introduced. It had a one-in/two-out control structure: a loop containing a break. By using the break effectively, the need for boolean spaghetti evaporated. Then C++ came, with exceptions. At that point, there was no longer a need for goto. CSCI 6636 { 4536 Lecture 6. 11/39 March 10, 2020 11 / 39 Goto Statements From the Delphi website, circa 1995: Delphi is a dialect of Pascal, with some OO constructs added. The Goto keyword forces a jump to a given label. It should Never be used in modern code since it makes code very difficult to maintain. It is mostly used to force a termination of heavily nested code, where the logic to safely exit would be tortuous. Never jump into or out of try statements, or into a loop or conditional block. Be careful! Use with extreme caution and only when fully justified. CSCI 6636 { 4536 Lecture 6. 12/39 March 10, 2020 12 / 39 Goto Statements Why goto Statements are Obsolete Using a goto is no longer good practice because it has bad effects on: Translation: the compiler must remember the location of all statement labels for the scope of the program, just in they are needed. To compile a goto statement, the compiler must search the list of labels. Modularity: all parts of the program between the goto and the target become part of one module. This breaks or confuses modern ideas of modularity. Debug-ability: using goto's makes it much harder to trace a program's logic, and therefore hard to debug. Maintainability: for the same reason, it is harder to modify or maintain. With the introduction of break, continue, and exceptions, there is no longer a need for goto's. CSCI 6636 { 4536 Lecture 6. 13/39 March 10, 2020 13 / 39 Goto Statements New Kinds of Spaghetti Code All major languages developed after C implement, tweak, and extend the C control structures, and support exceptions. Goto's are uniformly frowned upon, but still there. However, we now have a variety of ways to make spaghetti code without using goto. The term spaghetti code is now used to describe any program where the path of execution is not clear from the appearance of the code, and a flow chart is needed to figure out the logic. You can write spaghetti code using \structured units" if you include deeply nested logic units controlled by multiple state variables (boolean or not). And it is still poor technique. CSCI 6636 { 4536 Lecture 6. 14/39 March 10, 2020 14 / 39 Structured Control What Kinds of Control are Needed? Minimal Necessary Control Jacopini and Boehm proved that the if...then...else, while, and statement sequences form an adequate basis for programming without goto's. Procedural languages are built on this foundation. But you do not need all of these control structures: if...then...else and recursion (replacing loops and sequences) form an adequate basis for a language. Functional languages are built on this foundation. The pure functional languages are built on this foundation and do not need or support sequences or loops. CSCI 6636 { 4536 Lecture 6. 15/39 March 10, 2020 15 / 39 Structured Control What Kinds of Control are Needed? Structured vs. Unconstrained Control The control capabilities built into a language can be structured or unconstrained. A goto statement or expression is unconstrained: It can go to a target anywhere. An if...then...else statement or a while loop is structured: it has a defined beginning and end, and control flows through it in a prescribed way. Function calls are structured control because a call defines a controlled interface between two parts of a program, and control returns to the point at which the call started. Exceptions and break statements are structured because they can only end up at defined spots in the program.
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages39 Page
-
File Size-