liveBook · Manning

Generics

As explained in Julia as a Second Language

A parametric method is a method whose signature includes type parameters that constrain or relate its argument types.

A parametric method uses a type parameter to describe a relationship between its arguments. Instead of writing a separate search method for every element type, define one method that works across types while requiring the search value to match the collection’s element type. section 18.1

Listing 18.1 linearsearch in collection haystack for element needle
function linearsearch(haystack::AbstractVector{T}, needle::T) where T
   for (i, x) in enumerate(haystack)
       if needle == x
           return  i
       end
   end
   nothing
end

In `linearsearch(haystack::AbstractVector{T}, needle::T) where T`, the `where` clause declares `T`. Its two appearances require the vector elements and the needle to share that type. section 18.1

A mismatch is rejected

`linearsearch([4, 5, 8], 5)` returns `2`. Searching the same vector for `"five"` produces a `MethodError`: this method does not accept a string needle with integer elements. section 18.1

A type parameter can also eliminate repetitive methods. `kindof(x::T) where T = T` returns the argument’s type without separate definitions for integers, strings, and every other type. For parametric types, think of `P{T}` as supplying a type to a template to obtain a concrete type. section 18.1 section 10.2.1

Listing 18.7 Point and Vec2D defined so the type parameter must be a number type
import Base: +, -
 
struct Point{T<:Number}
    x::T
    y::T
end
 
struct Vec2D{T<:Number}
    Δx::T
    Δy::T
end
 
"Adding vector `v` to point `p` creates a new point"
function +(p::Point{T}, v::Vec2D{T}) where T
    Point(p.x + v.Δx, p.y + v.Δy)
end
 
"Subtracting two points gives a vector"
function -(p::Point{T}, q::Point{T}) where T
    Vec2D(p.x - q.x, p.y - q.y)
end

The `Point` and `Vec2D` definitions constrain their type parameter to `Number`. Their addition method uses the same `T` for both arguments, so it requires matching coordinate types. section 18.3

Choose parameters to express the relationship you need. `Point{T}` and `Point{S}` allow two points to have different coordinate types; using `Point` without a parameter leaves that relationship unspecified. A broader method can instead constrain each parameter to an integer type with `Point{<:Integer}`. section 18.3

Generic methods also work alongside conversion and promotion. For mixed angle units, promoting both operands before arithmetic avoids defining an operation for every pair of units; `promote_rule` specifies the target type. This is a related reuse technique, not a requirement for every parametric method. section 9.3.7

How Julia as a Second Language covers it

How deep it goes
Works through `where` clauses, matching and differing parameters, and subtype constraints; does not develop compiler internals for parametric methods.
Examples
Tests a linear search, implements a typeof-style function, and defines operations on parameterized points and vectors.
What it assumes
Assumes familiarity with Julia methods, type annotations, and collections; refreshes type parameters through a function-call analogy.
What you can do after
Build it from scratch: write parametric Julia methods that reuse code and enforce intended argument-type relationships.
How it connects
Connects parametric methods to parametric types, subtype constraints, multiple dispatch, conversion, and promotion.

Also explained in

Compare how 20 books explain generics →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Julia as a Second Language. The section links point to the parts of the book it draws on.