Concepts / Template Design Principles

Template Design Principles

Templates are used to express algorithms that apply to many argument types.

  • Programming

One Logic, Many Kinds of Data

Many programs need the same logic over and over again, but applied to different kinds of data. A sorting routine is a good example: the steps for putting values into order are the same whether the values are numbers, words, or records of some custom kind. A stack of items and a list of values follow the same pattern. Templates are the tool for describing code this way, so that the logic is written once and then used with many types.

What do you think happens?

You have written a sorting routine that works on a list of integers. What has to change in the routine itself so that it can sort a list of text strings instead?

  • Every comparison and swap has to be rewritten for text

  • Only the type of the data needs to be supplied; the written steps can stay the same

  • A separate sorting routine has to be written from scratch for each type

Reveal answer
Answer:

Only the type of the data needs to be supplied; the written steps can stay the same

The source describes the key idea as separation. The steps of the algorithm are written in terms of the operation being performed, while the specific type of the data is left open. When a particular argument type is needed, that type is supplied and the same written logic serves it.

Templates as Patterns with Open Type Slots

Definition

A template is a pattern with open type slots. The pattern describes the structure of an algorithm or a container, and the concrete types that fill those slots are chosen later, when the template is used.

Think of a template as a fixed body of logic with a blank in it. The blank is the type parameter. Everything that does not depend on the type stays exactly as written. When the template is needed for a particular argument type, that type is supplied, and the compiler or language machinery produces a concrete version that uses it. The source states the purpose directly: use templates to express algorithms that apply to many argument types. The written logic is shared; the concrete versions differ only in the type that was plugged into the open slot.

Sort templatesteps written once, typeslot openSort for integersslot filled with integerSort for textslot filled with textSort for recordsslot filled with a recordtypeinstantiated with integerinstantiated with textinstantiated with record type
How a single template definition becomes several concrete versions once a type is supplied for its open slot, and how each version stays linked to the original definition.

Tracing One Template Through Two Argument Types

Worked example

Applying a largest-value template to two types

A template describes an algorithm that returns the largest of three values. The steps are: start with the first value as the current largest; compare each remaining value with the current largest; replace the current largest when a bigger value appears. The type of the values is left open. Trace how the same written logic serves integers and text.

  1. 1
    Identify the open slot

    The element type is the open slot. The steps mention only the operation of comparison and never name a specific type, so the logic is the same for any type that supports comparison.

  2. 2
    Supply integers

    With the slot filled by integers and the values 4, 9, and 2, the steps run: current largest is 4; 9 is bigger, so it becomes 9; 2 is not bigger, so 9 stays. The result is 9.

  3. 3
    Supply text

    With the slot filled by text and the values pear, apple, and plum, the same steps run: current largest is pear; apple is not bigger; plum is bigger than pear in alphabetical order, so the result is plum.

  4. 4
    Compare the two runs

    The written steps did not change between the two runs. Only the type supplied for the slot changed, and the comparison operation carried the meaning of bigger for each type.

Result

One written algorithm produced correct results for two different argument types, because only the type slot was filled differently each time.

Containers That Hold Any Element Type

Without templates, a container for integers and a container for text would each need its own separate definition, even though their structure is the same. Both hold a sequence of elements, store them in order, and offer the same ways of adding and reading elements. Only the element type differs. Expressing the container as a template keeps the shared structure in one place and leaves the element type to be chosen by whoever uses the container.

element 042element 0appleelement 17element 1pearelement 219element 2plum
A generic container holding integers and a container of the same structure holding text. The arrangement of positions is identical; only the values stored in those positions differ.

The diagram shows why the template form helps. Both containers have the same three ordered positions. Their structure is the shared part that the template keeps in one place. The stored values are the part that changes with the element type, and that part is supplied by the user of the container. A user-defined type can be stored in the same way, because the container does not need to know what the element is in order to hold it.

Raising the Level of Abstraction

Abstraction means working with the idea of something rather than its every concrete detail. Templates raise the level of abstraction of code. The code is written in terms of general roles such as element, operation, or container, and concrete types are attached later. Because of this, a reader can understand what an algorithm or container does without tracing every specific type it might be used with.

sort for integersfull set of stepsgeneric sortsteps written oncesort for textfull set of steps againtype slotsupplied per usesort for recordsfull set of steps againuses
Three type-specific sorting routines written by hand, compared with one generic routine. The hand-written routines repeat the same steps; the template writes those steps once and shares them.
Best practice

When you write a template, name the roles in the code after what they do, such as element, operation, or container, rather than after a particular type. Readers can then follow the logic without needing to know which types will eventually use it.

Mistakes When Reading Templates

  • Common mistake

    Treating the template as one ordinary function that works for everything

    Why it fails

    A template is a pattern. It becomes a concrete version only when a type is supplied for its open slot, so the concrete versions are what actually run.

    Do this instead

    Think of the template as the shared description and reason about each concrete version separately when you need exact behavior.

  • Common mistake

    Assuming the same steps are safe for any type without checking

    Why it fails

    The algorithm is written in terms of an operation, such as comparison. A supplied type must support the operation the steps rely on.

    Do this instead

    Check that the chosen type supports every operation the template's steps use before relying on the result.

  • Common mistake

    Writing a separate container definition for each element type

    Why it fails

    The structure of the container is the same for integers, text, and other types, so repeating it duplicates the shared part.

    Do this instead

    Express the container once as a template and let each user choose the element type.

Practice Reading a Template

MEDIUM

A template describes a stack that holds items of an open element type, with operations to push an item and pop an item. Explain which part of this description stays the same for every use, and which part is chosen when the stack is used for a particular type.

Hints
  • Ask which parts of the stack's behavior, such as push and pop, depend on the kind of item being stored.
  • The element type is the open slot; the operations and the ordering of items are the shared structure.

Key Takeaways

  • A template expresses an algorithm once, leaving the argument type open so the same written logic can serve many types.
  • A template for a container keeps the shared structure in one place and lets the user of the container choose the element type.
  • Templates raise the level of abstraction by describing code in terms of general roles such as element, operation, or container, with concrete types attached later.
  • A template is a pattern; each concrete version exists only once a type has been supplied for the open slot.

Related concepts

More concepts starting with T