Skip to content

Commit 0cf7f31

Browse files
committed
docs: simplify symbolic imports to a quoted-import-equivalent model
1 parent cb3fe7f commit 0cf7f31

1 file changed

Lines changed: 21 additions & 41 deletions

File tree

SPEC.md

Lines changed: 21 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ Revisions to this specification are made periodically in order to correct errors
8787
- [Import Statements](#import-statements)
8888
- [Import URIs](#import-uris)
8989
-[Symbolic Import Forms](#-symbolic-import-forms)
90-
-[Scoping Rules for Symbolic Imports](#-scoping-rules-for-symbolic-imports)
9190
- [Importing and Aliasing Structs](#importing-and-aliasing-structs)
9291
- [Importing and Aliasing Enums](#importing-and-aliasing-enums)
9392
- [Task Definition](#task-definition)
@@ -3906,15 +3905,9 @@ This demonstrates that `~{verbosity}` produces the choice name "Info", while `~{
39063905

39073906
Although a WDL workflow and the task(s) it calls may be defined completely within a single WDL document, splitting them across multiple documents can be beneficial for modularity and code reuse. Furthermore, complex workflows consisting of multiple subworkflows must be defined across multiple documents because each document is allowed at most one workflow.
39083907

3909-
The `import` statement is the basis for modularity in WDL. A document may contain any number of `import` statements. Two import forms are supported:
3908+
The `import` statement is the basis for modularity in WDL. A document may contain any number of `import` statements. An import names a source and selects which of the source's items enter the importing document's scope. A source is either a quoted URI (see [Import URIs](#import-uris)) or ✨ an unquoted symbolic module path resolved through the consuming module's `module.json` per the [WDL Module Specification](modules/SPEC.md). The three available forms are described in [✨ Symbolic Import Forms](#-symbolic-import-forms).
39103909

3911-
1. **Quoted URI imports.** A quoted string literal is treated as a URI (local path, `http://`, or `https://`). These imports behave as described below in [Import URIs](#import-uris), [Importing and Aliasing Structs](#importing-and-aliasing-structs), and [Importing and Aliasing Enums](#importing-and-aliasing-enums). Remote URL imports (`http://`, `https://`) are soft-deprecated starting in WDL 1.4 in favor of the symbolic import form below; compliant engines should emit a warning when encountering them.
3912-
3913-
2.**Symbolic module imports.** An unquoted path refers to a module declared in the consuming module's `module.json`. Resolution is defined by the [WDL Module Specification](modules/SPEC.md). The symbolic import forms—including the `from` syntax for selective member imports—are described in [✨ Symbolic Import Forms](#-symbolic-import-forms) below.
3914-
3915-
Because existing `import` statements require quotes, any unquoted `import` source is unambiguously a symbolic import; no new marker or keyword is required to distinguish the two.
3916-
3917-
Each imported WDL document is assigned a unique namespace used to refer to its members. For quoted imports, the default namespace is the filename minus the `.wdl` extension, and it may be overridden with `as <identifier>`. The tasks and workflows imported through a namespace are accessible only through that namespace—see [Fully Qualified Names & Namespaced Identifiers](#fully-qualified-names--namespaced-identifiers) for details.
3910+
✨ Remote URL imports (`http://`, `https://`) are soft-deprecated in WDL 1.4 in favor of symbolic module paths; compliant engines should emit a warning when encountering them.
39183911

39193912
```wdl
39203913
import "http://example.com/lib/analysis_tasks" as analysis
@@ -3957,49 +3950,36 @@ Some examples of correct import resolution:
39573950

39583951
### ✨ Symbolic Import Forms
39593952

3960-
A symbolic import names a module declared in the consuming module's `module.json`. The three forms of symbolic import are:
3953+
An import statement takes one of three forms. Every form accepts the same two source styles, and the source style affects only how the build system locates the imported document.
39613954

3962-
1. `import <module-path> [as <alias>]` — every top-level item exposed by the module's entrypoint is brought into scope under a namespace. The namespace defaults to the last component of `<module-path>`; `as <alias>` renames it.
3963-
2. `import * from <module-path> [as <alias>]` — every top-level item exposed by the module's entrypoint is brought into the consuming document's scope. Without `as <alias>`, items enter scope unqualified; `as <alias>` groups them under `<alias>` and is therefore equivalent to `import <module-path> as <alias>`.
3964-
3. `import { <member> [as <Name>], ... } from <module-path> [as <alias>]` — only the selected items are brought into scope. Each `<member>` is a dotted path (`<name>`, `<ns>.<name>`, `<ns>.<inner>.<name>`, and so on) into the module's exposed surface. A per-member `as <Name>` renames the selected item locally; the trailing `as <alias>` groups all selected items under `<alias>`. A trailing comma after the last member is permitted.
3955+
1. `import <source> [as <alias>] (alias <Old> as <New>)*`. User-defined types (structs and enums) from `<source>` are copied into the importing document's scope. Tasks and workflows from `<source>` are accessible only through the import's namespace, which defaults to the filename minus the `.wdl` extension for a quoted URI or to the last component of the path for a symbolic module path. `as <alias>` overrides the default namespace; `alias <Old> as <New>` renames a struct or enum as it is copied. `alias` cannot rename tasks or workflows. See [Fully Qualified Names & Namespaced Identifiers](#fully-qualified-names--namespaced-identifiers) for how the namespace is used.
3956+
2. `import * from <source>`. Every task, workflow, and user-defined type from `<source>` enters the importing document's scope. No namespace is introduced.
3957+
3. `import { <member> [as <Name>], ... } from <source>`. Only the listed items enter the importing document's scope. A per-member `as <Name>` renames the selected item locally. A trailing comma after the last member is permitted. No namespace is introduced.
39653958

3966-
`from` is only valid with symbolic imports. A `from` clause used with a quoted URI import is a syntax error.
3959+
Forms 2 and 3 do not accept a trailing `as <alias>` or `alias` clause.
39673960

3968-
A `<member>` in form 3 may resolve to any top-level item exposed by the module's entrypoint: a namespace (the name under which the entrypoint imported a file), a task, a workflow, a struct, or an enum. Dotted paths reach deeper into nested namespaces.
3961+
A `<source>` is either a quoted URI or an unquoted symbolic module path. A quoted URI (e.g., `"foo.wdl"`, `"https://example.com/lib.wdl"`) resolves per [Import URIs](#import-uris). A symbolic module path takes the form `<dep>[/<sub-path>]` and resolves through the consuming module's `module.json` per the [WDL Module Specification](modules/SPEC.md). The two source styles produce identical scoping in every form; once resolved, they are interchangeable.
39693962

3970-
Examples:
3963+
When two imports both bring an item `baz` into scope, the importing document must rename one of them. Form 1 uses an `alias` clause; form 3 uses the per-member `as`:
39713964

39723965
```wdl
3973-
version 1.4
3974-
3975-
import openwdl/csvkit # csvkit.sort.CsvSort
3976-
import openwdl/csvkit as csv # csv.sort.CsvSort
3977-
import * from openwdl/csvkit # sort.CsvSort
3978-
import * from openwdl/csvkit as csv # csv.sort.CsvSort (same as form 1 with alias)
3979-
import { sort } from openwdl/csvkit # sort.CsvSort
3980-
import { sort as sorter } from openwdl/csvkit # sorter.CsvSort
3981-
import { sort.CsvSort } from openwdl/csvkit # call CsvSort
3982-
import { sort.CsvSort as MySort, sort.CsvSortStable } from openwdl/csvkit # call MySort, call CsvSortStable
3983-
import { sort.CsvSort, sort.CsvSortStable } from openwdl/csvkit as csv # call csv.CsvSort, call csv.CsvSortStable
3966+
import "foo.wdl" alias baz as foo_baz
3967+
import { baz as bar_baz } from "bar.wdl"
39843968
```
39853969

3986-
### ✨ Scoping Rules for Symbolic Imports
3987-
3988-
Symbolic imports namespace all member types **symmetrically**. Tasks, workflows, structs, and enums accessed through a symbolic import are all reached through the same namespace path; no member type is copied into the consuming document's global scope.
3989-
3990-
This is distinct from quoted URI imports, which copy struct and enum definitions into the importing document's global scope (see [Importing and Aliasing Structs](#importing-and-aliasing-structs) and [Importing and Aliasing Enums](#importing-and-aliasing-enums)). Symbolic imports do not carry that behavior.
3991-
3992-
Given:
3970+
Examples:
39933971

39943972
```wdl
3995-
import openwdl/csvkit as csv
3996-
```
3997-
3998-
If `csv`'s entrypoint imports `sort.wdl` and `sort.wdl` defines a struct `CsvSortResult`, the struct is accessed as `csv.sort.CsvSortResult`. It is not available unqualified in the importing document.
3999-
4000-
The worst-case qualification depth is three: `<alias>.<namespace>.<member>`. This bound is fixed regardless of how deep the module's own import tree is, because WDL namespaces are not transitively visible—consumers see only what the module's entrypoint directly exposes.
3973+
version 1.4
40013974
4002-
The `alias` clause described in [Importing and Aliasing Structs](#importing-and-aliasing-structs) is specific to quoted URI imports and is not used with symbolic imports. To rename a member of a symbolic import, use the `as` forms defined above.
3975+
import "csvkit.wdl" # csvkit.CsvSort, struct types in scope
3976+
import "csvkit.wdl" as csv # csv.CsvSort, struct types in scope
3977+
import * from "csvkit.wdl" # CsvSort directly in scope
3978+
import { CsvSort } from "csvkit.wdl" # CsvSort directly in scope
3979+
import { CsvSort as MySort, CsvSortStable } from "csvkit.wdl" # MySort and CsvSortStable in scope
3980+
import openwdl/csvkit # symbolic source, same semantics as form 1
3981+
import { CsvSort } from openwdl/csvkit # symbolic source, same semantics as form 3
3982+
```
40033983

40043984
### Importing and Aliasing Structs
40053985

0 commit comments

Comments
 (0)