The Myrddin Module System Is Very Simple
The Myrddin module system is simple and easy to understand. There simply isn't much to it. Your code is written in files. Your files export symbols into a namespace. Multiple files may export symbols into the same namespace. These files are assembled by the build system into packages. The list of files in a package is explicit in your build file.
Because the package is compiled, importing the package from within a package won't work. Since it's useful to import functions from other files in the same package, you may import files that are part of the current project directly.
The Module System Is Easy To Understand
Myrddin was designed with care to allow for separate compilation. There is no complexity from the compilation model that the system needs to deal with.
You either point the use
statement at a file in your directory, or you point
it at a package that has already been compiled. As a result, your source files
form a directed graph of dependencies. Cycles are not allowed. The build system
reads your sources and builds them in reverse topological order, starting at
the leaves of the DAG and walking upwards.
The search path for the modules is simple and fairly explicit. If you
explicitly want a package within the project, you use the lib
clause
in your build file. Otherwise, the paths given by -I
are searched,
followed by $prefix/lib/myr.
There Isn't Much Syntax
The module system has exactly two keywords, use
and pkg
.
Importing symbols is done via use packagename
, where packagename
is either
a single keyword referencing a package (eg, use std
), or a quoted string
referencing a file in the project (eg, use "mysource"
).
Exporting symbols into packages is done via pkg foo = declarations ;;
, where
foo
is the package namespace, and declarations
is a list of symbols that
should be exported. By convention, the types are manifestly declared here for
readability. However, the syntax of the declaration is exactly the same as the
syntax of any declaration at any other point in the file.
For example, if you had a file named hello.myr
, you might write:
use std
pkg demo =
const hello : (-> void)
;;
const hello = {; std.put("hello world!\n")}
This exports the hello
function into the demo
namespace. adding another
file that exports a function in the namespace is trivial. For example,
if this were in goodbye.myr
, you might write:
use std
pkg demo =
const goodbye : (-> void)
;;
const goodbye = {; std.put("goodbye world!\n")}
Now, if you want a function that calls both functions above, you might create a file named "greetdepart.myr", with the following code inside:
use std
use "hello"
use "goodbye"
pkg demo =
const hibye : (-> void)
;;
const hibye = {
hello()
goodbye()
}
You may notice that std
is not quoted, but "hello"
and "goodbye"
are
quoted. This is how Myrddin handles the distinction between packages and files
when referencing code in the use statements.
To build this, you might put the following into your bld.proj
file:
lib demo =
hello.myr
goodbye.myr
greetdepart.myr
;;
At this point, you can run the following to build and install the code:
$ mbld install
project base /home/ori/x:
/libdemo.a...
6m hello.myr
6m goodbye.myr
6m greetdepart.myr
muse -o libdemo.use -p demo greetdepart.use goodbye.use hello.use
ar -rcs libdemo.a greetdepart.o goodbye.o hello.o
libdemo.use => /home/ori/bin/lib/myr/libdemo.use
libdemo.a => /home/ori/bin/lib/myr/libdemo.a
And any future projects can use it via:
use demo
const main = {;demo.hibye()}
There Is No Namespace Graph
A package contains all the exported symbols in the namespace. Namespaces do not nest, and do not include other namespaces. And importing a namespace does not import any dependent symbols from any other namespace.
There's no need for complexity or construction of a namespace graph.
There Isn't Any More
Really. This is a full description. Some people may call it crude. Others might call it simplistic. Some might even call it a steaming pile of shit. They'd probably be right.
Thanks to Without Boats for the description of the Rust module system that inspired me to write this up.