Title: Expressions
1Expressions Assignments
- One of the original intentions of computer
programs was the evaluation of mathematical
expressions - languages would inherit much from math
conventions - expressions are constructed from math operators,
operands, parentheses, functions - Design issues
- what are the precedence and associativity rules?
- what order are operands evaluated?
- are there side effects?
- is operator-overloading available?
- what type mixing is allowed?
- All expressions consist of operators and
operands, 3 forms of operators - Binary (2 operands, the standard form of
mathematical operator) - Unary (1 operand as in Cs i or in unary as
in -5) - Ternary (3 operands, as in Cs conditional
statement) - Expressions requiring fetching the operator
followed by operands, then applying the operator
to those operands
2Precedence Rules and Associativity
FORTRAN C-languages Ada Ruby
Highest postfix , -- ,
abs , / prefix , --
, /, mod, rem unary , - , -
unary , - unary ,-
, /, , /, binary
,- binary , - Lowest
binary , -
( and ) have the highest precedence in all
languages
- If two or more operators are of the same
precedence, then they are applied based on
associativity - all languages use left-to-right associativity
except when dealing with exponent and unary
operators - in FORTRAN, exponent is the only right-to-left
operator - in Ada, abc is illegal and so most be
parenthesized - NOTE in Ada, unary has lower precedence than
mod, so a mod b is not the same as (a mod b) - in C-langauges, /-- and unary /- are right
associative and there is no exponent operator - In VB, exponent () is left associative
3Side Effects
- A side effect is when a function changes a
parameter passed to it - or changes a global variable
- This may lead to associativity not being
maintained, for instance in - A Fun(A)
- if Fun(A) does not alter A, then the order of
evaluation between A and Fun(A) is unimportant - but if Fun changes A, then A Fun(A) lt gt Fun(A)
A - Side effects can occur when the parameter is
passed by reference (a pointer) - side effects become unimportant if you require
that any function call be located at the end of
an expression - some languages disallow side effects (that is,
you are not able to pass pointers to pointers to
functions, or use global vars in functions) - Here is how some languages deal with side effects
- C/C side effects are allowed to leave the
language flexible - FORTRAN 77 expressions with function calls are
legal only if the function does not change the
value of any operands in the expression - Pascal and Ada allow all side effects
- Java operands evaluated left-to-right,
programmer can avoid side effects by placing
function calls to the right in an expression
4Overload Operators
- When the same operator is used for different
types - arithmetic operators (, -, , /) are all used
for byte, short, int, long, float and double, so
they are all overloaded - however, for each, the implementation differs
- overloading can aid readability and writability
but requires type checking - may also be used for and, union or string
concatenation - is overloaded in C/C for pointer
dereferencing - is overloaded in C/C to generate an address
and bitwise AND - in cases where overloading causes the type of
operation to differ (addition versus
concatenation, dereferencing versus
multiplication), then overloading damages
readability - the compiler must choose the correct meaning of
the operator given operand types - Question can the programmer overload an
operator? - available in Ada, C, FORTRAN 95, Common Lisp,
C - C restricts which operators can be overloaded
(., ., , ?, sizeof)
5Type Conversions/Coercions
- Narrowing going from a larger type to smaller
type (e.g. int to short int) - narrowing is rarely safe
- Widening going from a smaller type to larger
- widening is almost always safe however consider
going from a 32-bit int to a 32-bit float, while
this is thought of as widening, you might lose
precision! - Coercion
- implicit type conversion initiated by the
compiler - for instance, doing x y where x is an int and y
is a float - Casts (in C/C, Java, C) are explicit
conversion commands - Ada and Modula-2 also have them as in Float(X)
- Ada does not do implicit coercions, so the
assignment below is not legal since cannot
apply to both an integer and a float - A Integer
- B, C Float
- C A B
- Java also has methods to perform explicit
conversions - Most languages have at least round and truncate
operations
6Relational and Boolean Expressions
- Evaluate to True/False rather than numeric
- relational operators always have lower precedence
than arithmetic so that the relational comparison
is performed after any arithmetic operations (ex.
a1 gt b-2) - boolean operators usually have lower precedence
than relational operators except possibly NOT
Operation Ada C/Java FORTRAN77
Equal .EQ. Not equal /
! .NE. Greater Than gt gt .GT. Less
Than lt lt .LT. Greater/Equal gt gt
.GE. Less/Equal lt lt .LE. AND and
.AND. OR or .OR. NOT not
! .NOT.
The FORTRAN abbreviations originated because
early keypunches did not have lt, gt symbols
available FORTRAN 95 continued to use the
abbreviations, but also included , ltgt, lt, gt,
lt, gt JavaScript/PHP add and ! for
equality/inequality with coercion disabled
7Example expressions
- In FORTRAN
- AB .GT. 2 C . AND. K .NE. 0
- order of operations , , GT, NE, AND
- In Ada
- A gt B and A lt C or K0
- is illegal because and/or have equal precedence
and therefore must parenthesize, the proper
expression is - (A gt B and A lt C) or K 0
- with order of precedence as lt, gt and performed
first in a left-to-right order, followed by and
followed by or - In C a gt b gt c
- is legal as a gt b returns a 1 or 0 which is then
compared to c
C-language operator precedence
postfix,-- prefix , --, ! unary
, - , /, binary , - lt, gt,
lt, gt , !
8Short Circuiting
- A short circuited evaluation of an expression
occurs if the result can be determined without
evaluating the entire expression - (13 A) (B / 13 - 1)
- if A0, then the expression evaluates to 0 and
the right term (B / ) is ignored - (A gt 0) and (B lt 10)
- if A lt 0 then the entire expression is false
- We often take advantage of short circuiting to
simplify code to avoid errors - while(ptr!NULL ptr-gtvalue gt target) ptr
ptr-gtnext - without short circuiting, we either risk an error
arising (if ptr is NULL and we still try to
evaluat ptr-gtvalue, then we get an error) or we
have to separate this into a while loop with an
if statement inside it - In Ada, short-circuiting is available using AND
THEN and OR ELSE - While (Index lt Listlen) and then (Listindex /
key) do - In Modula-2, Turbo Pascal, AND and OR are
short-circuited - this is not true of Standard Pascal
- In C, C, Java, and are short circuited
and and are not - one must be cautious in C-languages when using
short circuiting, consider this - (a gt b) ((b) / 3)
- if a gt b is false, the right side of the
expression is not performed and so b remains
unchanged!
9The Assignment Statement
- Syntactic form
- lttarget_vargt ltass_opgt ltexprgt
- FORTRAN, BASIC, PL/I, C, C, Java, C, Python
all use for ltass_opgt whereas Ada/Algol/Pascal/Mo
dula all use - in PL/I, the use of is confusing as it is also
used for equal to leading to - A B C
- this means set A equal to true if B C or false
if B does not equal C - Some languages allow for multiple assignments in
one statement - PL/I SUM, TOTAL 0
- C, C, Java can use incr/decr operators and
nested assignments - a b(c d / b) - 1
- b gets b1, c gets d / b (old b), a gets b c -
1 (old b, old c) - while((ch getchar( )) ! EOF)
- Python a, b, c ltexpr1gt, ltexpr2gt, ltexpr3gt
- Common Lisp (setf a b c d) same as ab, cd
- Perl (a, b, c) (1, 2, 3)
- C/C/ Java also have the conditional target
(ternary operator) - flag ? count1 count2 0