Interfaces

Julia relies on informal interfaces: implement a few methods and your type works with the whole ecosystem.

Julia relies on informal interfaces: implement a few methods and your type works with the whole ecosystem.

16.1 Iteration

Iteration utilities: Iterators.take, drop, cycle, repeated, flatten, product, partition, countfrom, filter, map, zip, enumerate, rest, takewhile, peel.

struct Countdown
    from::Int
end
Base.iterate(c::Countdown, state=c.from) = state < 1 ? nothing : (state, state - 1)
Base.length(c::Countdown) = c.from
Base.eltype(::Type{Countdown}) = Int

for i in Countdown(3); print(i, " "); end   # 3 2 1
collect(Countdown(5)); sum(Countdown(4)); [x^2 for x in Countdown(3)]

16.2 Indexing

Also setindex!, checkbounds, axes.

struct Squares
    n::Int
end
Base.getindex(s::Squares, i::Int) = 1 <= i <= s.n ? i^2 : throw(BoundsError(s, i))
Base.firstindex(::Squares) = 1
Base.lastindex(s::Squares) = s.n
Squares(10)[3], Squares(10)[end]

16.3 AbstractArray interface

Optional: IndexStyle, setindex!, similar, axes. Other interfaces: broadcasting (BroadcastStyle), show, numbers (promote_rule, convert), AbstractDict, AbstractString, IO.

struct OnesVec <: AbstractVector{Int}
    n::Int
end
Base.size(v::OnesVec) = (v.n,)
Base.getindex(v::OnesVec, i::Int) = 1
OnesVec(4) .* 3, sum(OnesVec(10)), OnesVec(3)' * [1, 2, 3]   # everything works

16.4 Conversion & promotion

struct Meters
    v::Float64
end
Base.convert(::Type{Meters}, x::Real) = Meters(x)
Base.promote_rule(::Type{Meters}, ::Type{<:Real}) = Meters