1.Chapter 7 Expressions and Assignment Statements
2.Augment Sebesta Material Programming Languages-Cheng (Fall 2004) http://www.cse.msu.edu/~cse452/Fall2004/Lectures/07-expressions.ppt Type Systems and Structures- Bermúdez https://www.cise.ufl.edu/class/cop5556sp16/Lecture_20.ppt
3.Copyright © 2015 Pearson. All rights reserved. 1- 3 Chapter 7 Topics Introduction Arithmetic Expressions Overloaded Operators Type Conversions Relational and Boolean Expressions Short-Circuit Evaluation Assignment Statements Mixed-Mode Assignment
4.Copyright © 2015 Pearson. All rights reserved. 1- 4 Introduction Expressions are the fundamental means of specifying computations in a programming language To understand expression evaluation, need to be familiar with the orders of operator and operand evaluation Essence of imperative languages is dominant role of assignment statements
5.Copyright © 2015 Pearson. All rights reserved. 1- 5 Arithmetic Expressions Arithmetic evaluation was one of the motivations for the development of the first programming languages Arithmetic expressions consist of operators, operands, parentheses, and function calls
6.Copyright © 2015 Pearson. All rights reserved. 1- 6 Arithmetic Expressions: Design Issues Design issues for arithmetic expressions What are the Operator precedence rules? What are the Operator associativity rules? What is the Order of operand evaluation? What are the Operand evaluation side effects? Does the language allow user-defined Operator overloading? What type/mode mixing is allowed expressions?
7.Copyright © 2015 Pearson. All rights reserved. 1- 7 Arithmetic Expressions: Operators A unary operator has one operand A binary operator has two operands A ternary operator has three operands
8.Arithmetic Expressions Types of operators A unary operator has one operand: - x A binary operator has two operands: x + y Infix: operator appears between two operands Prefix: operator precede their operands A ternary operator has three operands: (x > 10)? 0 : 1 Evaluation Order Operator evaluation order Operand evaluation order
9.Operator Evaluation Order Four rules to specify order of evaluation for operators Operator precedence rules Define the order in which the operators of different precedence levels are evaluated (e.g., + vs * ) Operator associativity rules Define the order in which adjacent operators with the same precedence level are evaluated (e.g., left/right associative) Parentheses Precedence and associativity rules can be overriden with parentheses Conditional Expressions ( ?: operator in C/C++/Perl) Equivalent to if-then-else statement
10.Copyright © 2015 Pearson. All rights reserved. 1- 10 Arithmetic Expressions: Operator Precedence Rules The operator precedence rules for expression evaluation define the order in which “adjacent” operators of different precedence levels are evaluated Typical precedence levels parentheses unary operators ** (if the language supports it) *, / +, -
11.Copyright © 2015 Pearson. All rights reserved. 1- 11 Arithmetic Expressions: Operator Associativity Rule The operator associativity rules for expression evaluation define the order in which adjacent operators with the same precedence level are evaluated Typical associativity rules Left to right, except **, which is right to left Sometimes unary operators associate right to left (e.g., in FORTRAN) APL is different; all operators have equal precedence and all operators associate right to left Precedence and associativity rules can be overriden with parentheses
12.Copyright © 2015 Pearson. All rights reserved. 1- 12 Expressions in Ruby and Scheme Ruby All arithmetic, relational, and assignment operators, as well as array indexing, shifts, and bit-wise logic operators, are implemented as methods - One result of this is that these operators can all be overriden by application programs Scheme (and Common Lisp) All arithmetic and logic operations are by explicitly called subprograms a + b * c is coded as (+ a (* b c))
13.Copyright © 2015 Pearson. All rights reserved. 1- 13 Arithmetic Expressions: Conditional Expressions Conditional Expressions C-based languages (e.g., C, C++) An example: average = (count == 0)? 0 : sum / count Evaluates as if written as follows: if (count == 0) average = 0 else average = sum /count
14.Expression Evaluation Expressions consist of: Simple object, or Operator function applied to a collection of expressions. Structure of expressions: Prefix (Lisp), Infix (most languages) and most popular postfix (Postscript, Forth, some calculators) Infix Raises some issues. Precedence: Specify that some operators, in absence of parentheses, group more tightly than other operators.
15.Expression Evaluation (cont’d) Associativity: tie-breaker for operators on the same level of precedence. Left Associativity: a+b+c evaluated as ( a+b )+c Right Associativity: a+b+c evaluated as a+( b+c ) Different results may or may not accrue: Generally: ( a+b )+c = a+( b+c ), but (a-b)-c <> a-(b-c ) Specify evaluation order of operators. Generally, left-to-right (Java), but in some languages, the order is implementation-defined (C).
16.Copyright © 2015 Pearson. All rights reserved. 1- 16 Arithmetic Expressions: Operand Evaluation Order Operand evaluation order Variables: fetch the value from memory Constants: sometimes a fetch from memory; sometimes the constant is in the machine language instruction Parenthesized expressions: evaluate all operands and operators first The most interesting case is when an operand is a function call
17.Operand Evaluation Order When do we evaluate operand? Variables are evaluated by fetching their values from memory Constants Sometimes, constants are evaluated by fetching its value from memory; At other times, it is part of the machine language instruction Parenthesized expressions If operand is a parenthesized expression, all operators it contains must be evaluated before its value can be used as an operand Function calls Must be evaluated before its value can be used as an operand
18.Operators and Precedence in Various Languages C is operator-richer than most languages 17 levels of precedence. some not shown in figure: type casts, array subscripts, field selection (.) dereference and field selection a->b, equivalent to (*a).b Pascal:<, <=, …, in (row 6)
20.Pitfalls in Pascal if a < b and c < d then ... is parsed as if a < (b and c) < d . Will only work if a,b,c are booleans.
21.Pitfalls in C a < b < c parsed as (a < b) < c, yielding a comparison between (a < b) (0 or 1) and c.
22.Copyright © 2015 Pearson. All rights reserved. 1- 22 Arithmetic Expressions: Potentials for Side Effects Functional side effects: when a function changes a two-way parameter or a non-local variable Problem with functional side effects: When a function referenced in an expression alters another operand of the expression; e.g., for a parameter change: a = 10; /* assume that fun changes its parameter */ b = a + fun(&a);
23.Copyright © 2015 Pearson. All rights reserved. 1- 23 Functional Side Effects Two possible solutions to the problem Write the language definition to disallow functional side effects No two-way parameters in functions No non-local references in functions Advantage: it works! Disadvantage: inflexibility of one-way parameters and lack of non-local references Write the language definition to demand that operand evaluation order be fixed Disadvantage : limits some compiler optimizations Java requires that operands appear to be evaluated in left-to-right order
24.Operand Evaluation Order Functional Side Effects When function changes one of its params/global variable a + fun(a) If fun does not have the side effect of changing a , then the order evaluation of the two operands, a and fun(a), does not matter If fun does have the side effect of changing a , order of evaluation matters Two Possible Solutions : Disallow functional side effects in the language definition No two-way parameters in functions No non-local references in functions Advantage: it works! Disadvantage: No more flexibility Write language definition to demand fixed operand evaluation order Disadvantage: limits some compiler optimizations
25.A program has the property of referential transparency if any two expressions in the program that have the same value can be substituted for one another anywhere in the program, without affecting the action of the program result1 = (fun(a) + b) / (fun(a) – c); temp = fun(a); result2 = (temp + b) / (temp – c); If fun has no side effects, result1 = result2 Otherwise, not, and referential transparency is violated Referential Transparency Copyright © 2015 Pearson. All rights reserved. 1- 25
26.Advantage of referential transparency Semantics of a program is much easier to understand if it has referential transparency Because they do not have variables, programs in pure functional languages are referentially transparent Functions cannot have state, which would be stored in local variables If a function uses an outside value, it must be a constant (there are no variables). So, the value of a function depends only on its parameters Referential Transparency (continued) Copyright © 2015 Pearson. All rights reserved. 1- 26
27.Copyright © 2015 Pearson. All rights reserved. 1- 27 Overloaded Operators Use of an operator for more than one purpose is called operator overloading Some are common (e.g., + for int and float ) Some are potential trouble (e.g., * in C and C++) Loss of compiler error detection (omission of an operand should be a detectable error) Some loss of readability
28.Copyright © 2015 Pearson. All rights reserved. 1- 28 Overloaded Operators (continued) C++, C#, and F# allow user-defined overloaded operators When sensibly used, such operators can be an aid to readability (avoid method calls, expressions appear natural) Potential problems: Users can define nonsense operations Readability may suffer, even when the operators make sense
29.Copyright © 2015 Pearson. All rights reserved. 1- 29 Type Conversions A narrowing conversion is one that converts an object to a type that cannot include all of the values of the original type e.g., convert float to int A widening conversion is one in which an object is converted to a type that can include at least approximations to all of the values of the original type e.g., convert int to float