3.6. modules and loading

To reuse code across projects, alv code can be split up over multiple files and loaded as modules.

loading modules

To load modules, require, import and import* can be used:

require can load two types of modules: native modules written in Lua/MoonScript (such as everything listed in this reference), and modules written in alv itself. The latter are looked up relative to the file containing the (require …) expression, and are should match the module name with the file extension .alv; i.e. my-module.alv for the example above.

If a module is imported multiple times, it is only evaluated once and its result is reused.

writing modules

When an alv script file is imported, its ‘value’ is that of the last expression inside it:

my-module.alv

(print "loading my-module...")

4

main.alv

(import* string)
(print (str "my-module's value is " (require "my-module")))
loading my-module...
my-module's value is 4

Often it is useful to export multiple values from a file, for example when writing a library containing multiple functions. There are two operators to allow this: export and export*.

export creates a new scope and evaluates all its arguments in it, just like do. However it doesn’t return the result of the evaluations, but rather the newly created scope. It can therefore be combined with def, defn etc. to export symbol definitions:

my-module.alv

(import* math string)
(export
  (def a-value 7)

  (defn print-doubled (x) (print (str x " doubled is " (* x 2)))))

main.alv

(import* string)
(import my-module)

(print (str "my-module/a-value is " my-module/a-value))
(my-module/print-doubled 4)
my-module/a-value is 7
4 doubled is 8

export* on the other hand operates on the containing scope rather than creating a new one. When Used without any arguments, it returns the containing scope itself and can be used to (re-)export everything that is currently defined. When arguments are passed, only those symbols that are explicitly mentioned are exported:

my-module.alv

(def a 1)
(def b 2)
(def c 3)

(export* a b)

main.alv

(import* string)
(import* my-module)

(print (str "a is " a))
(print (str "b is " b))
(print (str "c is " c))
a is 1
b is 2
reference error: undefined symbol 'c'