COS 333: Chapter 7, Part 2

Willem van Heerden
1 Sept 202140:12

Summary

TLDRThis lecture delves into expressions and assignment statements, covering relational and boolean expressions, short-circuit evaluation, and various assignment statements. It explains operator coercion in languages like JavaScript and PHP, the importance of distinguishing between equality and assignment, and the use of compound and unary assignment operators. The lecture also touches on the nuances of assignment expressions in different programming languages, the potential pitfalls of short-circuit evaluation, and the concept of mixed mode assignments, highlighting the need for understanding type coercion in programming.

Takeaways

  • πŸ“˜ The lecture focuses on expressions and assignment statements, building upon the concepts introduced in the previous lecture.
  • πŸ” It discusses relational and boolean expressions, explaining how they define relationships or test for true/false conditions between operands.
  • 🌐 The script highlights the difference in behavior between languages like JavaScript, PHP, and C++/Java in terms of operator coercion during equality and inequality checks.
  • πŸ†š It emphasizes the use of '===' and '!==' in JavaScript and PHP for strict equality and inequality checks without type coercion.
  • πŸ”„ The concept of short-circuit evaluation is introduced, explaining how it can prevent unnecessary evaluation of operands in expressions.
  • πŸ’‘ Potential issues arising from the lack of short-circuit evaluation are presented, such as accessing invalid array indices.
  • πŸ›  The lecture covers various programming languages' approaches to short-circuit evaluation, with some languages providing options for programmers.
  • πŸ”„ Assignment statements are detailed, including the different operators and syntax used across languages, and the potential for ambiguity with the '=' operator.
  • πŸ”„πŸ”„ Compound and unary assignment operators are explained, showing shorthand methods for incrementing or decrementing values.
  • πŸ”€ The script touches on the precedence and associativity of unary assignment operators, which is important for understanding expression evaluation.
  • πŸ”€πŸ”„ The use of assignment statements as expressions in some languages, like C, is highlighted, noting the potential for errors and side effects.

Q & A

  • What topics are covered in the second lecture on chapter seven?

    -The second lecture on chapter seven covers relational and boolean expressions, short circuit evaluation, assignment statements, and mixed mode assignment.

  • What are relational expressions and what types of operators are included in this category?

    -Relational expressions define some sort of relationship between two operands. They include equality and inequality expressions, as well as operators such as less than (<), less than or equal to (<=), greater than (>), and greater than or equal to (>=).

  • How does operator coercion affect equality and inequality checks in JavaScript and PHP?

    -In JavaScript and PHP, operator coercion allows for the comparison of operands of different types by converting one operand to the type of the other, enabling the comparison to take place.

  • What is the difference between using triple equals (===) and double equals (==) in JavaScript for equality checks?

    -The triple equals (===) performs an equality check without type coercion, comparing both value and type, while the double equals (==) performs the check with type coercion, meaning the operands may be converted to comparable types before comparison.

  • What is short circuit evaluation and why is it used?

    -Short circuit evaluation allows an expression to produce a result without necessarily evaluating all operands and operators within the expression. It is used to prevent unnecessary evaluations, especially when the outcome of an expression can be determined without evaluating all parts.

  • What potential problems can arise if short-circuit evaluation is not supported in a programming language?

    -If short-circuit evaluation is not supported, it may lead to runtime errors, exceptions, or invalid operations when attempting to evaluate operands that should have been skipped, potentially causing program termination or unexpected behavior.

  • How do different programming languages handle short circuit evaluation?

    -Languages like C, C++, and Java have standard boolean operators that are short-circuit evaluated, while bitwise boolean operators are not. Languages such as Ruby, Perl, ML, F#, and Python have all of their logical operators short-circuit evaluated.

  • What is a conditional target in the context of assignment statements?

    -A conditional target is a feature supported by some programming languages like Perl, where an assignment can be made to one of multiple targets based on a condition, using a ternary-like operator syntax.

  • What is the general syntax for an assignment statement and what is the purpose of the assignment operator?

    -The general syntax for an assignment statement involves an assignment operator, a left operand (target variable), and a right operand (expression). The assignment operator is used to store the value of the expression in the target variable.

  • What are the problems associated with using assignment as an expression?

    -Using assignment as an expression can reduce error detection capabilities, as a mistaken assignment operator may be used instead of a comparison operator. Additionally, it can cause side effects if the assignment changes the value of a variable that should not be altered in that context.

  • How do mixed mode assignments differ between languages like Java and C# compared to Fortran, C, and Perl?

    -In Java and C#, only widening coercions are allowed in assignments, which is a safer approach as it prevents potential data loss due to narrowing coercions. In contrast, Fortran, C, and Perl allow any coercion, including narrowing, which can lead to data loss or unexpected results.

  • Why does Ada perform fewer coercions than most other high-level programming languages in assignments?

    -Ada performs fewer coercions to ensure type safety and prevent potential data loss or unexpected behavior. It does not perform any assignment coercions, requiring explicit conversions when necessary.

Outlines

00:00

πŸ“˜ Lecture Introduction to Expressions and Assignment Statements

This paragraph introduces the second lecture on chapter seven, focusing on expressions and assignment statements. It recaps the previous lecture's content on arithmetic expressions, overloaded operators, and type conversions. The lecture's agenda includes relational and boolean expressions, short circuit evaluation, assignment statements, and mixed mode assignments. Relational expressions are explained, highlighting their role in defining relationships between operands, such as equality and inequality. The paragraph also discusses operator coercion in languages like JavaScript and PHP, which allows for type conversion during equality or inequality checks.

05:01

πŸ” Deep Dive into Relational and Boolean Expressions

The second paragraph delves deeper into relational and boolean expressions, explaining how they work in different programming languages. It discusses the use of equality and inequality operators with and without coercion, using JavaScript, PHP, and Ruby as examples. The concept of short circuit evaluation is introduced, explaining how it can prevent unnecessary evaluation of operands in expressions, with an example of an arithmetic expression involving multiplication. Potential issues arising from the lack of short circuit evaluation are also highlighted, using an array iteration example that could lead to runtime errors if not properly handled.

10:03

⚠️ Potential Problems with Short Circuit Evaluation

This paragraph explores the potential problems that can arise from both the lack of support for short circuit evaluation and its misuse when side effects are expected within expressions. It provides examples of how short circuit evaluation can prevent unnecessary computation, but also how it can lead to issues if the programmer relies on side effects occurring every time an expression is evaluated. The paragraph discusses how different programming languages handle short circuit evaluation, with some supporting it for all logical operators and others providing options for both short-circuit and non-short-circuit evaluation.

15:05

πŸ”„ Understanding Assignment Statements and Their Varied Forms

The fourth paragraph discusses the general syntax and forms of assignment statements across different programming languages. It explains the use of assignment operators, the distinction between left and right operands, and how assignment can involve expressions. The paragraph also touches on the ambiguity that can arise from overloading the single equals operator for both assignment and relational equality tests, and how different languages address this issue, such as C-based languages introducing the double equals operator for relational comparisons.

20:07

πŸ”„ Advanced Assignment Concepts: Compound and Unary Operators

This paragraph examines advanced assignment concepts, including compound assignment operators that allow for shorthand incrementing or decrementing of values, and unary assignment operators that combine increment or decrement operations with an assignment. It explains the precedence and associativity of these operators, highlighting the difference between prefix and postfix increments and decrements, and their impact on the evaluation order in expressions.

25:08

πŸ“‹ Assignment as Expression and Its Implications

The sixth paragraph discusses how assignment statements can also serve as expressions, which has implications for their use in conditions and loops. It explains that the result of an assignment is the value that has been assigned, allowing it to be used within other expressions. The paragraph also points out potential issues with this approach, such as reduced error detection capabilities and the risk of unintended side effects when assignments are used in conditions.

30:10

πŸ”„ Multi-target Assignments and Functional Programming Assignments

The final paragraph explores multi-target assignments, which allow for the simultaneous assignment of multiple values to multiple variables, and how this differs in functional programming languages. It demonstrates the power of single-step swap operations without intermediary variables and contrasts assignment operations in imperative and functional programming paradigms, highlighting the unique binding mechanisms in languages like ML and Haskell.

Mindmap

Keywords

πŸ’‘Expressions

Expressions in programming are combinations of values, variables, operators, and function calls that are evaluated to a single value. They are fundamental to almost all programming languages and are used extensively in the script to discuss various types such as arithmetic, relational, and boolean expressions. For example, the script mentions 'arithmetic expressions' when discussing basic mathematical operations and 'relational expressions' for defining relationships between operands, like equality or inequality.

πŸ’‘Assignment Statements

Assignment statements are used to assign a value to a variable. They are a core concept in programming, allowing data to be stored and manipulated. In the script, assignment statements are highlighted as a main topic, with discussions on their syntax and different forms, such as simple assignments and compound assignments (e.g., '+=' for incrementing a value).

πŸ’‘Relational Operators

Relational operators are used to compare two values and determine a relationship between them, such as whether one value is greater than, less than, equal to, or not equal to another. The script discusses how these operators function in languages like JavaScript and PHP, including the concept of 'operator coercion' where operands of different types are converted to allow for comparison.

πŸ’‘Boolean Expressions

Boolean expressions are those that result in a Boolean value, either true or false. They are crucial for decision-making structures in programming, such as conditionals and loops. The script explains that in C89, the standardized version of C, there is no Boolean type, and integers are used instead, with non-zero values representing true and zero representing false.

πŸ’‘Short Circuit Evaluation

Short circuit evaluation is a behavior in programming where an expression evaluates to a result without evaluating all its operands, typically in logical operations. The script provides examples of how this can prevent unnecessary computation and also discusses potential issues that may arise if a language does not support this feature, particularly in loops.

πŸ’‘Operator Coercion

Operator coercion is the implicit type conversion that occurs during an operation between two different data types. The script explains that in JavaScript and PHP, for instance, if two operands in a comparison are of different types, one operand will be converted to match the type of the other to perform the comparison, as seen in the example comparing a string '7' with the numeric value 7.

πŸ’‘Conditional (Ternary) Operator

The conditional operator, often referred to as the ternary operator, is a decision-making construct that chooses one of two expressions to execute, based on a boolean condition. The script discusses this operator in the context of assignment, where it can be used to assign different values to a variable based on a condition, as in 'condition ? value_if_true : value_if_false'.

πŸ’‘Compound Assignment Operators

Compound assignment operators are a shorthand that combines an arithmetic operation and an assignment into a single statement, such as '+=' for addition. The script explains that these operators were introduced in Algol 68 and later adopted by C and other C-based languages, providing a concise way to increment or decrement a variable's value.

πŸ’‘Unary Increment/Decrement Operators

Unary increment or decrement operators are used to increase or decrease a variable's value by one. The script distinguishes between prefix (e.g., '++count') and postfix (e.g., 'count++') variants, explaining that the prefix version increments first and then returns the value, while the postfix version returns the original value first and then increments.

πŸ’‘Mixed Mode Assignment

Mixed mode assignment refers to assigning a value of one type to a variable of another type. The script discusses how different programming languages handle this, with some allowing any coercion (widening or narrowing) and others, like Java and C#, only allowing widening coercions, which are considered safer as they prevent potential data loss.

πŸ’‘Functional Programming

Functional programming is a paradigm where programs are constructed through the evaluation of expressions and functions, avoiding changing state and mutable data. The script contrasts this with imperative programming, highlighting how in languages like ML and Haskell, identifiers are bound to values rather than being variables that can be changed, as seen in the example using 'let' in ML to bind the sum of 'apples' and 'oranges' to the name 'fruit'.

Highlights

Introduction to expressions and assignment statements, including arithmetic expressions, overloaded operators, and type conversions.

Discussion on relational and boolean expressions, and how they define relationships or boolean values between operands.

Exploration of short-circuit evaluation in expressions, which can prevent unnecessary operand evaluation.

Comparison of equality and inequality operators in JavaScript, PHP, and their behavior with type coercion.

Introduction of non-coercion comparison operators like triple equals and not equals equals in JavaScript and PHP.

Explanation of boolean expressions in C89, where int types are used with non-zero and zero values representing true and false, respectively.

Clarification of the left associative nature of boolean expressions and their evaluation from left to right.

Potential issues with short-circuit evaluation when it's not supported, leading to runtime errors or exceptions.

Overview of how different programming languages handle short-circuit evaluation with logical and bitwise operators.

Discussion on the problems that can arise with short-circuit evaluation when side effects are expected in expressions.

General syntax and forms of assignment statements, including the use of different assignment operators across languages.

Potential ambiguity issues with the single equals operator when used for both assignment and equality testing.

Introduction to compound assignment operators for incrementing or decrementing values, and their origin in Algol 68.

Explanation of unary assignment operators, including prefix and postfix increments and decrements.

Precedence and associativity of unary assignment operators, and how they differ from unary plus and minus operators.

Assignment statements producing a result in C-based languages, allowing assignments to be used within expressions.

Problems associated with using assignment as an expression, such as reduced error detection and potential side effects.

Support for multiple target multiple source assignments in languages like Perl, allowing for complex assignments in a single step.

Differences in assignment operations between functional and imperative programming languages, focusing on value binding.

Mixed mode assignments allowing different types of values to be assigned to variables, with different coercion rules across languages.

Safety in Java and C# with only widening coercions allowed in assignments, contrasting with more permissive languages.

Ada's strict approach to assignments with no coercions allowed, emphasizing language's focus on safety and correctness.

Transcripts

play00:01

welcome to the second lecture on chapter

play00:04

seven which deals with expressions and

play00:06

assignment statements

play00:08

in the previous lecture we introduced

play00:10

the basic underlying concepts behind

play00:13

expressions and assignment statements

play00:15

we also spent a lot of time looking at

play00:18

arithmetic expressions

play00:20

then we took a brief look at overloaded

play00:23

operators and finished off with type

play00:26

conversions in this lecture we'll finish

play00:28

the chapter wolf

play00:31

these are the topics that we will be

play00:33

looking at in today's lecture

play00:36

we'll start off with a discussion on

play00:38

relational and boolean expressions

play00:41

then we'll look at short circuit

play00:43

evaluation which applies to all types of

play00:46

expressions including arithmetic

play00:49

expressions and relational and boolean

play00:52

expressions

play00:53

then we'll look at the second main topic

play00:56

covered in this chapter namely

play00:58

assignment statements and we'll finish

play01:00

off by looking at mixed mode assignment

play01:03

which is similar to mixed mode

play01:06

expressions which we discussed in the

play01:08

previous lecture

play01:11

now you should at this stage be very

play01:13

familiar with relational expressions

play01:16

which are expressions that define some

play01:18

sort of relationship between two

play01:20

operands

play01:21

so with the in this category we include

play01:25

equality and inequality expressions

play01:28

which test respectively for two operands

play01:31

being equivalent to one another or two

play01:34

operands being not equivalent to one

play01:36

another we also include expressions that

play01:40

define some kind of inequality so this

play01:43

would include then expressions with

play01:45

operators such as less than less than or

play01:49

equal to

play01:50

greater than and greater than or equal

play01:53

to

play01:54

now in javascript and php we have the

play01:57

equality

play01:59

and inequality relational operators

play02:02

which behave in a fairly similar fashion

play02:04

to what you would expect in c plus or

play02:07

java however the equality or inequality

play02:11

check is performed with operator

play02:14

coercion so what this means is that if

play02:17

the types of the two operands don't

play02:19

match then one of the operands will be

play02:22

converted to the type of the other

play02:23

operand so that the equality or

play02:26

inequality comparison can take place

play02:30

so that means that this kind of

play02:33

expression would be valid here we are

play02:35

testing for equality between the string

play02:38

containing the single character seven

play02:42

and the numeric value seven coercion

play02:45

will take place here which means that

play02:47

the two can then be compared to each

play02:49

other and this will then produce a true

play02:53

result

play02:54

now if we want to perform a comparison

play02:57

without coercion then we have the

play02:59

relational operators triple equals

play03:02

and not equals equals

play03:05

and these will then perform the same

play03:07

kind of operation as the equality and

play03:10

inequality

play03:12

operators respectively however no

play03:15

operand coercion will take place so if

play03:18

we perform then the same equality

play03:21

comparison using the triple equals

play03:24

operator

play03:26

then

play03:26

again we are comparing for equality the

play03:30

string containing the character 7 and

play03:33

the numeric value 7. this will then

play03:36

produce a false result because the

play03:39

operands are then not coerced to be

play03:42

comparable to one another which means

play03:44

that the comparison fails

play03:47

now ruby has a similar kind of

play03:49

arrangement to javascript and php

play03:52

so it uses the double equals operator

play03:56

for equality with coercions and then it

play04:00

uses eql question mark for equality

play04:04

without coercions

play04:08

now boolean expressions are expressions

play04:10

in which the operands must be boolean

play04:13

and the result of the expression is also

play04:16

a boolean value

play04:18

so here we are talking about boolean as

play04:20

a type as we discussed in the previous

play04:24

chapter

play04:25

now c89 the standardized version of c

play04:29

has no boolean type

play04:31

so it uses an int type for operands

play04:35

within what would be interpreted as

play04:38

boolean expressions

play04:39

so a non-zero integer value is then

play04:42

interpreted as true and a zero

play04:46

value is interpreted as false and this

play04:49

would be whenever one of these

play04:51

expressions

play04:52

is used as a condition for example for

play04:56

an if statement or within a loop of some

play04:59

sort

play05:01

now boolean expressions then also

play05:03

evaluate two integer values so a true

play05:06

expression will evaluate to one and a

play05:09

false expression will evaluate to zero

play05:13

so one relatively odd result of this

play05:16

design if you don't know how these

play05:19

expressions work

play05:20

is that it is legal for us to create an

play05:23

expression such as a less than b

play05:26

less than c

play05:28

however this doesn't work as one would

play05:30

expect it to work based on mathematics

play05:34

so this in fact doesn't test to see

play05:36

whether a is less than both b and c

play05:40

and b is greater than a but less than c

play05:44

and then c of course is greater than

play05:46

both a and b

play05:48

instead what happens is we evaluate

play05:51

these operators from left to right

play05:54

because they are left associative so

play05:57

first of all we perform the comparison a

play06:01

less than b now depending on what the

play06:03

values of a and b are we will then

play06:06

either get a zero value which indicates

play06:09

a false or a one value which indicates a

play06:13

true

play06:14

so in other words this portion of the

play06:16

expression evaluates to either zero or

play06:20

one

play06:20

the zero or one is then compared to c

play06:25

and we test to see whether the zero one

play06:27

is less than c or not and then that will

play06:31

again produce a zero or one result

play06:34

depending on whether that comparison

play06:37

produces a true result or a false result

play06:42

we'll now take a look at short circuit

play06:44

evaluation so short circuit evaluation

play06:48

allows an expression to produce a result

play06:50

without necessarily evaluating all of

play06:53

the operands and or operators within the

play06:57

expression so let's look at this in

play06:59

terms of a simple example which is an

play07:02

arithmetic expression which you can see

play07:04

over here

play07:05

so this arithmetic expression uses a

play07:08

multiplication operator and we have then

play07:12

a left operand as well as a right

play07:15

operand for that multiplication operator

play07:19

so now let's assume that the value of

play07:22

the variable a

play07:24

is zero so in this case if we evaluate

play07:27

our left operand we then have 13

play07:30

multiplied by a which is 13 multiplied

play07:32

by zero which of course produces a zero

play07:36

result

play07:37

now if we assume that multiplication is

play07:41

a short circuit evaluated operator

play07:44

what this means is we don't need to

play07:46

evaluate the right operand and the

play07:50

reason for this is that we know that

play07:52

zero multiplied by any value produces a

play07:55

zero result so because we've just seen

play07:58

that the left operand

play08:00

computes a zero result this means that

play08:03

we have zero multiplied by something

play08:05

which will produce a zero result meaning

play08:07

we don't need to evaluate the entire

play08:10

right operand

play08:12

we also don't have to evaluate any of

play08:15

the operators within the right operand

play08:18

so this division and the subtraction do

play08:21

not need to be evaluated

play08:25

now there are potential problems that

play08:27

can arise if short-circuit evaluation is

play08:29

not supported within a programming

play08:32

language so let's look at this in terms

play08:34

of a fairly simple example

play08:37

here we assume that we have an array

play08:39

named list and list contains a number of

play08:42

elements which is equivalent to

play08:44

length

play08:46

so here we have then some example code

play08:48

we have an integer variable called index

play08:51

and that is initiated to a value of zero

play08:56

now we have a while loop and the

play08:59

objective of this while loop is to

play09:01

iterate through our list array one

play09:04

element at a time we will stop iterating

play09:07

either when we reach the end of our

play09:09

array or if we find an element contained

play09:13

in the array that is equivalent to value

play09:16

which is the value that we are searching

play09:20

for in the array

play09:23

so

play09:24

at each step we will then move one

play09:26

element further along in the array so

play09:29

let's look at the condition of our while

play09:31

loop we have a logical and operator and

play09:35

then we have a left operand and a right

play09:40

operand

play09:41

the left operand tests to see where the

play09:43

index is still less than length so this

play09:46

means that we are still within the

play09:48

bounds of the array and as long as that

play09:51

condition is true then we can still

play09:53

continue searching

play09:55

our write operand accesses our list

play09:57

array at subscript index

play10:00

and it compares this to

play10:02

value so

play10:05

the loop will then continue executing

play10:07

when value has not been found in other

play10:09

words the current value that we're

play10:11

looking at in the list array is not

play10:13

equivalent to the value that we are

play10:15

searching for

play10:17

now inside the body of our loop we then

play10:20

just have an increment to index and this

play10:23

moves us on then to the next position

play10:26

within the list array

play10:29

so now the question arises what if this

play10:32

logical and operator over here is not

play10:35

short circuit evaluated so what i would

play10:38

like you to do at this point is to pause

play10:40

the video and try to answer this

play10:42

question

play10:48

so if we assume that this logical and

play10:50

operator is not short circuit evaluated

play10:54

then let's assume that the value that we

play10:57

are searching for is not contained at

play11:00

all within our list array so we continue

play11:03

iterating until eventually we reach the

play11:07

end of our array and at this point index

play11:09

is then incremented to one index

play11:12

position past the end of our array in

play11:15

other words index is incremented to

play11:18

length so this is of course assuming

play11:21

that our list array is indexed from zero

play11:25

up to one and less than the length of

play11:28

the array

play11:30

so in this situation we will then get a

play11:34

false result

play11:36

for our left operand

play11:39

however because we are assuming that our

play11:41

logical and operator is not short

play11:44

circuit evaluated we must then go on to

play11:47

evaluate the right operand

play11:51

so in this case we then attempt to

play11:54

access our list array at subscript index

play11:58

however index is equal to length so this

play12:00

means this is an invalid array index now

play12:04

of course what happens at this point

play12:06

depends on the programming language that

play12:08

we're working with there may in some

play12:11

languages be a runtime error which will

play12:13

terminate execution of the program

play12:16

there may alternatively be an exception

play12:18

that will be raised that we may be able

play12:20

to catch or alternatively we may just

play12:23

perform an invalid axis which will then

play12:26

retrieve a value which may produce a

play12:29

problem further along in runtime

play12:33

now on the other hand if we assume that

play12:36

our logical and operator is short

play12:38

circuit evaluated then we know that we

play12:41

can only produce a true result if both

play12:44

the left and the right operands have a

play12:47

value of true

play12:50

so if we reach the end of the array we

play12:52

know that our left

play12:54

operand will then produce

play12:56

a value of false and we therefore know

play13:00

that the entire logical and operation

play13:03

must then produce a result of false so

play13:06

in that case it's been unnecessary for

play13:08

us to evaluate the right operand and we

play13:11

can then immediately conclude that the

play13:14

condition for the while loop has become

play13:17

false and we need to terminate execution

play13:19

of the loop so this will then avoid the

play13:23

problem that arises if the logical and

play13:26

is not short circuit evaluated

play13:31

now let's look at how a variety of

play13:34

different programming languages deal

play13:36

with short circuit evaluation

play13:38

so c c plus plus and java have standard

play13:42

boolean operators that are short

play13:44

circuits evaluated and these include the

play13:47

logical and and logical or operators

play13:51

however the bitwise boolean operators

play13:54

are not short circuits evaluated and

play13:56

these include the bitwise and and

play13:59

bitwise or operators

play14:03

rubypel

play14:04

mlfsharp and python have all of their

play14:08

logic operators short circuit evaluated

play14:12

now the added programming language again

play14:14

provides a measure of flexibility to the

play14:17

programmers the programmer can choose

play14:19

whether they want short-circuit

play14:21

evaluation or not

play14:24

so there are non-short-circuit

play14:26

and and all logical operators which are

play14:30

represented by the special words and

play14:33

and or

play14:35

however there are then also short

play14:37

circuit versions of the logical and and

play14:40

or operators which are indicated by

play14:44

means of the special words and then

play14:47

and or else

play14:51

two slides ago we discussed the fact

play14:54

that a lack of support for short circuit

play14:56

evaluation can cause potential problems

play15:00

within a program

play15:02

but it is equally possible for support

play15:05

for short-circuit evaluation to also

play15:07

cause potential problems and this will

play15:10

occur if side effects are expected

play15:14

within expressions so let's look at this

play15:16

in terms of a simple example which is a

play15:20

boolean expression over here

play15:22

and here we are going to assume that the

play15:25

logical or operator is a short-circuit

play15:28

evaluated operator

play15:31

now recall that a functional side effect

play15:34

occurs when a function modifies either a

play15:37

parameter or a global variable

play15:40

so we discussed this back in chapter 15

play15:44

earlier on in this course

play15:47

so it's also possible for operators to

play15:49

cause side effects and this will happen

play15:52

when an operator changes one or more of

play15:55

its operands

play15:57

so what i would like you to do at this

play15:59

point is to pause the video

play16:02

and try to determine which operator in

play16:05

our example causes a side effect

play16:13

all right so if we look at our example

play16:15

the only operator that causes a side

play16:17

effect is this increment operator over

play16:20

here because it changes the value of its

play16:22

single operand namely the value of the

play16:26

variable b

play16:28

now if we rely on the fact that the side

play16:31

effect must occur every time that the

play16:33

expression is evaluated then when will

play16:36

the side effect not occur so what i

play16:39

would like you to do at this point is

play16:40

again pause the video and try to answer

play16:43

this question

play16:48

all right so if we assume that our

play16:51

logical or operator is short circuit

play16:54

evaluated

play16:55

then we will not evaluate our right

play16:59

operand and in other words we will then

play17:01

not evaluate this increment operator

play17:04

which we've just determined does cause a

play17:07

side effect

play17:09

if we have a situation where the left

play17:12

operand evaluates to true

play17:15

and in this case we can then immediately

play17:18

conclude that the entire logical

play17:20

expression must then evaluate to true

play17:23

because only one of the operands needs

play17:26

to evaluate to true for the entire

play17:29

logical or to be true so this means then

play17:33

that we have no need to evaluate the

play17:36

right operand and therefore we won't

play17:39

perform the increment operation

play17:42

now if we rely on the fact that we

play17:44

expect that when this condition is

play17:46

evaluated that b will always be

play17:49

incremented then we have a problem

play17:51

because when the logical or operator is

play17:55

short-circuited this increment doesn't

play17:58

take place

play18:01

now we get on to the second major topic

play18:04

for this chapter which is assignment

play18:07

statements

play18:08

so the general syntax for an assignment

play18:10

statement involves an assignment

play18:12

operator of some sort and then there are

play18:15

two operands a left operand which must

play18:18

be a target variable which we are

play18:20

assigning to

play18:21

and a right operand which is some sort

play18:24

of expression the value of the

play18:26

expression will then be stored in the

play18:29

target variable

play18:32

now the assignment operator can take

play18:34

different forms so in fortran basic and

play18:37

all of these c based languages a single

play18:40

equals operator is used however in the

play18:44

algol programming languages both algor

play18:46

58 and alcohol 60 as well as pascal and

play18:50

ada the colon equals operator is used

play18:54

now we discussed all the way back in

play18:56

chapter two where the codon equals

play18:58

operator comes from it was originally

play19:01

introduced in algol 58 and it comes from

play19:04

an arrow notation that points from the

play19:07

right hand side to the left-hand side

play19:10

which is a mathematical notation

play19:12

and it would have been represented as a

play19:15

less than symbol followed by an equal

play19:17

symbol which would look like an arrow

play19:19

pointing from the right hand side to the

play19:21

left hand side but due to character set

play19:24

limitations a colon was used instead of

play19:27

a less than symbol

play19:32

now there is a potential problem that

play19:34

arises if the single equals operator is

play19:37

overloaded for use as the relational

play19:41

equality operator which compares two

play19:43

operands to each other and doesn't

play19:46

perform an assignment

play19:48

now this problem is an ambiguity between

play19:52

the assignment

play19:53

and equality test operations

play19:57

so in order to solve this problem we

play20:00

need separate operators for assignment

play20:03

and for an equality test

play20:06

so the c-based programming languages

play20:09

solve this problem by introducing a new

play20:11

operator

play20:13

for relational comparisons of equality

play20:16

and this is the double equals operator

play20:19

which you should be familiar with

play20:21

now this is potentially problematic

play20:24

because a beginner programmer who isn't

play20:26

familiar with the notation used in the

play20:29

c-based programming languages may assume

play20:32

that a single equals operator represents

play20:36

a relational comparison for equality and

play20:40

this may then cause confusion and

play20:42

potential errors within the program code

play20:45

which may be difficult to debug

play20:49

now algol 58's

play20:51

colon equals operator is unambiguous

play20:55

because there is an entirely separate

play20:57

way of representing assignment and

play21:00

therefore a single equals operator can

play21:03

be used for the relational equality

play21:06

operation

play21:10

conditional targets are supported in

play21:13

perl and these are very similar in

play21:15

format to the conditional expressions

play21:18

that we spoke about in the last lecture

play21:22

however conditional targets are used as

play21:25

the target of an assignment operation

play21:28

so this is the form of a conditional

play21:32

target the conditional target being the

play21:34

left operand of an assignment

play21:38

so again we have three operands

play21:42

and we have then operator symbols which

play21:46

are the question mark and the colon

play21:50

symbols

play21:51

so

play21:52

the operand then that appears to the

play21:55

left of the question mark is a condition

play21:57

in other words it must be a boolean

play21:59

expression that evaluates to true or

play22:02

false

play22:03

now if this operand evaluates to true

play22:06

then the entire conditional target

play22:09

becomes the second operand which appears

play22:12

between the question mark and the column

play22:15

symbols

play22:16

if however the first operand evaluates

play22:20

to false then the entire conditional

play22:23

expression becomes the third operand

play22:26

which is

play22:28

appearing to the right of the colon

play22:31

symbol so what this means is in this

play22:34

example if flag is true then zero is

play22:38

assigned to total otherwise if flag is

play22:42

false

play22:43

then 0 is assigned to subtotal

play22:47

so here we have then

play22:49

an equivalent piece of code using an if

play22:53

statement which performs the same

play22:55

operation as our conditional target we

play22:58

have an if which is then based on the

play23:01

value of our flag

play23:04

and if the flag is true then we assign 0

play23:07

to total otherwise if the flag is false

play23:10

then we assign 0 to subtotal

play23:14

so what i would like you to do at this

play23:16

point is to pause the video and try to

play23:19

determine which of the programming

play23:22

language evaluation criteria are

play23:24

supported by support for conditional

play23:27

targets within a programming language

play23:36

now you should be very familiar with

play23:38

compound assignment operators at this

play23:40

point

play23:41

which are a shorthand method for

play23:43

specifying a very commonly used form of

play23:46

assignment

play23:47

namely an assignment that either

play23:50

increments or decrements a value by a

play23:53

user-specified amount

play23:56

now compound assignment operators were

play23:58

introduced in algol 68 and then later on

play24:01

adopted by c and were therefore also

play24:04

supported in all of the c based

play24:07

programming languages

play24:08

so over here we have an example of a

play24:10

compound assignment

play24:13

specifically one that performs an

play24:15

incrementing operation

play24:17

so the plus equals is the compound

play24:20

assignment operator it has two operands

play24:23

a lift operand which is the variable

play24:27

that is being incremented and the right

play24:29

operand which provides the value that we

play24:33

should increment by so this is

play24:35

equivalent to the longer form notation

play24:38

which you see at the bottom over here

play24:40

where we are assigning 2a

play24:43

a's original value with b

play24:46

added to it so we are essentially then

play24:49

performing an increment to a

play24:52

by the amount specified within the

play24:54

variable b

play24:56

now we also have a compound assignment

play24:59

operator that performs a decrement

play25:02

operation and in this case the operator

play25:05

would be minus equals and this would

play25:07

then be equivalent to an assignment

play25:11

operation similar to what we see

play25:14

for the compound assignment example that

play25:17

we looked at before however instead of

play25:19

performing an addition we would be

play25:21

performing a subtraction operation

play25:26

you should also be very familiar with

play25:28

unary assignment operators which are

play25:31

supported in all of these c-based

play25:33

programming languages

play25:35

these combine increments or decrement

play25:37

operations with an assignment

play25:41

so we'll consider

play25:42

unary increment operators first and

play25:46

there are two different variants of the

play25:49

unary increments operator

play25:52

namely a prefix increment sometimes

play25:54

called a pre-increment and a post-fix

play25:57

increment sometimes called a post

play25:59

increment

play26:01

so the prefix increment

play26:03

is

play26:04

an operator plus plus which appears

play26:07

before the operand that it is applied to

play26:11

namely count in this example

play26:14

so the semantics for a prefix increment

play26:17

are that we perform the increment and

play26:20

then the incremented result is returned

play26:24

so in this case we would increment count

play26:27

by 1

play26:28

and then the incremented value would be

play26:31

returned and would be assigned to sum

play26:36

now a postfix increment operator has the

play26:40

same general form except that the

play26:43

operator appears after the operand to

play26:46

which it is applied namely count in this

play26:49

example

play26:51

so the semantics here

play26:53

are that the result that is returned by

play26:57

the increments operation is the original

play27:00

value of the operand in this case the

play27:03

value of count and then after this value

play27:06

has been returned then the increment

play27:09

operation is performed so in this case

play27:12

the original unincremented value of

play27:15

count will be assigned to sum and after

play27:18

that assignment has taken place then the

play27:21

increment is performed to counts value

play27:25

now

play27:26

the same applies to

play27:28

unary decrement operators again there we

play27:32

have a prefix decrement

play27:35

and a postfix decrement and these have

play27:38

exactly the same semantics as for the

play27:41

prefix increments and postfix increment

play27:44

except that a decrement operation is

play27:46

performed instead of an increment

play27:49

operation

play27:51

so now we'll talk about precedence and

play27:54

associativity of the unary assignment

play27:57

operators what you should note here is

play28:00

that this discussion is somewhat

play28:02

different to what is presented in the

play28:04

textbook where the textbook presents a

play28:07

simplified view

play28:09

so you should base your studying on what

play28:12

is discussed in the slides here

play28:15

so postfix increments and decrements are

play28:18

at a higher precedence level than prefix

play28:22

increment and decrement and the unary

play28:25

plus and minus operators

play28:28

so what this means is if these are mixed

play28:31

then post fix increments and decrements

play28:34

will be evaluated first before prefix

play28:37

increments and decrements and unary plus

play28:40

and minus operators

play28:43

so postfix increment and decrement are

play28:47

left to right associative we can see

play28:49

that in this example over here where we

play28:52

are applying the unary increment

play28:55

and decrement postfix operators to count

play28:59

so in this case the evaluation would be

play29:02

that the increment is first applied to

play29:05

count and then afterwards the decrement

play29:08

is applied

play29:11

so prefix

play29:12

and unary increments and decrements are

play29:16

at the same precedence level as unary

play29:18

plus and minus unary plus and minus are

play29:22

simply used to make value positive or

play29:26

negative

play29:27

now these operators are all right to

play29:30

lift associative so over here we have an

play29:33

example where we are performing a

play29:36

negation as well as an increment to the

play29:39

variable count

play29:41

so in this case because we are

play29:43

associating right to left we will first

play29:46

perform

play29:47

the pre-increment operation on count and

play29:50

once that operation has completed then

play29:53

we will negate the result

play29:58

now in the c-based programming languages

play30:01

as well as pull and javascript an

play30:04

assignment statement actually produces a

play30:06

result and that result is the value that

play30:09

has been assigned

play30:11

so if we consider this assignment over

play30:14

here which is assigning a value of 4 to

play30:16

a variable called number in this case

play30:19

the value of the assignment will be 4

play30:22

which is the value that has been

play30:24

assigned to number

play30:26

so what this means is that an assignment

play30:28

can be used as an expression

play30:31

and what this also implies is that an

play30:33

assignment can then be used as an

play30:36

operand within another expression

play30:39

so here we have a fairly simple example

play30:41

of this we have an if statement

play30:44

and inside the condition of this if

play30:46

statement we have a comparison operator

play30:50

an equality comparison operator and an

play30:53

assignment operator so the way that this

play30:55

would be evaluated is that the

play30:57

assignment would be performed first so

play30:59

we would assign the value of the

play31:01

variable c

play31:02

to the variable b

play31:05

and the result of that assignment would

play31:08

then be c which is the value that has

play31:10

been assigned

play31:12

then we would compare a

play31:15

to c

play31:16

which is the result of the assignment

play31:19

and we would test to see whether these

play31:21

two are equivalent to one another this

play31:24

would then produce either a true or a

play31:26

false result

play31:29

here we have another example of an

play31:32

assignment that is used as an operand

play31:36

and this is a very common use

play31:40

of this kind of assignment particularly

play31:42

in the c programming language so here we

play31:47

have a while loop and the objective of

play31:50

this loop is to read through an input

play31:52

file one character at a time but we

play31:55

don't know how many characters there are

play31:58

contained in the files so we need to

play32:00

stop once the end of the file is reached

play32:03

now we know that a file end has been

play32:05

reached once a special character is

play32:07

encountered known as an endophile or eof

play32:11

character

play32:13

so in the condition of this while loop

play32:16

we first have an assignment that takes

play32:18

place

play32:19

this assignment

play32:21

calls the get char function which reads

play32:24

a single character from the input file

play32:27

and this character is then assigned to

play32:29

the variable ch

play32:32

so now ch contains the character that

play32:35

has been read from the file and this can

play32:37

be used in the body of our while loop

play32:41

however this assignment also has a value

play32:45

and the value of this assignment is the

play32:48

character that has been read from the

play32:50

file by means of the get char function

play32:53

because this is the value that is

play32:55

assigned

play32:56

so this character value is then compared

play32:59

by means of an inequality operator

play33:02

to the eof character which is

play33:05

represented by a named constant over

play33:08

there

play33:09

what this means is that the loop will

play33:11

continue executing as long as the next

play33:14

character that is read is not the end of

play33:16

file character and as soon as the end of

play33:18

file character is encountered then the

play33:21

loop will end because we have fully

play33:23

processed our file

play33:26

now there are two problems associated

play33:29

with using assignment as an expression

play33:33

so first of all our error detection

play33:36

capabilities are reduced

play33:38

and this will occur in a situation where

play33:41

we intend to type a double equals

play33:44

equality comparison operator but instead

play33:47

we must type this as a single equals

play33:50

assignment operator

play33:53

so in this example over here we have an

play33:55

if statement and we have a condition and

play33:58

this condition should have been x equals

play34:02

equals y so in other words we wanted to

play34:04

test whether x was equivalent to y

play34:08

however instead of doing that we've

play34:09

mistyped the double equals comparison

play34:12

operator as a single equals assignment

play34:15

operator

play34:17

now because assignment is handled as an

play34:20

expression this means that this

play34:23

assignment returns a result which is

play34:26

then y which is the value that has been

play34:29

assigned

play34:30

so this will then be the condition that

play34:33

the if statement will base its decision

play34:36

on

play34:37

if we are working in c or c plus plus

play34:41

then this will be interpreted on a

play34:43

numeric level as either a true or a

play34:47

false value

play34:49

the second issue that can arise is that

play34:52

an assignment can cause a side effect

play34:56

so

play34:57

in order to understand this we need to

play35:00

recall that operators can cause side

play35:02

effects by changing their operands

play35:06

so if we look at this first example over

play35:08

here

play35:09

then what i would like you to do is

play35:11

pause the video at this point and try to

play35:15

explain how a side effect is caused in

play35:18

this example

play35:26

now pearl ruby and lewis support

play35:30

multiple target multiple source

play35:32

assignments

play35:34

so here we have an example of such an

play35:36

assignment

play35:37

we have three targets in this case

play35:40

namely first second and third all three

play35:44

of which are variables we also have

play35:47

multiple sources

play35:48

the same number of sources as targets

play35:52

and in this case our multiple sources

play35:55

are 20 30 and 40. so the result of this

play36:00

is that the value 20 will be assigned to

play36:02

the variable first the value 30 will be

play36:04

assigned to the variable second and the

play36:06

value 40 will be assigned to the

play36:08

variable third

play36:10

now what's very interesting and what

play36:14

illustrates the power of this kind of

play36:16

assignment is that we can actually

play36:19

perform a single step swap operation

play36:21

without having to use an intermediary

play36:24

variable to

play36:26

hold a value during the assignment so

play36:29

we've done exactly that in this example

play36:32

over here

play36:33

we are assigning the original value of

play36:36

second to first and then the original

play36:39

value of first to second

play36:45

assignment in functional programming

play36:47

languages works a little differently to

play36:50

imperative programming languages so as

play36:52

we've seen in chapter 15 in functional

play36:55

languages identifiers are only names for

play36:58

values they aren't actually variables

play37:01

this means that we can't perform certain

play37:04

kinds of operations like for example

play37:06

incrementing a variable's value

play37:09

so

play37:10

in ml

play37:12

names are bound to values using vel so

play37:15

that's exactly what we've done here we

play37:17

use the special word vel and we bind the

play37:20

results of adding apples and oranges to

play37:24

the name

play37:25

fruit

play37:26

so if another vowel then binds a

play37:29

different value to fruit

play37:32

following this initial binding then it

play37:35

is a new name and the previous fruit is

play37:38

hidden in that case

play37:41

now if sharp uses lit instead of vowel

play37:44

and this has a fairly similar result

play37:46

again it's a binding of a value to a

play37:49

name and it doesn't constitute a

play37:52

variable

play37:53

however lit also creates a new scope

play37:57

which is not the case with vel in ml

play38:03

finally we get to mixed mode assignments

play38:06

so assignments just like expressions can

play38:10

be mixed mode and again this is a

play38:13

situation where the right and left

play38:15

operands have different types so this

play38:18

then allows us to assign a value of a

play38:21

different type to the type of the

play38:24

variable

play38:26

so in fortran c c plus plus and perl

play38:30

coercion rules will be applied to allow

play38:32

these assignments to take place and this

play38:35

happens for any numeric type value that

play38:38

is assigned to any numeric type variable

play38:42

so what i would like you to do at this

play38:44

point is to pause the video and try to

play38:48

explain what problem this can cause

play38:57

in java and c-sharp only widening

play39:00

coercions are allowed in assignments

play39:03

in contrast within fortran c c plus and

play39:08

perl

play39:09

any coercion is allowed within an

play39:11

assignment so these coercions may be

play39:14

widening or narrowing coercions

play39:17

so what i would like you to do at this

play39:19

point is to pause the video and try to

play39:21

explain why java and c sharp have a

play39:24

safer approach in this regard

play39:31

now ada once again performs fewer

play39:34

coercions than most of the other

play39:37

high-level computative programming

play39:39

languages

play39:40

and it performs no assignment coercions

play39:44

at all

play39:46

so what i would like you to do is again

play39:48

pause the video at this point and

play39:50

explain what this implies about ada's

play39:54

assignments

play39:58

all right so that concludes our

play40:00

discussion on chapter seven

play40:02

in the next lecture we will begin with

play40:04

chapter eight in which we will discuss

play40:07

statement level control structures

Rate This
β˜…
β˜…
β˜…
β˜…
β˜…

5.0 / 5 (0 votes)

Related Tags
ExpressionsAssignmentControl StructuresProgramming ConceptsBoolean LogicOperator PrecedenceType ConversionShort-Circuit EvaluationConditional AssignmentMixed Mode Assignment