millionchart
فارسی

Modules and libraries

Put functions and types you reuse in a module, import them into other scripts with a version, and know the rules about cycles, names and limits.

When the same function turns up in three scripts, move it to a module. A module is a script whose job is to be imported: it draws nothing of its own, it only exports names. Other scripts import it and call what it exports.

Write a module#

A module starts with module Name instead of indicator "Name". Anything marked export can be imported; the rest is private.

Cuprel
// A module: a running mean kept in a record. Other scripts import it by name and version.
module Stats
    edition = 1

export type Stats
    n: int = 0
    total: float = 0

export fn Stats.add(self: Stats, x: float)
    self.n += 1
    self.total += x

export fn Stats.mean(self: Stats): float = if self.n > 0 then self.total / self.n else na

A module draws nothing by itself, so it cannot run on a chart on its own: the engine refuses it with This is a library: other scripts import it; it does not draw on its own.

Import it#

import Owner/Name@version as alias brings a module in. Only your own modules can be imported in this release: the owner is written Me (the engine finds the module by its name and does not look at the owner), the name is the module's name, and the version is written 1. The alias is how you reach what the module exports.

Cuprel
// Using the module: the running mean of every close so far, drawn next to the close.
indicator "Running mean"
    edition = 1
    display = price

import Me/Stats@1 as mu
state stats = mu.Stats(n = 0)
stats.add(close)
plot(stats.mean(), name = "Mean of every close so far", color = color.orange)
plot(close, name = "Close", color = color.gray)
  • mu.Stats(n = 0) builds a record of the imported type, by naming its fields.
  • stats.add(close) and stats.mean() call methods that the module exports.
  • The module runs with a separate memory for every import: two scripts that import it do not share state.

An import without a version is refused:

Cuprel · error E2070
indicator "An import with no version"
    edition = 1
import Me/Stats as mu
plot(close)

Rules#

  • Versions. The version is required in the text of the import. This release has no second version of a module: write @1.
  • Names. If you use a name that the module does not export, the error is E3172. Only exported functions, types and enums are visible.
  • No cycles. A module may not import itself, directly or through other modules. The error is E-IMPORT-CYCLE, and the message names the chain, a -> b -> a.
  • A module that is not there. Importing one you do not have gives an error that names the library.

Limits#

Modules are bounded before they compile:

LimitValue
Modules importing modules, deep8
Imports compiled for one script, including those inside modules64
Characters of module text compiled for one script1,000,000

Real scripts use one level and a few imports. Beyond a limit the script stops with E-IMPORT-DEPTH, E-IMPORT-COUNT or E-IMPORT-SIZE, naming the one that was passed.

See also: Functions, types and enums, Limits and budgets.