You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
TODO: Integrate this documentation within the larger MeTTa Book
5
6
6
7
Modules are implementations of free-standing MeTTa functionality that can be imported into other MeTTa modules or programs. Modules may be implemented in MeTTa code itself, but they may also include functionality implemented with, or linked from host languages such as Rust, C, or Python. Modules may include additional files and resources as well.
7
8
8
9
**_NOTE:_** Importantly, a module can have sub-module dependencies, aka "downward" dependencies, but it cannot have "upward" dependencies, ie. dependencies on the client code importing the module.
9
10
10
-
## What *is* a Module?
11
+
###What *is* a Module?
11
12
12
13
Fundamentally a module in a persistent encapsulation of a context within which MeTTa code can run. Every module has a unique [Space] (and also a [Tokenizer], for now). For MeTTa code running within the context of a module, the `&self` token will resolve to the module's space.
13
14
14
15
A loaded module is represented with the [MettaMod] struct. In addition to a [Space] and a [Tokenizer], a module may also contain a filesystem path to the module's resources, the sub-modules imported by the module, a [ModuleDescriptor] object, and a [PkgInfo] struct, the latter of which are documented in the [Package Management](#package-management) section.
15
16
16
17
To execute code in the context of any loaded module, use the [RunnerState::new_with_module] method.
17
18
18
-
## Loading a Module
19
+
###Loading a Module
19
20
20
21
Modules are loaded into a [Metta] runner using one of the module loading methods: [Metta::load_module_direct], [Metta::load_module_at_path], or [RunContext::load_module]. Loaded modules are referred to with a [ModId].
21
22
22
23
Fundamentally, all modules are loaded via a loader object that implements the [ModuleLoader] trait. Irrespective of the module's original format or host language, a loader object's [ModuleLoader::load] function ultimately loads the module into the runner.
23
24
24
-
### Module Names & Name Paths
25
+
####Module Names & Name Paths
25
26
26
27
Each loaded module must have a name. A legal module name is an ascii string, containing only alpha-numeric characters plus `_` and `-`.
27
28
@@ -55,7 +56,7 @@ will cause the name `some_module` to be resolved into a specific module instance
55
56
56
57
**NOTE**: The same module name may occur in multiple places in the hierarchy, and there is no guaranteed a name will always refer to the same module. However, within a given node of the module name hierarchy, a module name will always be unique.
57
58
58
-
## Importing a Module
59
+
###Importing a Module
59
60
60
61
A module is imported into another module using one of the import methods:
61
62
-[MettaMod::import_dependency_as], corresponding to `import module as name`
@@ -64,7 +65,7 @@ A module is imported into another module using one of the import methods:
64
65
65
66
Once imported, a sub-module is accessed via an embedded [Space] atom in the destination module's space, [Tokenizer] entries for accessing the source module's space, tokens, or a combination of the two.
66
67
67
-
### Behavior WIP
68
+
####Behavior WIP
68
69
69
70
TODO: The precise semantics of importing (in other words, linking) are still under discussion and development. Specifically we may wish to provide a mechanism to explicitly declare what is exported from a module (and thus available for import). This would be similar to the `export` key words in some languages, or the `pub` visibility qualifiers in Rust.
70
71
@@ -77,7 +78,7 @@ Some issues regarding this are:
77
78
78
79
More discussion on these topics is in the section: "Importing / Linking" of the `modules_internal_discussion.md` file.
79
80
80
-
# Package Management
81
+
##Package Management
81
82
82
83
Package Management is the set of features that allow for:
83
84
- searching for modules across multiple locations (Catalogs)
@@ -86,15 +87,15 @@ Package Management is the set of features that allow for:
86
87
87
88
Modularity is a fundamental and inseparable aspect of the MeTTa runner, but Package Management features could be optional.
88
89
89
-
## Module File Formats
90
+
###Module File Formats
90
91
91
92
Modules may be loaded from files and other file-system-like resources (for example, a github repo) using the objects that implement the [FsModuleFormat] trait. This trait contains the interface to interpret a file or a directory and instantiate a [ModuleLoader] to load the module(s) contained within.
92
93
93
94
The objects [SingleFileModuleFmt] and [DirModuleFmt] are part of the default environment and are capable of loading MeTTa modules from single `.metta` files and directories containing a `module.metta` file respectively. Additionally, the `hyperon` Python module contains a [FsModuleFormat] for loading MeTTa modules from Python modules - both stand-alone `.py` files as well as directories containing an `__init__.py` file.
94
95
95
96
More information on the individual module file formats is available in the MeTTa usage documentation and MeTTa Python documentation respectively.
96
97
97
-
## The PkgInfo Structure
98
+
###The PkgInfo Structure
98
99
99
100
Each module has an associated [PkgInfo] structure, which provides the module author a place to specify meta-data about the module and express requirements for the module's dependencies. Additionally a [PkgInfo] can provide explicit loading instructions such as file system paths or github URLs for dependent modules. The [PkgInfo] structure is the same concept as the Cargo.toml file used in Cargo/Rust.
100
101
@@ -105,7 +106,7 @@ docs on https://docs.rs when Rust crate is published).
105
106
106
107
TODO: PkgInfo documentation also belongs in user-facing docs. In that section, cover how to specify the pkginfo as a MeTTa structure and/or in a `_pkg-info.metta` or `_pkg-info.json` file as opposed to as a Rust struct.
107
108
108
-
## Module Name Resolution
109
+
###Module Name Resolution
109
110
110
111
When MeTTa code executes the `!(import! &space some_module)` operation, the module name needs to be mapped to a loaded or loadable module. This process occurs according to the logic described by the flowchart below.
111
112
@@ -130,15 +131,15 @@ Depending on the host OS, the config directory locations will be:
130
131
131
132
In the future we may create a centralized module catalog along the lines of `PyPI` or `crates.io`.
132
133
133
-
## Catalogs
134
+
###Catalogs
134
135
135
136
An object that implements the [ModuleCatalog] trait exposes an interface to locate modules based on name and version constraints, and create [ModuleLoader] objects to retrieve and load those modules.
136
137
137
138
One built-in [ModuleCatalog] object type is the [DirCatalog]. As described in the "Module File Formats" section, a [DirCatalog] uses a collection of [FsModuleFormat] objects to export a catalog of modules contained within its associated directory.
138
139
139
140
Additional catalogs may be implemented for other module repository formats or protocols - for example a central package service similar to `PyPI` or `crates.io`, as mentioned earlier.
140
141
141
-
## Implementing a [ModuleLoader]
142
+
###Implementing a [ModuleLoader]
142
143
143
144
All modules are ultimately loaded programmatically through the MeTTa API, and it's the role of a [ModuleLoader] to make the necessary API calls.
0 commit comments