Skip to content
AgileLogics
5 min read

Modules

Prerequisites: Functions

A module is a separate namespace for code. Every package is a module, and you can define your own:

module Geometry

export area, Circle

struct Circle
    r::Float64
end

area(c::Circle) = π * c.r^2
circumference(c::Circle) = 2π * c.r   # not exported

end # module

using .Geometry

c = Circle(2)
println(round(area(c), digits = 3))
println(round(Geometry.circumference(c), digits = 3))
12.566
12.566
  • export lists the names that using brings into scope.
  • Non-exported names are still reachable with Module.name.
  • using .Geometry — the dot means "a module defined here", not an installed package.

using versus import

module Greetings
export hello
hello(name) = "Hello, $name"
secret() = "hidden"
end

import .Greetings
println(Greetings.hello("Ada"))

using .Greetings: hello
println(hello("Grace"))

import .Greetings as G
println(G.secret())
Hello, Ada
Hello, Grace
hidden
Statement Effect
using Mod Brings in Mod and all its exported names
using Mod: a, b Brings in only a and b
import Mod Brings in only the name Mod; use Mod.f
import Mod as M Same, under a shorter name
import Mod: f Brings in f and allows adding methods to it

Many style guides prefer using Mod: a, b in packages, so it's clear where each name comes from.

Splitting code across files

include("file.jl") runs another file's code as if it were pasted in. A typical package module looks like this:

# illustrative — src/Inventory.jl
module Inventory

export Item, add_item!, total_value

include("types.jl")      # defines Item
include("operations.jl") # defines add_item!, total_value

end

Each file is included once, from the module file. Don't include the same file from several places — that defines things twice.

Main and Base

Code you run in the REPL or a script lives in the module Main. Julia's built-in functions live in Base (and standard libraries like LinearAlgebra are modules too) — that's why you write Base.show(...) when adding a method to show.