From 6da825344c4fc1a31d1a6d85a8892941ae2faec0 Mon Sep 17 00:00:00 2001 From: Michael Toy <66150587+mtoy-googly-moogly@users.noreply.github.com> Date: Mon, 25 May 2026 16:38:35 -0700 Subject: [PATCH] Document the export { ... } statement Updates the Imports page (renamed Imports and Exports) with an Exports section covering: opt-in semantics, syntax mirroring selective import, additive statements, re-exporting imports, and the order-dependent / no-rename / no-star rules. Pairs with malloydata/malloy#2837. --- src/documentation/language/imports.malloynb | 57 ++++++++++++++++++++- src/table_of_contents.json | 2 +- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/src/documentation/language/imports.malloynb b/src/documentation/language/imports.malloynb index e1cd710c..de273b2e 100644 --- a/src/documentation/language/imports.malloynb +++ b/src/documentation/language/imports.malloynb @@ -1,5 +1,5 @@ >>>markdown -# Imports +# Imports and Exports In order to reuse or extend a source from another file, you can include all the exported sources from another file using `import "path/to/some/file.malloy"`. @@ -31,4 +31,57 @@ The default is to import all objects from the referenced file. You can also use import { airports, spaceports is airports } from "airports.malloy" run: airports -> { aggregate: airport_count is count() } -run: spaceports -> { aggregate: spaceport_count is count() } \ No newline at end of file +run: spaceports -> { aggregate: spaceport_count is count() } +>>>markdown + +## Exports + +By default, every `source:`, `query:`, `given:`, and `type:` declared in a file is exported — that is, visible to anyone who imports the file. If you'd rather keep some definitions local (for example, helper sources used only as scaffolding for the things you actually publish), add an `export { ... }` statement listing only the names you want to expose: + +```malloy +source: raw_flights is duckdb.table('flights.parquet') + +source: flights is raw_flights extend { + measure: flight_count is count() +} + +export { flights } +``` + +After this, `flights` is exported but `raw_flights` is not. `raw_flights` is still usable inside the file — only its visibility from other files is affected. + +The syntax intentionally mirrors selective import: + +```malloy +import { flights } from "flights.malloy" +export { flights } +``` + +`export` is opt-in. A file with no `export` statement behaves exactly as before: everything declared is exported. + +Multiple `export` statements add together: + +```malloy +source: a is duckdb.table('a.parquet') +export { a } + +source: b is duckdb.table('b.parquet') +export { b } +// exports are now { a, b } +``` + +You can re-export an imported name. This is the natural way to build a curated library on top of another: + +```malloy +import { customers is raw_customers } from "raw.malloy" +source: orders is duckdb.table('orders.parquet') + +export { customers, orders } +``` + +### Rules + +- An `export` statement must appear after the definition of each name it lists. Forward references are an error. +- Only sources, queries, givens, and user types can be exported. Connections cannot. +- There is no rename on export — rename at the definition site if you need a different public name. +- There is no `export *`. The way to "export everything" is to leave the `export` statement out entirely. \ No newline at end of file diff --git a/src/table_of_contents.json b/src/table_of_contents.json index ffe9c621..ed34ed92 100644 --- a/src/table_of_contents.json +++ b/src/table_of_contents.json @@ -192,7 +192,7 @@ "link": "/language/sql_sources.malloynb" }, { - "title": "Imports", + "title": "Imports and Exports", "link": "/language/imports.malloynb" }, {