Skip to main content

Modules & Exports

Every .rv file is a module. Modules say what they provide with export, and pull in what they need with import.

Exports

Exports are a single block, conventionally at the top of the file:

export { double, Scale }

bundle Scale()

fn double(x) { x * 2 }

Only exported names are visible to importers – importing something unexported is an error.

Imports

Import from a package by name, or from a file by relative path:

import { map, collect, range } from "common"
import { double } from "./scale.rv"
import { half, Measure } from "./util/measure.rv"

{ ... } is a wildcard, importing everything the module exports:

import { ... } from "./core.rv"

The standard library, common, is imported implicitly in ordinary programs – you don't need to ask for println or map.

Re-exports

A module can forward another module's exports, useful for building a package's public face out of internal files:

export { ... } from "./scale.rv"
export { half } from "./measure.rv"

This is exactly how common itself is put together – one file of re-export blocks.

Packages

A package is just a module tree with a named entry point. Register one on the command line with --package:

$ raven --package maths=maths/maths.rv main.rv

Now import { quadruple } from "maths" works in main.rv. Modules have stable identities: however a module is reached – by package name or relative path – it's the same module, so its types are shared and its definitions exist once.

A fuller package story (manifests, registries, versioning) is on the roadmap.

Functions belong to modules

A subtle but important consequence of modules: defining fn foo(...) creates a new function in your module, even if you imported a foo from elsewhere. To add methods to an imported function, use @extend:

import { ... } from "common"

@extend
fn show(Celsius(deg)) { ... }

Without @extend, the standard library's show is untouched and your method silently never runs.