89 lines
2.5 KiB
Markdown
89 lines
2.5 KiB
Markdown
# Modules and Imports
|
|
|
|
`import` returns a DCDL module or structured value resolved by the host.
|
|
|
|
## Syntax
|
|
|
|
```dcdl
|
|
import "./config.dcdl"
|
|
```
|
|
|
|
An import specifier is a string literal.
|
|
The host decides whether a specifier represents a path, URL, resource name, or another form of identifier.
|
|
|
|
## Modules
|
|
|
|
A sequence of field definitions at the top level creates a recursive module scope.
|
|
A top-level field can refer to another top-level field in the same module by identifier.
|
|
|
|
```dcdl
|
|
schema = {
|
|
name = String;
|
|
};
|
|
|
|
result = schema;
|
|
```
|
|
|
|
Fields in an ordinary object literal do not implicitly refer to sibling fields by identifier.
|
|
To reference a value from inside an object, use a binding in an outer scope or an explicit path reference.
|
|
|
|
Modules and their fields are evaluated lazily.
|
|
An unreferenced field of an imported module is not evaluated.
|
|
|
|
## Host-defined resolution
|
|
|
|
Decodal does not define filesystem or network rules for import specifiers.
|
|
The host receives the importing module and specifier, then returns one of:
|
|
|
|
- DCDL source
|
|
- A structured value constructed by the host
|
|
|
|
The latter allows a host to parse Markdown, JSON, TOML, and other formats according to its own rules and expose the result as an ordinary Decodal value.
|
|
|
|
```dcdl
|
|
Post = {
|
|
frontmatter = {
|
|
title = String;
|
|
draft = Bool default false;
|
|
};
|
|
body = String;
|
|
};
|
|
|
|
post = (import "./hello.md") as Post;
|
|
```
|
|
|
|
Structured values follow the same rules as source-derived values for path references, composition, constraint validation, and materialization.
|
|
See [Embedding](../embedding.md#imports) for the loader API and diagnostic provenance.
|
|
|
|
## Cyclic imports
|
|
|
|
Modules may import one another cyclically as long as the dependency graph of the fields actually evaluated is not cyclic.
|
|
|
|
```dcdl
|
|
# main.dcdl
|
|
schema = {
|
|
name = String;
|
|
};
|
|
|
|
result = (import "./func.dcdl")(schema);
|
|
```
|
|
|
|
```dcdl
|
|
# func.dcdl
|
|
(input: (import "./main.dcdl").schema) => input
|
|
```
|
|
|
|
Here, `func.dcdl` imports `main.dcdl`, but the referenced `schema` does not depend on `result`, so evaluation succeeds.
|
|
Reaching the same field again while it is being evaluated produces a cycle-dependency diagnostic.
|
|
|
|
## Import failures
|
|
|
|
The following conditions produce an import failure:
|
|
|
|
- The host cannot resolve the specifier.
|
|
- The resource cannot be read.
|
|
- Parsing DCDL source fails.
|
|
- A required value in the imported module cannot be evaluated.
|
|
- Reading or converting a structured value fails.
|
|
- The evaluated dependency graph is cyclic.
|