Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs/tour/expressions: simplicity and tone edit
See previous commit for context. Page-specific notes: * operators: - point to other docs for integer division and operator precedence * interpolation: - include multi-line string example for completeness * dynamic-fields (renamed from interpolfield): - align page title and path with spec ("dynamic fields") - include pointer to explanation of how generated fields can be referenced - amend example to demonstrate references to dynamic fields * conditional: - remove "single field" limitation - remove evaluation failure prediction; allow cue error message to explain it - polish example; use multiple files for the first time, which required explanation * listcomp: - expand example to show off single-/multi-line, let declarations, and nesting * fieldcomp: - reference other pages so prose doesn't need to be repeated - replace and expand example * query-projection: [new page] - demonstrate querying and projecting data using comprehensions * regexp: - give more hints as to what "unary" means, for the less CompSci-aware reader - self-explanatory example definition names - link to pkg/regexp and RE2 for reference * coalesce: - incorporate jba's in-page feedback - make example clearer For cue-lang/docs-and-content#78 Preview-Path: /docs/tour/expressions/operators/ Preview-Path: /docs/tour/expressions/interpolation/ Preview-Path: /docs/tour/expressions/interpolfield/ Preview-Path: /docs/tour/expressions/conditional/ Preview-Path: /docs/tour/expressions/listcomp/ Preview-Path: /docs/tour/expressions/fieldcomp/ Preview-Path: /docs/tour/expressions/query-projection/ Preview-Path: /docs/tour/expressions/regexp/ Preview-Path: /docs/tour/expressions/coalesce/ Signed-off-by: Jonathan Matthews <github@hello.jonathanmatthews.com> Change-Id: I065af2bb41cfe7ca4534cfafc625ac3bdf17a412 Reviewed-on: https://review.gerrithub.io/c/cue-lang/cuelang.org/+/1177830 Reviewed-by: Paul Jolly <paul@myitcv.io> TryBot-Result: CUEcueckoo <cueckoo@gmail.com>
- Loading branch information
1 parent
501f81c
commit 4eb5826
Showing
32 changed files
with
726 additions
and
347 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,44 +1,40 @@ | ||
--- | ||
title: "Null Coalescing" | ||
title: Null Coalescing | ||
weight: 80 | ||
--- | ||
|
||
<!-- jba: the terms here are confusing. "Null coalescing" is actually not | ||
that, but then there is something called "actual null coalescing." | ||
Just say that because _|_ | X evaluates to X, you can use disjunction | ||
to represent fallback values. | ||
And then you can use that to effectively type-check with a default value. | ||
--> | ||
**Null coalescing** is a technique that allows your CUE to evaluate successfully, | ||
despite data having invalid, unexpected, or missing values. | ||
By "null coalescing", we really mean error (or bottom) coalescing. | ||
|
||
With null coalescing we really mean error, or bottom, coalescing. | ||
The defaults mechanism for disjunctions can also be | ||
used to provide fallback values in case an expression evaluates to bottom. | ||
It uses a disjunction's default marker (`*`) to prefer the value of an | ||
expression that *might* evaluate to bottom (`_|_`), | ||
alongside an alternative, fallback value that the disjunction will select if | ||
the expression *does* produce bottom. | ||
This isn't a separate language feature, but is the expected outcome from CUE's | ||
design that `_|_ | value` evaluates to `value`. | ||
|
||
In the example the fallback values are specified | ||
for `a` and `b` in case the list index is out of bounds. | ||
This technique can guard against situations such as list indexes being out of | ||
bounds, and type checks, with a fallback in the case of a type mismatch. | ||
|
||
To do actual null coalescing one can unify a result with the desired type | ||
to force an error. | ||
In that case the default will be used if either the lookup fails or | ||
the result is not of the desired type. | ||
{{{with code "en" "tour"}}} | ||
exec cue eval -c file.cue | ||
cmp stdout out | ||
-- file.cue -- | ||
#pets: ["Cat", "Mouse", "Dog"] | ||
|
||
{{{with code "en" "coalesce"}}} | ||
exec cue eval coalesce.cue | ||
cmp stdout result.txt | ||
-- coalesce.cue -- | ||
list: ["Cat", "Mouse", "Dog"] | ||
// Guard against out of bounds list indexes. | ||
pet0: *#pets[0] | "Pet not found" | ||
pet5: *#pets[5] | "Pet not found" | ||
|
||
a: *list[0] | "None" | ||
b: *list[5] | "None" | ||
#nums: [7, "8", "9"] | ||
|
||
n: [null] | ||
v: *(n[0] & string) | "default" | ||
-- result.txt -- | ||
list: ["Cat", "Mouse", "Dog"] | ||
a: "Cat" | ||
b: "None" | ||
n: [null] | ||
v: "default" | ||
// Perform a type check. | ||
num0: *(#nums[0] & int) | "Not an integer" | ||
num1: *(#nums[1] & int) | "Not an integer" | ||
-- out -- | ||
pet0: "Cat" | ||
pet5: "Pet not found" | ||
num0: 7 | ||
num1: "Not an integer" | ||
{{{end}}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,34 @@ | ||
--- | ||
title: "Conditional Fields" | ||
weight: 60 | ||
title: Conditional Fields | ||
weight: 40 | ||
--- | ||
|
||
Field comprehensions can also be used to | ||
add a single field conditionally. | ||
Field comprehensions can be used to add fields conditionally. | ||
|
||
Converting the resulting configuration to JSON results in an error | ||
as `justification` is required yet no concrete value is given. | ||
{{< info >}} | ||
When `cue export` processes multiple files it *unifies* their contents. | ||
The value of the `price` field in `stock.yaml` is available inside `file.cue`, | ||
and triggers the conditional inclusion of the required fields. | ||
{{< /info >}} | ||
|
||
{{{with code "en" "conditional"}}} | ||
exec cue eval conditional.cue | ||
cmp stdout result.txt | ||
-- conditional.cue -- | ||
{{{with code "en" "tour"}}} | ||
! exec cue export file.cue stock.yaml | ||
cmp stderr out | ||
-- file.cue -- | ||
price: number | ||
|
||
// Require a justification if price is too high | ||
// High prices require a reason and the name of | ||
// the authorising person. | ||
if price > 100 { | ||
justification: string | ||
reason!: string | ||
authorisedBy!: string | ||
} | ||
|
||
-- stock.yaml -- | ||
price: 200 | ||
-- result.txt -- | ||
justification: string | ||
price: 200 | ||
-- out -- | ||
authorisedBy: field is required but not present: | ||
./file.cue:5:1 | ||
reason: field is required but not present: | ||
./file.cue:5:1 | ||
{{{end}}} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
--- | ||
title: Dynamic Fields | ||
weight: 30 | ||
aliases: | ||
- interpolfield | ||
--- | ||
|
||
A **dynamic field** is a field whose name, or *label*, is determined by | ||
an expression wrapped in parentheses | ||
or through string interpolation: | ||
`(a + b)` or `"\(a + b)"`. | ||
|
||
A dynamic field's identifier is not available in the scope in which the field is defined.\ | ||
Referencing dynamic fields needs to be done using | ||
[selectors, index expressions]({{< relref "docs/tour/references/selectors" >}}), | ||
or [aliases]({{< relref "docs/tour/references/aliases" >}}). | ||
|
||
{{{with code "en" "tour"}}} | ||
exec cue eval file.cue | ||
cmp stdout out | ||
-- file.cue -- | ||
a: "foo" | ||
b: "bar" | ||
(a + b): "foobar" | ||
|
||
s: X={ | ||
"\(a)_and_\(b)": "foobar" | ||
|
||
// Valid references using a selector and | ||
// an index expression. | ||
FooAndBar: s.foo_and_bar | ||
FooAndBar: X["foo_and_bar"] | ||
|
||
// Invalid reference because the | ||
// indentifer is not in scope. | ||
//FooAndBar: foo_and_bar | ||
} | ||
|
||
// Valid reference using an index expression. | ||
FooAndBar: s["foo_and_bar"] | ||
-- out -- | ||
a: "foo" | ||
b: "bar" | ||
s: { | ||
foo_and_bar: "foobar" | ||
FooAndBar: "foobar" | ||
} | ||
foobar: "foobar" | ||
FooAndBar: "foobar" | ||
{{{end}}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package site | ||
|
||
content: docs: tour: expressions: "dynamic-fields": page: _ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,42 +1,73 @@ | ||
--- | ||
title: "Field Comprehensions" | ||
weight: 50 | ||
title: Field Comprehensions | ||
weight: 60 | ||
--- | ||
|
||
CUE also supports comprehensions for fields. | ||
Fields can be specified using **field comprehensions**. | ||
|
||
One cannot refer to generated fields with references. | ||
Instead, one must use indexing. | ||
Just like | ||
[list comprehensions]({{< relref "listcomp" >}}), they use | ||
`for` loops, `if` guards, and `let` declarations, | ||
combined in any order. | ||
|
||
{{{with code "en" "fieldcomp"}}} | ||
exec cue eval -c fieldcomp.cue | ||
cmp stdout result.txt | ||
-- fieldcomp.cue -- | ||
Because field comprehensions specify | ||
[dynamic fields]({{< relref "dynamic-fields" >}}), | ||
these fields can't be referenced directly | ||
and need to be accessed using | ||
[selectors, index expressions]({{< relref "docs/tour/references/selectors" >}}), | ||
or [aliases]({{< relref "docs/tour/references/aliases" >}}). | ||
|
||
{{{with code "en" "tour"}}} | ||
exec cue eval -c file.cue | ||
cmp stdout out | ||
-- file.cue -- | ||
import "strings" | ||
|
||
#a: ["Barcelona", "Shanghai", "Munich"] | ||
#censusData: [ | ||
{name: "Kinshasa", pop: 16_315_534}, | ||
{name: "Lagos", pop: 15_300_000}, | ||
{name: "Cairo", pop: 10_100_166}, | ||
{name: "Giza", pop: 9_250_791}, | ||
] | ||
|
||
for k, v in #a { | ||
"\( strings.ToLower(v) )": { | ||
pos: k + 1 | ||
name: v | ||
nameLen: len(v) | ||
// city maps from a city's name to its details. | ||
city: { | ||
for index, value in #censusData | ||
let lower = strings.ToLower(value.name) { | ||
"\(lower)": { | ||
population: value.pop | ||
name: value.name | ||
position: index + 1 | ||
} | ||
} | ||
} | ||
-- result.txt -- | ||
barcelona: { | ||
pos: 1 | ||
name: "Barcelona" | ||
nameLen: 9 | ||
} | ||
shanghai: { | ||
pos: 2 | ||
name: "Shanghai" | ||
nameLen: 8 | ||
} | ||
munich: { | ||
pos: 3 | ||
name: "Munich" | ||
nameLen: 6 | ||
|
||
// References via selector and index expression. | ||
gizaPopulation: city.giza.population | ||
cairoPopulation: city["cairo"].population | ||
-- out -- | ||
city: { | ||
kinshasa: { | ||
population: 16315534 | ||
name: "Kinshasa" | ||
position: 1 | ||
} | ||
lagos: { | ||
population: 15300000 | ||
name: "Lagos" | ||
position: 2 | ||
} | ||
cairo: { | ||
population: 10100166 | ||
name: "Cairo" | ||
position: 3 | ||
} | ||
giza: { | ||
population: 9250791 | ||
name: "Giza" | ||
position: 4 | ||
} | ||
} | ||
gizaPopulation: 9250791 | ||
cairoPopulation: 10100166 | ||
{{{end}}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,36 @@ | ||
--- | ||
title: "Interpolation" | ||
title: Interpolation | ||
weight: 20 | ||
--- | ||
|
||
String and bytes literals support interpolation. | ||
String and bytes literals support **interpolation**, | ||
in both their single- and multi-line forms. | ||
|
||
Any valid CUE expression may be used inside the escaped parentheses. | ||
Interpolation may also be used in multiline string and byte literals. | ||
Any valid CUE expression may be used inside escaped parentheses. | ||
|
||
{{{with code "en" "interpolation"}}} | ||
exec cue eval interpolation.cue | ||
cmp stdout result.txt | ||
-- interpolation.cue -- | ||
"You are \( #cost-#budget ) dollars over budget!" | ||
{{{with code "en" "tour"}}} | ||
exec cue export file.cue --out yaml | ||
cmp stdout out | ||
-- file.cue -- | ||
m: "You are \(#cost-#budget) dollars over budget!" | ||
email: """ | ||
Here is a message from the finance team: | ||
|
||
\(m) | ||
|
||
Regards, | ||
Your friends on the 12th floor | ||
""" | ||
|
||
#cost: 102 | ||
#budget: 88 | ||
-- result.txt -- | ||
"You are 14 dollars over budget!" | ||
#cost: 102 | ||
#budget: 88 | ||
-- out -- | ||
m: You are 14 dollars over budget! | ||
email: |- | ||
Here is a message from the finance team: | ||
|
||
You are 14 dollars over budget! | ||
|
||
Regards, | ||
Your friends on the 12th floor | ||
{{{end}}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.