Subsections

- Exercises

# Primaries

Primaries are denotations, applied identifiers, casts, calls and slices. We have met denotations in chapters 1, 4 and 6. Only plain values, routines and a special name (`NIL`) have a denotation. `NIL` is dealt with in the section on tertiaries and the mode `BITS` is covered in chapter 11. Applied-identifiers means identifiers being used in a context, rather than in their declarations. We have met numerous examples of these. Routine denotations are not primaries.

A cast consists of a mode indicant followed by an enclosed clause, usually a closed clause. Here is a formula with a cast:

       3.4 * REAL (i)

where `i` has mode `INT`. The cast puts the enclosed clause in a strong context. Thus, in the above formula, the normal context of an operand is firm (see chapter 2), but the cast causes the value of `i` to be widened to a `REAL`. Casts are usually used in formulæ and identity relations (see sections 10.8 and 11.6). Casts are sometimes used to coerce a conditional or case clause where balancing is insufficient to provide the mode required (see section 10.9 later in this chapter). The mode indicant can be any mode and can contain any of the mode-constructors such as `REF` or `PROC` or `[]` (but it should not be a generator, which is not a mode indicant). Care should be taken when using a structured mode. For example, in this formula,

       3 * STRUCT(INT k)(4)

assuming that the operator has been declared for operands of modes `INT` and `STRUCT(INT k)`, the cast must include the field selector because it is part of the mode.

Calls were discussed in sections 6.3.1 and 6.3.2. Here is a simple example:

       sqrt(0.7)

In this call, `sqrt` is itself a primary (it is an applied-identifier). In section 10.2, it was mentioned that the primary of a call is in a meek context. This applies even if the call itself (as a whole) is in a strong context. The primary of a call can be an enclosed clause. For example,

       (a>4|sqrt|sin)(x)

which yields `sqrt(x)` if `a > 4` and `sin(x)` otherwise. In this case, the primary is

       (a>4|sqrt|sin)

We discussed slices in section 3.2. They include simple subscripting. For example, given the declaration

       [,]INT r = ((1,2,3),(4,5,6))

the units `r[1,]` and `r[2,3]` are both slices. Whatever the context of the slice, the context of the primary of the slice (`r` in these examples) is always weak. This means that only weak-dereferencing is allowed. Thus, given the phrases

       [2,3]INT s:=r;  INT p:=s[2,1]

the slice `s[2,1]` is in a strong context, but the `s` is in a weak context, so the name that `s` identifies, which has the mode `REF[,]INT` will not be dereferenced, though the slice, which has mode `REF INT`, will be.

There is another consequence of the weak context of the primary of a slice: row-displays can only be used in a strong context. So if you want to change the bounds of a row-display, because the slicer will produce a weak context, the row-display must be enclosed in a cast.

The context of subscripts and bounds in trimmers is meek and they must be units.

All enclosed clauses are primaries, but not all primaries are enclosed clauses.

## Exercises

10.5
  What are the contexts of Ans
  (a)
    `p` (mode `REF[]REAL`) in `[]REAL (p[3])`

  (b)
    `q` (mode `PROC(REAL)INT`) in `REAL(q(0.5))`

10.6
  How many primaries are there in each of the following units: Ans
  (a)
    `3 * (1.4 + r)/2**6`

  (b)
    `p:=sqrt(r) - 6`

  (c)
    `num:=x[3,ENTIER r]`

  (d)
    `i * []CHAR("e")`