Define and use non-composite types

13.1 User‑defined Data Types – Non‑composite Types

Learning Objective

Define and use the five non‑composite user‑defined types required by the Cambridge AS/A‑Level syllabus, evaluate their impact on code clarity, safety and maintainability, and select the most appropriate type for a given problem (AO1–AO3).

Syllabus Alignment (Cambridge AS/A‑Level 9618)

UnitContentAssessment Objective(s)
13.1Non‑composite user‑defined types (enumerated, sub‑range, type synonyms, pointer‑type synonyms, set types)AO1 – terminology & definitions
AO2 – select appropriate type for a given problem
AO3 – implement, test and evaluate a solution

What Are Non‑composite Types?

Non‑composite types are atomic: they are not built from other types. They differ from composite types (records, arrays, ADTs) which combine several values. The five non‑composite types listed in the syllabus are:

  • Enumerated (enum) types
  • Subrange types
  • Type synonyms (type definitions)
  • Pointer‑type synonyms
  • Set types

Quick comparison with composite types

AspectNon‑compositeComposite
ConstructionDefined from a single existing ordinal type or from a pointerBuilt from two or more component types (e.g., record, array)
Memory layoutSingle value (or a single pointer)Multiple contiguous or linked values
Typical useRepresent a limited set of concepts, enforce a numeric range, give a domain‑specific name, or create a simple pointer aliasGroup related data (e.g., a student record) or store collections (e.g., an array of marks)

1. Enumerated Types

Definition

An enumerated type defines a finite, named set of possible values. Each value is an enumeration constant. Internally the compiler stores them as integers (ordinal values), but the program works only with the symbolic names.

Pascal syntax

type

Colour = (Red, Green, Blue);

Java equivalent

enum Colour { RED, GREEN, BLUE }

Typical operations

  • Assignment: c := Red; (Pascal) or Colour c = Colour.RED; (Java)
  • Comparison: if c = Blue then … or if (c == Colour.BLUE) …
  • Successor / Predecessor: next := Succ(c); (Pascal) or Colour[] v = Colour.values(); Colour next = v[(c.ordinal()+1)%v.length]; (Java)
  • Iteration: for c := Low(Colour) to High(Colour) do … (Pascal) or for (Colour c : Colour.values()) … (Java)

Ordinal vs. non‑ordinal representation

Most compilers assign the first constant the ordinal value 0, the second 1, etc., but the exact numeric values are not guaranteed by the language standard. Therefore:

  • Never rely on Red = 0 in program logic.
  • Use the symbolic constants for all comparisons and arithmetic.

Design activity (AO2)

Think‑Pair‑Share: Design an enum Day for the seven days of the week. In pairs decide which days are “weekend” and write a short method that returns true for weekend days. Discuss why an enum is a better choice than a set of integer constants.

Testing tip (AO3)

Write a JUnit test that passes each enum constant to the method created above and asserts the correct Boolean result.

Common pitfalls

  1. Comparing an enum with an integer literal – illegal.
  2. Assuming the underlying ordinal values are the same across languages – they may differ.

2. Subrange Types

Definition

A subrange type restricts an existing ordinal type (integer, char, or enumerated) to a contiguous interval of values.

Pascal syntax

type

Score = 0..100; { integer subrange }

GradeLetter = 'A'..'F'; { character subrange }

Java equivalent

Java has no built‑in subrange type. The same effect is achieved with a small wrapper class that validates the value in the constructor.

final class Score {

private final int value;

public Score(int v) {

if (v < 0 || v > 100)

throw new IllegalArgumentException("Score out of range");

this.value = v;

}

public int get() { return value; }

}

Operations

  • Assignment: s := 85; (Pascal) – range‑checked at run‑time.
  • Comparison: if s > 70 then …
  • Compile‑time checking: When a constant lies outside the range, the compiler flags an error. Example:

const

BadScore : Score = 101; { compile‑time error: value out of range }

Design activity (AO2)

Given the problem “store a patient’s temperature in Celsius, which will never be below –30 or above 45”, decide whether a subrange or a type synonym is more appropriate and justify your choice.

Testing tip (AO3)

Create test cases that attempt to construct a Score with values –1, 0, 100 and 101. Verify that only –1 and 101 throw an exception.

Common pitfalls

  1. Assuming out‑of‑range values are caught at compile‑time for variables – they are only caught at run‑time unless the value is a constant.
  2. Defining a character subrange without considering the underlying character set (ASCII vs Unicode).

3. Type Synonyms (Type Definitions)

Definition

A type synonym creates a new name for an existing type. It does not create a distinct type; the two names are interchangeable.

Pascal syntax

type

StudentID = integer;

Temperature = real;

Java analogue

Java has no direct typedef. The intent is conveyed by:

  • Using a dedicated wrapper class (e.g., class StudentID { private final int value; … }) when a distinct type is required.
  • Adding a clear comment or Javadoc tag when a plain primitive is sufficient.

When to use

  • To give a meaningful domain‑specific name (e.g., Price = real;).
  • To allow a future change of representation without touching the rest of the program.

Pitfall

Because the synonym is not a separate type, the compiler will not prevent mixing it with its base type. Logical errors must be caught by the programmer (e.g., adding a StudentID to a plain integer that represents a score).

Design activity (AO2)

Write a short paragraph explaining why type Money = real; is a better choice than using real directly in a banking application.

4. Pointer‑type Synonyms

Definition

A pointer‑type synonym creates a new name for a pointer to an existing type. It is useful when the same pointer type is used in several places (e.g., linked‑list nodes).

Pascal syntax

type

NodePtr = ^Node; { pointer‑type synonym }

Node = record

data : integer;

next : NodePtr;

end;

Java analogue

Java references are implicit; a synonym is expressed by a class name. For linked lists we typically write:

class Node {

int data;

Node next; // “NodePtr” is implicit

}

Why it matters (AO2)

Using a synonym makes the intention explicit (e.g., “this variable holds a pointer to a node”) and allows a single point of change if the underlying structure is altered.

Common pitfall

Confusing a pointer‑type synonym with a new record type – the synonym does not introduce a new structure, only a new name for the same pointer.

5. Set Types

Definition

A set type defines a collection of values taken from an ordinal base type. The set itself is a non‑composite type because it is stored as a bit‑vector rather than as a collection of separate objects.

Pascal syntax

type

Day = (Mon, Tue, Wed, Thu, Fri, Sat, Sun);

DaySet = set of Day;

Java equivalent

Java uses EnumSet which is a specialised, efficient implementation of a set of enum constants.

enum Day { MON, TUE, WED, THU, FRI, SAT, SUN }

EnumSet<Day> weekend = EnumSet.of(Day.SAT, Day.SUN);

Typical operations

  • Membership test: if Mon in WorkDays then … (Pascal) or if (workDays.contains(Day.MON)) … (Java)
  • Set union / intersection: AllDays := WorkDays + Weekend; or EnumSet<Day> all = EnumSet.copyOf(workDays); all.addAll(weekend);
  • Iteration: for d := Low(Day) to High(Day) do if d in MySet then …

Design activity (AO2)

Model a school timetable where each class can be scheduled on any subset of the days Monday–Friday. Choose between a set type and an array of Boolean flags, and justify your choice.

Why Use Non‑composite User‑defined Types?

  • Clarity: Names reflect the problem domain (e.g., Colour, Score, StudentID).
  • Safety: The compiler or runtime can reject illegal values (enumeration constants, out‑of‑range subranges, illegal set members).
  • Maintainability: Changing the underlying representation requires editing only the type definition.
  • Assessment focus: Provides natural hooks for AO2 (type selection) and AO3 (testing of range checks, enum handling, set operations).

Full Example Program (Pascal) – Uses All Five Non‑composite Types

program NonCompositeDemo;

{---------------------------------------------------------------}

{ Demonstrates enumerated, subrange, type synonym, }

{ pointer‑type synonym and set types. }

{---------------------------------------------------------------}

type

Colour = (Red, Green, Blue); { enumerated }

Score = 0..100; { subrange }

StudentID = integer; { type synonym }

{ linked‑list node }

NodePtr = ^Node; { pointer‑type synonym }

Node = record

id : StudentID;

mark : Score;

next : NodePtr;

end;

Day = (Mon, Tue, Wed, Thu, Fri, Sat, Sun);

DaySet = set of Day; { set type }

var

c : Colour;

s : Score;

id : StudentID;

head: NodePtr;

workDays, weekend, allDays: DaySet;

function CalculateGrade(m : Score) : (A, B, C, D, F);

begin

case m of

90..100: CalculateGrade := A;

80..89 : CalculateGrade := B;

70..79 : CalculateGrade := C;

60..69 : CalculateGrade := D;

else CalculateGrade := F;

end;

end;

procedure AddNode(var list: NodePtr; nid: StudentID; nscore: Score);

var

newNode: NodePtr;

begin

new(newNode);

newNode^.id := nid;

newNode^.mark := nscore;

newNode^.next := list;

list := newNode;

end;

begin

{--- Enumerated & Subrange ---}

c := Red;

s := 78; { range‑checked at run‑time }

id := 12345;

writeln('Student ', id, ' scored ', s, ' (', Colour(c), ')');

{--- Pointer‑type synonym ---}

head := nil;

AddNode(head, 10001, 85);

AddNode(head, 10002, 92);

{--- Set type ---}

workDays := [Mon, Tue, Wed, Thu, Fri];

weekend := [Sat, Sun];

allDays := workDays + weekend; { union }

writeln('All days count: ', Ord(High(Day)) - Ord(Low(Day)) + 1);

end.

Java Translation (Paper 4 practice)

enum Colour { RED, GREEN, BLUE }

enum Grade { A, B, C, D, F }

enum Day { MON, TUE, WED, THU, FRI, SAT, SUN }

final class Score {

private final int value;

public Score(int v) {

if (v < 0 || v > 100) throw new IllegalArgumentException("Score out of range");

this.value = v;

}

public int get() { return value; }

}

final class StudentID {

private final int value;

public StudentID(int v) { this.value = v; }

public int get() { return value; }

}

/* linked‑list node – pointer‑type synonym is implicit */

class Node {

StudentID id;

Score mark;

Node next;

Node(StudentID i, Score m, Node n) { id = i; mark = m; next = n; }

}

public class NonCompositeDemo {

public static Grade calculateGrade(Score s) {

int v = s.get();

if (v >= 90) return Grade.A;

else if (v >= 80) return Grade.B;

else if (v >= 70) return Grade.C;

else if (v >= 60) return Grade.D;

else return Grade.F;

}

public static void main(String[] args) {

Colour c = Colour.RED;

Score s = new Score(78);

StudentID id = new StudentID(12345);

System.out.println("Student " + id.get() + " scored " + s.get() + " (" + c + ")");

/* linked list */

Node head = null;

head = new Node(new StudentID(10001), new Score(85), head);

head = new Node(new StudentID(10002), new Score(92), head);

/* set type using EnumSet */

java.util.EnumSet workDays = java.util.EnumSet.range(Day.MON, Day.FRI);

java.util.EnumSet weekend = java.util.EnumSet.of(Day.SAT, Day.SUN);

java.util.EnumSet allDays = java.util.EnumSet.copyOf(workDays);

allDays.addAll(weekend);

System.out.println("All days = " + allDays);

}

}

Summary Table

TypePurposePascal syntaxJava analogueTypical values
EnumeratedFixed set of named constantstype Colour = (Red, Green, Blue);enum Colour { RED, GREEN, BLUE }Red, Green, Blue
SubrangeRestrict an ordinal type to a contiguous intervaltype Score = 0..100;Wrapper class with range check0 … 100
Type synonymGive a domain‑specific name to an existing typetype StudentID = integer;Comment or wrapper classinteger
Pointer‑type synonymNew name for a pointer to an existing typetype NodePtr = ^Node;Implicit reference (class name) in JavaNodePtr = ^Node
Set typeCompact collection of values from an ordinal base typetype DaySet = set of Day;EnumSet<Day>{Mon, Tue, …, Sun}

Quick‑Check Quiz (AO1 & AO2)

  1. Which statement is correct?

    A) An enumerated type can be compared directly with an integer.

    B) A subrange type can only be defined for real values.

    C) A type synonym creates a new, distinct representation.

    D) All of the above.

    Answer: None – enumerated types compare with their constants, subranges apply to ordinal types, and synonyms do not create a new representation.

  2. Write a one‑line Pascal declaration for a subrange type called Age that allows values from 0 to 120.
  3. In Java, show a concise way to enforce the same range restriction for Age.

Practice Questions (AO3 – Implementation & Testing)

  1. Enumerated: Define an enum Day for the seven days of the week. Write a procedure printDayType that prints “Weekend” for Saturday and Sunday, otherwise “Weekday”. Provide a JUnit test case for each branch.
  2. Subrange: Create a subrange type Age (0..120). Write a function isLegalVoter that returns true if the age is ≥ 18. Supply two test cases (one legal, one illegal) and state the expected outcomes.
  3. Type synonym vs. subrange: Explain the difference between type Money = real; and type Money = 0..1000; in terms of allowed values, precision and program safety. Suggest a scenario where each would be preferable.
  4. Pointer‑type synonym: Using the Pascal node example, write a procedure CountNodes that returns the number of nodes in the list. Show a Java method that performs the same task on the Node class.
  5. Set type: Define a set Weekend of type DaySet. Write a Pascal expression that tests whether a variable d : Day is a weekend day, and the equivalent Java expression using EnumSet.

Coverage Checklist for Unit 13.1

ItemPresent?
Definition of all five non‑composite types
Pascal syntax & Java equivalents
Typical operations (assign, compare, iterate, set ops)
AO mapping (AO1‑AO3)
Design activity (AO2) for each type
Testing activity (AO3) for each type
Common misconceptions (ordinal values, range checking, synonym mixing)
Comparison with composite types
Explicit compile‑time range‑error example
Discussion of ordinal vs. non‑ordinal representations
Quick‑check quiz & practice questions

Next Steps (Link to Paper 4 Practical Skills)

Students should rewrite the full Pascal example in Java (or Python/Visual Basic) to solidify translation of non‑composite types across languages. Suggested tasks:

  • Implement the Grade enum and calculateGrade method in Java.
  • Create a Score class that enforces the 0‑100 range and write JUnit tests for the boundary values 0, 100 and 101.
  • Design a wrapper class for StudentID and discuss how it differs from a simple type synonym.
  • Use EnumSet<Day> to model working days and weekend days, then write a method that returns true if a given Day is a weekend.
  • Explain, in a short paragraph, why a pointer‑type synonym is useful when implementing linked data structures.

Completing these activities will give students practice in:

  • Choosing the most appropriate non‑composite type (AO2).
  • Writing correct, well‑tested code that demonstrates the safety benefits of the chosen type (AO3).
  • Articulating the advantages of non‑composite types in written explanations (AO1).