DOCS: Update the documentation with module out expressions.

issue #35
This commit is contained in:
Jeremy Wall 2019-02-21 19:54:04 -06:00
parent 34b47fa70d
commit 4b34296923
2 changed files with 39 additions and 15 deletions

View File

@ -516,14 +516,16 @@ the statements later. Modules are an expression. They can be bound to a value
and then reused later. Modules do not close over their environment but they can and then reused later. Modules do not close over their environment but they can
import other UCG files into the module using import statements including the import other UCG files into the module using import statements including the
file they are located themselves. This works since the statements in a module file they are located themselves. This works since the statements in a module
until you attempt to call the module with a copy expression. are not evaluated until you attempt to call the module with a copy expression.
Module expressions start with the module keyword followed by a tuple Module expressions start with the module keyword followed by a tuple
representing their parameters with any associated default values. The body of representing their parameters with any associated default values. The body of
the module is separated from the parameter tuple by the `=>` symbol and is the module is separated from the parameter tuple by the `=>` symbol an optional
delimited by `{` and `}` respectively. `(expr)` defining the out expression, and a series of statements delimited by
`{` and `}` respectively. The body of the module can contain any valid UCG
The body of the module can contain any valid UCG statement. statement. You instantiate a module via the copy expression. By default if
there is no out expression then the module will export all of the named
bindings in the statements.
``` ```
let top_mod = module { let top_mod = module {
@ -539,20 +541,42 @@ let top_mod = module {
let embedded = embedded_def{deep_value = mod.deep_value}; let embedded = embedded_def{deep_value = mod.deep_value};
}; };
```
You instantiate a module via the copy expression. The resulting module instance let embedded_with_params = top_mod{deep_value = "Some"};
can reference the bindings in the module similarly to selecting a tuple field
or a binding from an imported file.
``` // By default all of the named bindings in a module are exported so we can
let embedded_default_params = top_mod{}; // get the embedded tuple out via a selector.
embedded_default_params.embedded.value == "None";
let embedded_with_params = embedded_mod{deep_value = "Some"};
embedded_with_params.embedded.value == "Some"; embedded_with_params.embedded.value == "Some";
``` ```
### Out Expressions
If there is an out expression then the module will only export the result of
that expression. The out expression is computed after the last statement in the
module has been evaluated.
```
let top_mod_out_expr = module {
deep_value = "None",
} => (embedded) { // we will only expose the embedded binding in our module
let shared_funcs = import "shared.UCG";
let embedded_def = module {
deep_value = "None",
} => {
let value = mod.deep_value;
};
let embedded = embedded_def{deep_value = mod.deep_value};
};
let embedded_default_params = top_mod_out_expr{};
// We don't have to dereference the embedded binding since the out expression
// exported it for us.
embedded_default_params.value == "None";
```
### Recursive Modules ### Recursive Modules
One consequence of a module being able to import the same file they are located in One consequence of a module being able to import the same file they are located in

View File

@ -119,7 +119,7 @@ func_def: func_keyword, lparen, [ arglist ], rparen, fatcomma, tuple ;
#### Module Definition #### Module Definition
``` ```
module_def: module_keyword, tuple, fatcomma, lbrace, [ { statement } ], rbrace ; module_def: module_keyword, tuple, fatcomma, [lparen, expr, rparen], lbrace, [ { statement } ], rbrace ;
``` ```
#### Copy and Call Expression #### Copy and Call Expression