Skip to content

Modules

prepoly organizes code into modules: every file is a module, and directories form the module path. Let’s split a small geometry library across files.

First, write geometry/vec.pp:

type Vec2 = {
x: float64
y: float64
}
fun Vec2.new(x, y) {
return Self { x: x, y: y }
}
fun Vec2.add(self, other) {
return Self { x: self.x + other.x, y: self.y + other.y }
}
fun Vec2.length(self) {
return sqrt(self.x * self.x + self.y * self.y)
}
fun dot(a, b) {
return a.x * b.x + a.y * b.y
}
fun _helper() {
// A name starting with `_` is private to this module.
}

Then use it from main.pp, next to the geometry directory:

import geometry.vec.{ Vec2, dot }
fun main() {
let a = Vec2.new(3.0, 4.0)
let b = Vec2.new(1.0, 2.0)
let c = a.add(b)
println("a + b = ({c.x}, {c.y})")
println("a . b = {dot(a, b)}")
println("|a| = {a.length()}")
}
Terminal window
prepoly main.pp
a + b = (4.0, 6.0)
a . b = 11.0
|a| = 5.0

The import path follows the directory layout relative to the importing file: geometry.vec is geometry/vec.pp. The braced list names what to import.

Two shorter forms cover the other common needs. A single name can skip the braces, and importing the module itself makes its exports available qualified by the path’s last segment. as overrides the qualifier:

import geometry.vec.dot // one name, same as .{ dot }
import geometry.vec // whole module, used as vec.<name>
import geometry.vec as g // same, but used as g.<name>
fun main() {
let a = vec.Vec2.new(3.0, 4.0)
let b = vec.Vec2 { x: 1.0, y: 2.0 }
println("a . b = {vec.dot(a, b)}")
}

A few points worth noting:

  • A type’s methods travel with it: importing Vec2 makes a.add(b) and Vec2.new(...) available with no separate import.
  • A name beginning with _ (like _helper) is private to its module and cannot be imported.
  • The top-level standard library is an implicit prelude — sqrt, println, and the array/string helpers need no import. Nested standard-library modules are not in the prelude and are imported explicitly, e.g. import std.collections.{ HashMap }.

The full rules are in the modules reference.