Title: 159'331 Programming Languages
1159.331 Programming Languages Algorithms
- Lecture 7 - Imperative Programming Languages -
Part 3 - State
2State
- Important activity of an imperative language is
changing the - Internal state of the machine as represented by
the values of the program variables, and the - External state as stored in its input/output
devices (and files etc) - Sometimes the state of some output devices can
be observed eg print-out on paper - and is
called the result of the program - Statements are the commands that change the
programs state
3Assignment Statements
- Modify the value of a variable
- C i (x y ) / 2 Ada I (X Y ) / 2
- Calculates the value of the expressions (xy)/2
and assigns the result as the new value of i - Expression is called the source, the left hand
side is called the destination - Note that unlike in mathematics this is a once
off action - it does not signify a permanent
relation - i keeps it value only until the next
assignment to it - We can therefore legally have expressions like i
i 1 - Expressions have a type - can often be derived
from expression alone without having to run the
program - this is useful so that strong type
checking can be applied
4Assignment Syntax
- used in C for assignment - do not confuse
with (logical equality) - used for assignment in Ada, single used
for logical equality test - Some languages have extra syntax for assignment
- eg let x x 1 or set y 6 or PUT 17.95
in pricebook in ABC - Note that the transfer of data is not performed
until the expression is completely evaluated - This rule is important for eg overlapping slice
assignments or for expressions that evaluate with
side effects
5We are using Ada 1..N index notation here T is a
temp array used to hold the slice - invisible
to the programmer but set up probably on the
stack
See what can go wrong if we do not properly
enforce the rule to only transfer after full
expression evaluation
6Assignment Operators
- Man have the form (in EBNF style)
- ltdestinationgt ltdestinationgt ltoperatorgt
ltsomethinggt - eg I I 1 ankj1 ankj1 2
- Some language s allow some shorthand syntax
such as I 1 - C has post-increment i this actually
evaluates as an expression to the old value of
I - C has pre-increment i that evaluates to the
new (incremented) value. (likewise --i, i-- )
7- Although the post/pre increment/decrement
operators might seem hard to figure they - Do aid compiler efficiency
- Can make neater more compact program code
- Idea is definitely useful if we only need to
write ankj 2 - we do not need to
write the complicated indexing expression twice
(with the inherent risk of introducing a typing
mistake) - C has many combined assignment operators ( ,
- , ), Ada does not.
8Simultaneous Assignments
- More than one value is transferred (effectively)
simultaneously - i,j 3,5 assigns 3 to i and 5 to j
- i,j j, i might be useful to swap i and j
without having to declare an auxiliary varaible. - However can cause some semantic difficulties
- what if i and j are equal in ai , aj 3,
5 ? - Neither C nor Ada have simultaneous assignments
but ABC does.
9Expressions
- The source of the value in an assignment is an
expression - Generally expression syntax in most languages
has been designed to be as close as possible to
mathematical notation, with linearisation to
cope with subscripts etc and make our program
source code fit in a machine-readable text file - So ak becomes rendered as ak
- We can write expressions in a number of ways
Infix Notation is the way we learn at school
10Infix Notation for Expressions
- Operators have precedence so we have
conventions that tell us that - 456 is to be interpreted as 4 ( 5 6 )
- Rather than as ( 4 5 ) 6
- Becuase multiplication has higher precedence
than addition - Programming languages have many operators and
they are usually divided into levels, with some
lower-level operators having precedence over
higher-level ones - We can of course use parentheses in our
expressions to override the precedence rules.
11Use for this
This implies that a lt b c d means a lt ( ( b
c) d )
12Operator Associativity
- We usually have a convention for associating
left or right operators - Left-associative operators are executed from
left-to-right - Most are left associative eg and - so that
- a-b-c-d means ((a-b)-c)-d
- Assignment operator is right-associative
however, so that the multiple assignment - a b c 3 means a (b ( c
3) ) - Which works provided the assignment operator
returns as an expression the value being
transferred - If assignment was non-associative then a b c
would be erroneous
13Operators and Operands
- Operators with a single operand argument if you
like) are called monadic or unary - Operators with two operands are called dyadic or
binary - Almost all unary operators precede their operands
- they are called prefix operators - Likewise dyadic operators are called infix
(in-between) - An operator that follows it operand is called
postfix - An example in mathematics is the factorial
operator, 5! read as five-factorial is
1 x 2 x 3 x 4 x 5 120 - We can consider some special constants and
enumerations as zeroadic - operators with zero
operands eg pi, e etc - The degree of an operator is known as its arity
or adicity
14Conditional Expressions
- Some languages offer extra sorts of expression -
a well known example is the conditional
expression - Q IF X / 0 THEN 1/X ELSE 0
- C provides this using the ternary operator ?
- q x ! 0 ? 1/x 0
- The operator precedence ensures this is
interpreted as - q ( (x ! 0) ? (1/x) 0 )
15Operator Overloading Mixed Mode Arithmetic
- Traditionally operators overloaded heavily
- 2 x 12.5 and 1.07 x 370.18 have actually
different x-operators (integer-float and
float-float) - To cater for this mixed-mode arithmetic even
early languages which had little if any other
overloading did allow ad-hoc overloading for this - Operators have now lost their special status
and many modern languages allow overloading
more orthogonally - In Ada Put is the most heavily overloaded
operator. - In C ltlt and gtgt are overloaded to cope with
I/O of all the basic types
16Prefix Postfix Notation
- Need not only use infix classical expressions
- Some languages are set up to use the prefix or
postfix forms of expression - In prefix form the operator always comes first
and is followed by zero or more operands. In
EBNF - ltexpressiongt lt0-operand operatorgt
- lt1-operand operatorgt ltexpressiongt
- lt2-operand operator lt expressiongt lt expressiongt
-
- The arity of each operator determines how many of
the following expressions it absorbs. Needs no
parentheses but less readable than infix? - Prefix notation is used extensively in some
functional languages
17- postfix form is mirror image of the prefix form,
again in EBNF - ltexpressiongt lt0-operand operator gt
- ltexpressiongt lt1-operand operatorgt
- lt expressiongt ltexpressiongt lt2-operand
operatorgt -
- Since the order of the operands is not mirrored,
prefix and postfix notations of the same
expression need not be each others mirror image
however. - postfix corresponds closely to the order of the
machine instructions for expressions in the
computer. This stack based approach of postfix
is used in process control languages like Forth
or PostScript - You may come across the postfix form or the
Reverse Polish Notation used on some
calculators. (Especially HP)
18Think of the prefix operators as hungry is
looking (expecting) to find two operands
Postfix uses a stack approach - put 3 on the
stack put 4 on the stack, execute operator
which pops its necessary two operands off the
stack
19Lazy Evaluation
- In Functional (more often than in imperative)
languages sometimes we want to evaluate an
operand only when it is actually needed - known
as lazy evaluation - For instance in the test
- IF I lt 10 AND aI gt 0 THEN
- We do not want both operands of the AND operator
to be evaluated if I gt 10. In that case I lt 10
and we already know the result of the AND already
ie false. We do not want the aI to be
evaluated for I gt 10 as that would cause the
out of bounds error we are trying to avoid!
20- Operators with this lazy evaluation semantics are
called short-cut operators or short-circuit
operators in imperative languages. - More on Lazy evaluation when we look at
functional languages - The logical operators and the conditional
expression in C are short-cut operators. Ada has
no conditional expressions but has logical
short-cut operators. - Note that in C we can use etc
which are not short-cutted or the
form which are short-cutted. Make sure you use
the right ones!
21External State
- Assignment statements use the internal state to
modify the internal state - We use output statements (eg printf or PUT ) to
modify the external state based on the internal
state - Input statements ( eg scanf or GET) modify the
internal state based on the external state - A program that does not interact with the
external state is not very interesting! - Changing the external state might mean
interaction with a human, or another program
lt,on another machinegt lt,at a later timegt
22State Representation
- Inside the machine we have an agreed
representation for our state variables etc - For a human to interact we probably have to
convert representation eg turn into a string
using one of the formatting conventions - Unfortunately many language s do not separate
this input/output idea from the
format/conversion idea (an example of
unorthogonality) - Modern Languages will typically support
formatted or unformatted I/O - we must make a
serious decision which to use in our programs
23Character and Binary Output
- Character output or formatted output is supported
well by printf/fprintf/sprintf in C - but
beware, no strong type checking done - can result
in unexpected output! - Lots of predefined syntax to specify
different formats for numbers, decimals and
characters etc. (d f c) - Binary output is when we write out the raw bytes
of memory that represent the values of our data
- useable on our machine and our operating
system - likely not at all portable however! - Big-endian/Little-endian byte conventions differ
on different operating systems (in which order
should the 4 bytes of a 32-bit integer be stored?)
24Input
- Similar issues to output
- An additional complication - we cannot do static
type-checking on input data - type-checking has
to be done dynamically - So its all usually hidden behind a library
interface - scanf/fscanf/sscanf library functions in C
- Better having the typed arguments than having
function like I getc() , as it allows us to
do some type checking - These routines actually return the number of
values successfully read - which your program can
check - We can also have an exception raised if the
input stream contains unexpected or unreadable
junk
25Persistence
- Persistence is the idea that somehow we can make
our programs internal state persist even when
the program is halted temporarily by a
machine crash or power failure - It turns out to be hard to provide orthogonal
persistence that is portable across machines and
operating systems - Some attempts use verbose meta-type languages
to provide a semi-portable format for widely
used primitive data types. - Ongoing research area!
26State - Summary
- Bal Grune Chapter 2, Section 2.3
- Sebesta Chapter 7
- Next - Flow of Control
- Assignments
- Assignment operators
- Simultaneous assignments
- Expressions
- Infix notation
- Operator overloading and mixed mode arithmetic
- Prefix and Postfix notations
- Lazy evaluation
- External State
- Output
- Input
- Persistence