Modules & Imports

Splitting Chasm code across files with import and module-qualified calls.

Chasm files are modules. A module exports its def functions and extern fn declarations. defp functions are private, they cannot be called from other modules.

Importing a Module

import "math_utils"

The path is relative to the current file, without the .chasm extension. Once imported, all public functions from math_utils.chasm are available in the current file.

Module-Qualified Calls

Call a function from an imported module using the module.function(args) syntax:

import "math_utils"

def main() do
  d = math_utils.distance(0.0, 0.0, 3.0, 4.0)
  print(d)   # 5.0
end

Unqualified calls also work when there is no name conflict:

d = distance(0.0, 0.0, 3.0, 4.0)   # also valid

Module-qualified syntax is preferred when the same function name exists in multiple imports.

Defining a Module

math_utils.chasm:

# Public, exported to importers
def distance(ax :: float, ay :: float, bx :: float, by :: float) :: float do
  dx = bx - ax
  dy = by - ay
  sqrt(dx * dx + dy * dy)
end

# Private, only callable within this file
defp sq(x :: float) :: float do
  x * x
end

What Gets Exported

DeclarationExported?
def fn(...)Yes
defp fn(...)No
extern fn ...Yes
@attr :: ...No, attrs are module-private
defstruct ...Yes (type usable in other modules)
enum ...Yes

Module attributes (@name) are never exported. Each module manages its own state.

Shared Utility Pattern

A common pattern is a shared utility file that the game module imports:

utils.chasm:

def lerp_angle(a :: float, b :: float, t :: float) :: float do
  a + angle_diff(a, b) * t
end

def sign_of(x :: float) :: float do
  if x > 0.0 do 1.0 else if x < 0.0 do -1.0 else 0.0 end end
end

game.chasm:

import "utils"

def on_tick(dt :: float) do
  @angle = utils.lerp_angle(@angle, @target_angle, 5.0 * dt)
end

Import Resolution

The compiler resolves imports relative to the importing file's directory. Nested imports are allowed, if a imports b and b imports c, all three are merged into the final compilation unit.

Circular imports are not allowed and will produce a compile error.