# 5.4 Expressions

In computer code, one may want to formulate an expression to achieve some particular purpose, such as to express some condition about the states of variables involved in the code. For example, suppose that you want to express the condition that a sequence *s* contains at least two members, and that the second member of *s* is not the space character (with ASCII code 32). This condition holds when the expression below is **true**.

(*SIZE*(*s*) > _{Int} 1) ∧ (*NOT*(*ASC*(*AT*(2,*s*)) = _{Int} 32))

When writing expressions involving functions and binary operations, there are some points to be careful about. One needs to be careful to use brackets as necessary to ensure that operations are applied in the desired order. This is particularly important in expressions using infix notation. You also need to apply each process in a way that is consistent with its signature. And you must apply each process in a way that is consistent with any precondition that it has. We say that an expression is **not valid** if it uses a function in a way that is inconsistent with its signature or its precondition. For example, ‘Q’ =_{Int } 32 is not valid, since =_{Int } compares two integers, and ‘Q’ is a character, while *PUT*(7, “This”, ‘Q’) is not valid, since 7 does not satisfy the precondition of *PUT*. (The precondition of *PUT* requires that 7≤ *SIZE*(“This”), but *SIZE*(“This”) is 4.)

The functions *SIZE* and *AT* were described in Activity 16, and the function *ASC* was described in Section 4.3. The binary operations =_{Int }, >_{Int } and ∧ are defined earlier in this section.

## Activity 28

(a) With

*s*= “I#am.”, evaluate each of the expressions:(i)

*AT*(2,*s*).(ii)

*ASC*(*AT*(2,*s*)).(iii)

*ASC*(*AT*(2,*s*)) =_{Int }35.(iv)

*NOT*(*ASC*(*AT*(2,*s*)) =_{Int }35).(v) (

*SIZE*(*s*) >_{Int }3) ∧ (*NOT*(*ASC*(*AT*(2,*s*)) =_{Int }35)).

(b) Let

*s*be a general string. Under what circumstances does the expression in (a) (v) give the value**true**? Under what circumstances is that expression valid?(c) With

*s*= “I#am.”, why is it not possible to evaluate the expression

(*ASC*(*AT*(2,*s*)) = _{Int} 35)?

### Discussion

(a) (i)

*AT*(2,*s*) = ‘#’.(ii)

*ASC*(*AT*(2,*s*)) = 35.(iii)

*ASC*(*AT*(2,*s*)) =_{Int }35 becomes 35 =_{Int }35, which evaluates to**true**.(iv)

*NOT*(*ASC*(*AT*(2,*s*)) =_{Int }35) becomes*NOT*(**true**) =**false**.(v) We have

*SIZE*(*s*) = 5 (the number of characters in the string “I#am.”), so (*SIZE*(*s*) >_{Int }3) becomes (5 >_{Int }3) which is**true**. So the expression in (v) becomes**true**∧**false**=**false**.(b) The given expression will be

**true**only if each of*SIZE*(*s*) >_{Int }3 and*NOT*(*ASC*(*AT*(2,*s*)) =_{Int }35) is**true**. The first of these is**true**if the string*s*contains at least four characters. The second is**true**if the second character is*s*is not the character ‘#’. So the expression in (a) (v) will be**true**if:the string

*s*contains at least four characters and its second character is not ‘#’.The precondition of

*AT*requires here that the string*s*contains at least two characters. The expression in (a) (v) will be valid so long as this is true. (All the other functions in the expression are total. The example in part (a) indicates that the expression is put together in a way that is consistent with the signatures of the functions.)(c)

*AT*(2,*s*) = ‘#’. Then*AT*(2,*s*) =_{Int }35 becomes ‘#’ =_{Int }35. This expression is not valid, since =_{Int }requires two integers as inputs, and ‘#’ is a character. So the given expression is not valid.

Notice how important the brackets are in a complicated expression. The order in which the bits of the overall expression are to be evaluated is determined by the way the brackets appear in the expression. We need to follow this carefully in evaluating an expression such as that in Activity 28 (a) (v). A slip in placing one bracket can easily lead to an expression that is not valid, as in (c) above. On the whole, it is good practice when writing computing code to seek to avoid writing complicated expressions. Usually one can split the code into intermediate steps, as indicated by the steps in the evaluation in (a) above.