Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BaseTypeContracts.jl

CI Coverage Ready-made TypeContracts.jl contracts for Julia's Base types — analogous to BaseInterfaces.jl for Interfaces.jl.

Load the package and the core standard-library abstract types carry structural contracts and behavioral invariants, so you don't have to write them yourself.

Contract target Protocol Example satisfying type
AbstractArray indexing Vector{Int}
AbstractDict associative Dict{String,Int}
AbstractSet set Set{Int}
AbstractString string String
Number arithmetic Int, Float64
Real ordering Float64, Int64
AbstractFloat IEEE 754 laws Float64, Float32
Integer bitwise ops Int64, UInt8
AbstractChar code point Char
IO byte I/O IOBuffer
AbstractChannel messaging Channel{Int}
Iterable iteration queried explicitly

Installation

using Pkg
Pkg.add(["TypeContracts", "BaseTypeContracts"])

Usage

Loading the package registers everything — there is nothing to declare.

using TypeContracts, BaseTypeContracts

# Does a type satisfy a Base protocol?
implements(Vector{Int}, AbstractArray)      # true
implements(Dict{String,Int}, AbstractDict)  # true
implements(Set{Int}, AbstractSet)           # true
implements(String, AbstractString)          # true
implements(Int, Number)                     # true

# Check all applicable contracts at once (returns Bool)
all_implements(Vector{Int})    # true
all_implements(Float64)        # true — covers Number, Real, AbstractFloat

Detailed results

check returns the full satisfies result per applicable contract:

BaseTypeContracts.check(Vector{Int})
# Dict(AbstractArray => (satisfied = true, …))

BaseTypeContracts.check(Float64)
# Dict(Number => (satisfied = true, …), Real => (satisfied = true, …), …)

Behavioral invariants

The contracts encode real laws, not just method existence — validate them against real objects:

test_behavior(Vector{Int}, AbstractArray, [[1, 2, 3], Int[]])
# checks length == prod(size), eachindex covers length

test_behavior(Int, Number, [0, 1, -5, 42])
# checks x + zero(x) == x and x * one(x) == x

The iteration marker

Iteration has no Base abstract supertype, so BaseTypeContracts provides the Iterable marker. Nothing is <: Iterable — query it explicitly:

implements(Vector{Int}, Iterable)                        # true
test_behavior(String, Iterable, ["abc", ""])             # iterate returns nothing or a 2-tuple

Trait dispatch (juliac-safe)

interface_trait is --trim clean, so it works in statically-compiled binaries:

interface_trait(AbstractArray, Vector{Int})  # Implemented{AbstractArray}()
interface_trait(AbstractArray, String)        # NotImplemented{AbstractArray}()

(Note: numbers such as Int do satisfy the structural AbstractArray contract — Base defines size, getindex and length for scalars — so String is used here as a type that genuinely lacks the indexing methods.)

Inspect a contract

describe(AbstractArray)         # mandatory + optional methods
describe(Number, Val(:all))     # also lists behavioral invariants

Documentation

Full documentation is available at https://el-oso.github.io/BaseTypeContracts.jl/dev/.

Development note

This package was developed with assistance from Claude (Anthropic). All code has been reviewed and is maintained by the author.

License

See the repository for license details.

About

Ready-made [TypeContracts.jl](https://github.com/el_oso/TypeContracts.jl) contracts for Julia's `Base` types — analogous to `BaseInterfaces.jl` for `Interfaces.jl`. Load the package and the core standard-library abstract types carry structural contracts and behavioral invariants, so you don't have to write them yourself.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages