230 likes | 339 Views
CSCI 330: Programming Language Concepts Instructor: Pranava K. Jha. Control Flow-I: Expressions. Control Flow. Basic paradigms for control flow: Sequencing Selection Iteration Procedural abstraction Recursion Concurrency Exception handling and speculation Nondeterminacy. Expressions.
E N D
CSCI 330: Programming Language ConceptsInstructor: Pranava K. Jha Control Flow-I: Expressions
Control Flow • Basic paradigms for control flow: • Sequencing • Selection • Iteration • Procedural abstraction • Recursion • Concurrency • Exception handling and speculation • Nondeterminacy
Expressions • An expression consists of • a simple object, (e.g., literal or variable), or • an operator or a function applied to a collection of operands each of which, in turn, is an expression.
Expressions • Here are common syntactic forms for operators: • Function call notation, e.g. func(A, B, C) • Infix notation for binary operators, e.g., A + B • Prefix notation for unary operators, e.g., – x • Postfix notation for unary operators, e.g. n++ in C • Cambridge Polish (prefix) notation, e.g. (* (+ A B) C) in Lisp • “Multi-word” infix, e.g., A > B?a : b in C
Ambiguity of Expression Evaluation • Which of the following is the right interpretation of a + b * c ** d ** e / f? • ((((a + b) * c) * d) ** e)/for • a + (((b * c) ** d) ** (e/f ))or • a + ((b * (c ** (d **e)))/f )
Precedence and Associativity • Operator precedence specifies that certain operator, in the absence of parentheses, group “more tightly” than other operators. • Operator associativity specifies the evaluation order of operators of the same precedence: • Left associativity: Operators are evaluated left-to-right (most common). • Right associativity: Operators are evaluated right-to-left (Fortran power operator **, C assignment operator = and unary minus). • No associativity: Parentheses must be used to specify grouping (APL, Smalltalk).
Precedence and Associativity • C++ has 17 levels - too many to remember • C has 15 levels - too many to remember • Fortran has 8 levels • Ada has 6 levels • Pascal has 3 levels - too few for good semantics • C/C++ has too many while Pascal has too few.
Pascal: Too Few Precedence Levels if A < B and C < D then … is the same as if A < (B and C) < D then … which causes compilation error. Lesson: When not sure, use parentheses!
Evaluation Order Precedence and associativity do not necessarily fix the evaluation order. • In f (a)+ b * c, either f (a) or b * c can be evaluated first. • The evaluation order of arguments in function and subroutine calls may differ, e.g. arguments evaluated from left to right or from right to left. • Evaluation order is important because of • Side effects: the evaluation of one subexpression affects the values of other subexpressions. • Code improvement: Compilers may rearrange expressions to maximize efficiency.
Evaluation Reordering Issue Computer arithmetic is not the same as mathematical arithmetic. • Rearranging expressions may lead to arithmetic overflow: assume b, d, and c are very large positive integers, then if b – c + d is rearranged into (b + d) – c, arithmetic overflow occurs. • Rearranging expressions may lead to different floating point results: floating point value of b – c + d may differ from that of b + d – c.
Design Choices for Expression Evaluation • Java: Expression evaluation is always left to right and overflow is always detected. • C#: Expression evaluation is always left to right and runtime check can be enabled or disabled. • Pascal: Expression evaluation is unspecified and overflows are always detected. • C/C++: Expression evaluation is unspecified and overflow detection is implementation-dependent.
Expression Evaluation • Short-circuit evaluation may save significant amounts of time in certain situations. • if (very expensive function) && (very unlikely condition) . . • Consider (a < b) && (b < c): If a >= b there is no point evaluating whether b < c because (a < b) && (b < c) is automatically false. Other similar situations if (b != 0 && a/b == c) ... if (*p && p->foo) ... if (f || messy()) ...
Assignments Fundamental difference between imperative and functional languages: • Imperative: “computing by means of side effects” • Computation is an ordered series of changes to values of variables in memory (state). • Control flow is influenced by run-time testing values of variables. • Expressions in functional languages are referentially transparent.
Assignments • A side effect is some permanent state change caused by execution of function • some noticeable effect of call other than return value • in a general sense, assignment statements provide the ultimate examples of side effects – they change the value of a variable • SIDE EFFECTS ARE FUNDAMENTAL TO THE WHOLE VON NEUMANN MODEL OF COMPUTING. • In (pure) functional languages, or logic languages, or dataflow languages, there are no such changes. • These languages are called SINGLE-ASSIGNMENT languages.
Assignments • Side effects are a particular problem if they affect state used in other parts of the expression in which a function call appears • Several languages outlaw side effects for functions • easier to prove things about programs • closer to Mathematical intuition • easier to optimize • (often) easier to understand
L-Values vs. R-Values • The left-hand side of an assignment is an l-value which is an expression that should denote a location, e.g., • array element a[2] • a variable foo • a dereferenced pointer *p. • The right-hand side of an assignment is an r-value which is an expression that should denote a value , e.g., • a literal constant • a variable • an arithmetic expression.
Value Model vs. Reference Model • Languages that adopt the value model copy values into locations. • Languages that adopt the reference model copy references, resulting in shared data values via multiple references. b := 2; c := b; a := b + c;
Expression Evaluation Variables as values vs. variables as references • value-oriented languages • C, Pascal, Ada • reference-oriented languages • most functional languages (Lisp, Scheme, ML) • Clu, Smalltalk • Algol-68 halfway in-between • Java deliberately in-between • built-in types are values • user-defined types are objects - references
Expression Evaluation Expression-oriented vs. statement-oriented languages • expression-oriented: • functional languages (Lisp, Scheme, ML) • Algol-68 • statement-oriented: • most imperative languages • C halfway in-between • allows expression to appear instead of statement
Expression Evaluation • Orthogonality • Features that can be used in any combination • Meaning is consistent if (if b != 0 then a/b == c else false) then ... if (if f then true else messy()) then ... • Initialization • Pascal has no initialization facility (assign) • Aggregates • Compile-time constant values of user-defined composite types
Special Cases of Assignments Initialization: • Explicit initialization, e.g. definite assignment requirement in Java • Implicit initialization, e.g. global variables or arrays are assigned 0’s in C • Constructors in most object-oriented programming languages.
Special Cases of Assignments (contd.) • Combinations of assignment operators • Compiler produces better code, because the address of a variable is only calculated once, e.g., in C/C++/C#/Java a+ = b is equivalent to a = a + b • Avoid the complication of side-effects, e.g., f [i + +]+ = 1 is different from f [i + +] = f [i + +] + 1 • Multi-way assignments in Python, ML, and Perl • a; b = c; d assigns c to a and d to b simultaneously. • a; b = b; a swaps a with b —o—