# The Standard Library

Every language ships with a set of "batteries included" — ready-made types and functions so you don't reinvent the basics. Julia's is called the **standard library**, and a lovely fact about it is that it's almost entirely **written in Julia** and open source (MIT licensed). You can read exactly how `sort` or `Dict` is implemented, and contribute improvements. This final chapter is a guided tour of what's in the box.

## Base: always there, no import needed

`Base` is loaded automatically in every session. You've been using it the entire book:

- **Types** — `Int`, `Float64`, `Bool`, `String`, `Char`, `Complex`, `Rational`, `Array`, `Tuple`, `NamedTuple`, `Dict`, `Set`
- **Core functions** — `println`, `length`, `push!`, `sum`, `map`, `filter`, `sort`, `reduce`, `minimum`, `maximum`
- **Math** — `sqrt`, `abs`, `exp`, `log`, `sin`, `round`, `floor`, `ceil`, `clamp`
- **Introspection** — `typeof`, `eltype`, `fieldnames`, `methods`, `@which`

A few Base functions worth knowing that beginners often miss:

```{code-block} julia
reduce(+, [1,2,3,4])                  # 10 — general fold
mapreduce(abs2, +, [1,2,3])           # 14 — map and reduce in one pass, no temporary
foldl(-, [1,2,3])                     # -4 — explicitly left-associative
accumulate(+, [1,2,3,4])              # [1,3,6,10] — running totals
count(>(2), [1,2,3,4])                # 2
any(iseven, [1,3,5])                  # false
all(>(0), [1,2,3])                    # true
findfirst(>(2), [1,2,3,4])            # 3 — the index
zip([1,2,3], "abc")                   # pairs up two collections
partialsort([5,3,1,4], 1:2)           # smallest two, without full sort
```

`mapreduce` deserves the callout. `sum(abs2, xs)` and `mapreduce(abs2, +, xs)` compute the sum of squares without ever materializing an array of squares. Many Base reductions take an optional function as their first argument this way — `sum(f, xs)`, `maximum(f, xs)`, `count(f, xs)` — and it's consistently the allocation-free option.

Also note `>(2)` in those examples. That's a **partially applied operator**: `>(2)` is a function that tests whether its argument is greater than 2. Very handy inside `filter`, `count`, and friends. (Julia 1.12 generalized this machinery with a `Fix` type, so more functions support partial application than before.)

## Standard library packages

These ship with Julia but need a `using` line. No installation, no `Project.toml` entry needed.

### Statistics

```{code-block} julia
using Statistics

mean(xs)
median(xs)
std(xs)
var(xs)
quantile(xs, 0.95)
cor(xs, ys)
cov(xs, ys)

mean(A; dims = 1)        # column means of a matrix
```

### LinearAlgebra

```{code-block} julia
using LinearAlgebra

A \ b                    # solve Ax = b — the workhorse
det(A), tr(A), rank(A)
norm(v)
dot(u, v), cross(u, v)
eigen(A)                 # eigenvalues and eigenvectors
svd(A), qr(A), lu(A), cholesky(A)
I                        # the identity, sized automatically
Diagonal(v), Symmetric(A), UpperTriangular(A)
```

Those last few are worth understanding as a design lesson, not just an API. `Symmetric(A)` doesn't copy anything — it wraps `A` in a type that *tells the compiler* the matrix is symmetric. Dispatch then picks specialized algorithms. Encoding a mathematical property in the type system, and getting a faster algorithm for free, is Julia's whole approach in miniature.

### Random

```{code-block} julia
using Random

rand()                   # uniform [0,1)
rand(1:6)                # a die roll
rand(1:6, 100)           # a hundred of them
randn(1000)              # standard normal
shuffle([1,2,3,4])
Random.seed!(42)         # reproducibility
rng = MersenneTwister(42)   # or an explicit generator
```

Pass an explicit `rng` to functions in code you want reproducible. Relying on the global generator works until you add threads.

### Dates

```{code-block} julia
using Dates

today()
now()
d = Date(2026, 7, 28)
d + Month(3)             # 2026-10-28
Dates.format(d, "yyyy-mm-dd")
Date("2026-07-28", "yyyy-mm-dd")
dayofweek(d), month(d), year(d)
```

Real date arithmetic with calendar-aware periods. If you've done fiscal-period logic in another language you'll appreciate that `Month(1)` knows February is short.

### Test

```{code-block} julia
using Test

@testset "ledger" begin
    @test net_pay(1000, 0.1) ≈ 900
    @test_throws ArgumentError net_pay(-1, 0.1)
    @test length(entries) == 3
end
```

Run with `] test`. That's the whole setup — no config file, no test runner to install.

### Printf, Serialization, and friends

```{code-block} julia
using Printf
@printf("%.2f%%\n", 8.25)         # C-style formatting

using Serialization
serialize("model.jls", my_object)
obj = deserialize("model.jls")

using Downloads
Downloads.download("https://example.com/data.csv", "data.csv")
```

Others in the box: `Logging`, `Profile`, `SparseArrays`, `Distributed`, `Sockets`, `SHA`, `UUIDs`, `Base64`, `DelimitedFiles`, `Pkg` itself.

### SparseArrays

Worth a special mention if you do any large-scale numerical work:

```{code-block} julia
using SparseArrays

S = sparse([1, 2, 3], [1, 2, 3], [1.0, 2.0, 3.0])
S * dense_vector          # dispatches to a sparse algorithm automatically
```

Again the pattern: a different type, the same operators, a completely different algorithm chosen for you.

## Files and I/O

```{code-block} julia
# Read a whole file
content = read("ledger.csv", String)
lines = readlines("ledger.csv")

# Stream it — for files bigger than memory
open("big.csv") do io
    for line in eachline(io)
        process(line)
    end
end

# Write
open("output.txt", "w") do io
    println(io, "result: $value")
end

# Paths, portably
joinpath("data", "2026", "ledger.csv")
isfile(path), isdir(path), mkpath(dir)
basename(path), dirname(path), splitext(path)
```

Use `joinpath` rather than string concatenation with slashes. It's the difference between code that works on your Mac and code that works on the deployment server.

## How to explore further

The standard library is large, so the most useful skill isn't memorizing it — it's knowing how to look things up:

- **`?name` in the REPL.** Every function is documented. This is faster than a web search and always matches your installed version.
- **`apropos("interpolate")`** searches all docstrings for a word when you don't know the function's name.
- **`methods(f)`** shows every method of a function, with the file and line of each.
- **`@which f(x)`** tells you which one your call landed on; **`@edit f(x)`** opens it.
- **`names(Statistics)`** lists everything a module exports.
- The [official manual](https://docs.julialang.org/en/v1/) is genuinely excellent as a reference.

A good habit: before writing a utility yourself, spend two minutes checking whether Base already has it. More often than you'd expect, it does — and the built-in version is faster, better-tested, and composes with everything else.

## Where you are now, and where to go next

Take a breath and look back at the ground we've covered. You started by installing Julia and printing "Hello, world!". Along the way you learned:

- how Julia stores data, and why the memory layout of a typed array is where the speed comes from,
- control flow and functions, the everyday building blocks,
- the collections you'll actually use, and the broadcasting notation that makes working with them feel like mathematics,
- how the type system is organized, and how to add your own types to it,
- multiple dispatch — the idea the whole language is built around,
- modules, environments, and how Julia makes reproducibility the default,
- metaprogramming, and the discipline to use it sparingly,
- how to borrow Python's ecosystem and call into C when you need to,
- who owns what data, and when it gets copied,
- how to find and fix the handful of mistakes that separate slow Julia from fast Julia,
- how to use every core in your machine, and your GPU,
- and what the compiler is actually doing with all of it.

That's a real foundation. You can now write Julia that's expressive *and* fast — the exact combination that pulled me to this language in the first place.

From here, the natural next step is to point these skills at real problems. In future installments, that's exactly where we're headed: data analysis, visualization, transformation, and ultimately training and deploying machine-learning models — all the way from a research notebook to production hardware, in one language.

Thank you for coming this far with me. This book began as my own attempt to rebuild my research code on a foundation I could trust to scale, and if it's helped you take even a few steps along that same path, then it's done its job.

Now go build something.
