First exams 2027 · HL only

B4.1.1 · Fundamentals of ADTs

What an ADT actually is, and why it matters

This page starts from nothing: no prior statement required. It builds one small ADT from scratch to show what "defined by its operations, not its implementation" really means.

HL only Typically 2 marks · AO2 Command term: explain

Explainer

Think of a car. You press the accelerator and the car goes faster. You never need to know whether it burns petrol, runs on batteries, or something else entirely, the pedal works the same way regardless. The pedal is the interface; whatever produces the motion is the implementation, and it's completely hidden from you.

Df

An Abstract Data Type (ADT) is a data type defined entirely by what operations it supports, never by how those operations are built. Whoever uses it only needs the operation names and what they do, never what's happening underneath. The worked example below builds one from scratch to show exactly what that means.

You'll be learning more ADTs as this topic continues, linked lists (B4.1.2/1.3), binary search trees (B4.1.4), sets (B4.1.5), and every one of them is a concrete example of this same pattern. This page names the pattern first, so you have it in hand before meeting the specific structures.

This whole topic is really answering one question, the guiding question behind B4 itself: which ADT is most appropriate for a given situation? You can't answer that without first knowing what "an ADT" even means, which is exactly what this page builds. Every later statement in this topic (B4.1.2 through B4.1.6) comes back to this same question, applied to a specific structure.

1

Abstraction

Hiding the complexity of HOW an operation works from whoever is using it. You call add(); you never see the code inside it.

2

Interface

The fixed contract of operation names, inputs and outputs. It's the ONLY thing the rest of the program is allowed to depend on.

3

Modularity

Because the interface never changes, the implementation behind it can be rebuilt, replaced or improved later without breaking any code that uses it.

Worked example

Same interface, two different bodies

Imagine a simple music library ADT with just two operations: add(track) and contains(track). Nothing here depends on any other statement, it's built from scratch below. Click each tab: the METHOD NAMES never change, only what happens inside them.

Interface every caller relies on, never changes: add(track), contains(track)

# Unsorted list underneath: add is instant, contains checks every item
def add(self, track):
    if track not in self.tracks:
        self.tracks.append(track)

def contains(self, track):
    return track in self.tracks   # checks every item, one by one
# Sorted list underneath: add costs more (must find the right spot), contains can stop early
def add(self, track):
    if track not in self.tracks:
        for i, existing in enumerate(self.tracks):
            if existing > track:
                self.tracks.insert(i, track)
                return
        self.tracks.append(track)

def contains(self, track):
    for existing in self.tracks:
        if existing == track:
            return True
        if existing > track:
            return False          # can stop early: list is sorted
    return False

Every caller in the program still writes library.add(x) and library.contains(x), word for word, no matter which tab is active. That's modularity: swap the implementation, the rest of the program notices nothing. (Other statements build on this same idea with real named ADTs, linked lists, trees, sets, hash tables, but this page doesn't assume you've met any of them yet.)

Check your understanding

A program has thousands of lines calling library.add(x). The library's internal implementation is rewritten from an unsorted list to a sorted list. How much of those thousands of lines needs to change?

Common mistake

Markers reported this pattern for B4.1.1

RecurringMarkers reported candidates struggling specifically with questions asking for an advantage of modularity in program development. The concept is easy to state but hard to justify: the weak answers restate that modularity "breaks a program into parts" without saying what that actually buys you.

✕

What a weak answer looks like: "Modularity means splitting a program into separate modules." Describes what it is, not why it helps.

✓

What it should say: "Because each module's interface stays fixed, one module can be rewritten, tested or fixed without needing to change or retest the modules that use it." Names the actual consequence.

Linking question

How this connects to the rest of the syllabus

The IB syllabus is deliberately woven together, not a stack of isolated topics. Here's how ADTs connect specifically to A2 (databases and data management), worth thinking through, not just memorising: it's the kind of synthesis a Paper 1/2 question can genuinely ask for.

A2

Can abstract data types be used to manage data? (Every real database and data-management system is, underneath, built out of ADTs like the ones in this topic: sets to enforce uniqueness, hash tables for fast lookup, trees for sorted access.)

Revision questions

Past-paper style. Write an answer, then reveal the marking points and mark yourself.

Question 1 · 1 mark

[1]State the term for the fixed set of operation names, inputs and outputs that other code is allowed to depend on.

Question 2 · 2 marks

[2]Outline one advantage of using modularity in program development.

Question 3 · 3 marks

[3]Explain why a linked list, a binary search tree and a set can all be described as ADTs, despite storing and organising data in completely different ways.

Flashcards

Active recall for this statement's key terms.