Skip to content

Commit

Permalink
docs/tour/types: simplicity and tone edit
Browse files Browse the repository at this point in the history
See previous commit for context.

Page-specific notes:

* types:
  - change plaintext hierarchy diagram to mermaid
    - include top and bottom
  - explain "cue eval" as we've avoided it until now
* bottom:
  - change values in the example so they pop more visibly
  - explain what the example is showing
* top: [new page]
* numbers:
  - move some prose into the example's comments
  - mention number type
  - align tour with spec: `4` is *not* compatible with `float`.
  - add examples of float-related sugar
  - move mention of arbitrary precision into here, from
    docs/tour/types/bounddef/
* stringlit:
  - rename to mirror "Bytes"
  - remove comparison to JSON as it feels out of place
  - include interpolation in the example
* stringraw:
  - expand example to show comparative versions of the same string with
    different delimiters
* bytes:
  - plain text table changed to markdown
  - include mention of how to emit a stringified byte array to help
    avoid newcomer frustration
  - example expanded to include the same string being output as a string
    and as bytes' base64, to show the behaviour more clearly
  - include string interpolation of bytes to demo "how to display some
    bytes that you know aren't binary data, as a string"
  - include multiple examples of both hex and octal escapes, and
    demonstrate their equivalence via unification
* structs:
  - renamed from /optional; alias added
  - moved ahead of closed and defs to permit for a more natural flow
    through learning struct concepts
  - example is changed from a definition to a regular field, as this
    page now precedes definitions' page.
  - updated so it's suitable to accept inbound links that
    previously targeted the language guide
* closed:
  - updated so it's suitable to accept inbound links that
    previously targeted the language guide
* defs:
  - updated to be a 90% copy of docs/tour/basics/definitions/, as that
    content is already written. Examples differ.
* disjunctions:
  - revise awkward wording of first sentence, as it's really jarring
    until the 3rd or 4th read through
  - stop explaining the example via the prose; use cue-eval-i instead to
    demonstrate evaluation failure
  - expand example's disjunction to include 4 values, so as to demo the
    syntax beyond just 2 elements
* defaults:
  - add explanation of why defaults exist, what CUE does with a default,
    and when
  - reuse "options" language from preceding page
  - make example abstract
    - include a 3-way disjunction so it's not implied that the default
      has to unify with the non-default
* sumstruct:
  - show CUE in action in the example
* bounds:
  - more narrative example, including a multi-constraint field
  - removed the sentence "The bound is defined for all values for which
    the corresponding comparison operation is defined", as it feels a
    little too technical for the tour
* bounddef:
  - move mention of arbitrary precision to docs/tour/types/numbers/
  - reword "no unsigned integer type" more positively
  - use cue vet for examples
  - make all examples fail
* lists:
  - expand explanation
  - change example to be more narrative, with less prose required for
    explanation
  - begin the examples with common, concrete use cases, so users can get
    what they need from this longer set of eamples more easily, whilst
    still demonstrating important syntactic detail nearer the end
  - include sufficient distinct examples so that the various syntaxes
    implied by the prose have concrete visualisations
  - include examples of two failure modes that can confuse newcomers
* templates:
  - mention pattern constraints
  - expand example to include a disjunction-based pattern constraint,
    and use top for field instantiation where possible
  - opened cue-lang/cue#2916
* value-constraints: [new page]
  - left as draft (i.e. not published) following feedback and awaiting
    later updates

For cue-lang/docs-and-content#78

Preview-Path: /docs/tour/types/types/
Preview-Path: /docs/tour/types/bottom/
Preview-Path: /docs/tour/types/top/
Preview-Path: /docs/tour/types/bounddef/
Preview-Path: /docs/tour/types/bounds/
Preview-Path: /docs/tour/types/bytes/
Preview-Path: /docs/tour/types/defaults/
Preview-Path: /docs/tour/types/structs/
Preview-Path: /docs/tour/types/closed/
Preview-Path: /docs/tour/types/defs/
Preview-Path: /docs/tour/types/disjunctions/
Preview-Path: /docs/tour/types/numbers/
Preview-Path: /docs/tour/types/lists/
Preview-Path: /docs/tour/types/stringlit/
Preview-Path: /docs/tour/types/stringraw/
Preview-Path: /docs/tour/types/sumstruct/
Preview-Path: /docs/tour/types/templates/
Signed-off-by: Jonathan Matthews <github@hello.jonathanmatthews.com>
Change-Id: Id4870cb92903bfcb7662fb236a7da2ace15a24c5
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cuelang.org/+/1177673
TryBot-Result: CUEcueckoo <cueckoo@gmail.com>
Reviewed-by: Paul Jolly <paul@myitcv.io>
  • Loading branch information
jpluscplusm committed Mar 19, 2024
1 parent 1583abe commit 7bc69d0
Show file tree
Hide file tree
Showing 68 changed files with 1,539 additions and 847 deletions.
2 changes: 1 addition & 1 deletion content/docs/howto/mark-a-field-as-optional/en.md
Expand Up @@ -62,7 +62,7 @@ s1:
## Related content

- [**Optional field constraints**]({{< relref
"docs/tour/types/optional"
"docs/tour/types/structs"
>}})
- [**Commented CUE guides**]({{< relref
"docs/howto#commented-cue-guides"
Expand Down
2 changes: 1 addition & 1 deletion content/docs/howto/mark-a-field-as-required/en.md
Expand Up @@ -49,5 +49,5 @@ s1:
## Related content

- [**Required field constraints**]({{< relref
"docs/tour/types/optional"
"docs/tour/types/structs"
>}})
Expand Up @@ -292,7 +292,7 @@ overriding values.
"docs/tour/types/disjunctions"
>}})
- [**Field constraints**]({{< relref
"docs/tour/types/optional"
"docs/tour/types/structs"
>}})
<!-- TODO:postLG
- [**Value constraints**]({{</* relref
Expand Down
11 changes: 7 additions & 4 deletions content/docs/reference/glossary/en.md
Expand Up @@ -90,12 +90,13 @@ toc_hide: false

## Field
🔗 <!-- TODO:postLG [Language Guide](\{\{\< relref "docs/language-guide/data/maps-and-fields" >}}) -->
[Tour]({{< relref "docs/tour/basics/json-superset" >}})
[Tour]({{< relref "docs/tour/types/structs" >}})
- A key-value pair inside a map, associating a value with a given set of keys

## Field constraint
🔗 <!-- TODO:postLG [Language Guide](\{\{\< relref "docs/language-guide/schemas-and-validation/field-constraints" >}}) -->
[Language Spec]({{< relref "docs/reference/spec#field-constraints" >}})
| [Tour]({{< relref "docs/tour/types/structs" >}})
- A field constraint restricts a [field]({{< relref "#field" >}})'s value
without actually defining the field, with the field only forming part of the
output if it is successfully [unified]({{< relref "#unification" >}}) with a
Expand Down Expand Up @@ -196,7 +197,8 @@ toc_hide: false

## Optional field constraint
🔗 <!-- TODO:postLG [Language Guide](\{\{\< relref "docs/language-guide/schemas-and-validation/field-constraints#optional-field-constraints" >}}) -->
[Howto Guide]({{< relref "docs/howto/mark-a-field-as-optional" >}})
[Tour]({{< relref "docs/tour/types/structs" >}})
| [Howto Guide]({{< relref "docs/howto/mark-a-field-as-optional" >}})
- A [field constraint]({{< relref "#field-constraint" >}}) that restricts the
[field]({{< relref "#field" >}})'s value if the field is present, whilst also
permitting the field's absence
Expand Down Expand Up @@ -244,7 +246,8 @@ toc_hide: false

## Required field constraint
🔗 <!-- TODO:postLG [Language Guide](\{\{\< relref "docs/language-guide/schemas-and-validation/field-constraints#required-field-constraints" >}}) -->
[Howto Guide]({{< relref "docs/howto/mark-a-field-as-required" >}})
[Tour]({{< relref "docs/tour/types/structs" >}})
| [Howto Guide]({{< relref "docs/howto/mark-a-field-as-required" >}})
- A [field constraint]({{< relref "#field-constraint" >}}) that restricts the
[field]({{< relref "#field" >}})'s value whilst also requiring the field to
be present
Expand All @@ -264,7 +267,7 @@ toc_hide: false
## Struct {#struct-type}
🔗 <!-- TODO:postLG [Language Guide](\{\{\< relref "docs/language-guide/data/maps-and-fields" >}}) -->
[Language Spec]({{< relref "docs/reference/spec#structs" >}})
| [Tour]({{< relref "docs/tour/types/optional" >}})
| [Tour]({{< relref "docs/tour/types/structs" >}})
<!-- Link to this section? [Language Spec]({{< relref "docs/reference/spec#values-1" >}}) -->
- A composite type representing a set of elements (called
[fields]({{< relref "#field" >}})) each of which has a name (called a label)
Expand Down
63 changes: 34 additions & 29 deletions content/docs/tour/types/bottom/en.md
@@ -1,35 +1,40 @@
---
title: "Bottom / Error"
title: Bottom / Error
weight: 20
---

Specifying duplicate fields with conflicting values results in an error
or bottom.
_Bottom_ is a special value in CUE, denoted `_|_`, that indicates an
error such as conflicting values.
Any error in CUE results in `_|_`.
Logically all errors are equal, although errors may be associated with
metadata such as an error message.

Note that an error is different from `null`: `null` is a valid value,
whereas `_|_` is not.

{{{with code "en" "bottom"}}}
exec cue eval -i bottom.cue
cmp stdout result.txt
-- bottom.cue --
a: 4
a: 5

l: [1, 2]
l: [1, 3]

list: [0, 1, 2]
val: list[3]
-- result.txt --
a: _|_ // a: conflicting values 5 and 4
l: [1, _|_, // l.1: conflicting values 3 and 2
Specifying a field multiple times with conflicting values results in an error,
or **bottom**, written `_|_`.

Bottom is a special value in CUE, and is the value that results from any error.
Logically, all errors are equal,
although CUE may associate them with metadata such as an error message.

An error is *not* the same as the value `null`.
`_|_` isn't a valid value for a field, but `null` is.

{{{with code "en" "tour"}}}
exec cue eval -i file.cue
cmp stdout out
-- file.cue --
a: 1
a: 2

b: [50, 100]
b: [50, 200]

c: [0, 1, 2]

d: c[5]
-- out --
a: _|_ // a: conflicting values 2 and 1
b: [50, _|_, // b.1: conflicting values 200 and 100
]
list: [0, 1, 2]
val: _|_ // val: index out of range [3] with length 3
c: [0, 1, 2]
d: _|_ // d: invalid list index 5 (out of bounds)
{{{end}}}

Notice how the `-i` flag changes how `cue eval` behaves.
It causes errors to be represented as literal error values in the output, with
error messages as inline comments.
These literal `_|_` values *invalidate* the CUE that's output.
2 changes: 1 addition & 1 deletion content/docs/tour/types/bottom/gen_cache.cue
Expand Up @@ -8,7 +8,7 @@ package site
page: {
cache: {
code: {
bottom: "xDESv1/aDzbs80lFToPEbGLCnPdNwnXi70tb3/Rb6nM="
tour: "r3NzzXohlz7lHyktuTwMoknzqf42wX/hHlzX5zOL3Oc="
}
}
}
Expand Down
65 changes: 32 additions & 33 deletions content/docs/tour/types/bounddef/en.md
@@ -1,44 +1,43 @@
---
title: "Predefined Bounds"
title: Predefined Bounds
weight: 140
---

CUE numbers have arbitrary precision.
Also there is no unsigned integer type.

CUE defines the following predefined identifiers to restrict the bounds of
integers to common values.
integers to common values.\
The `u`-prefixed identifiers provide similar capabilities to unsigned integer
types in other languages.

{{{with code "en" "defined"}}}
-- defined.cue --
uint: >=0
uint8: >=0 & <=255
int8: >=-128 & <=127
uint16: >=0 & <=65536
int16: >=-32_768 & <=32_767
rune: >=0 & <=0x10FFFF
uint32: >=0 & <=4_294_967_296
int32: >=-2_147_483_648 & <=2_147_483_647
uint64: >=0 & <=18_446_744_073_709_551_615
int64: >=-9_223_372_036_854_775_808 & <=9_223_372_036_854_775_807
int128: >=-170_141_183_460_469_231_731_687_303_715_884_105_728 &
<=170_141_183_460_469_231_731_687_303_715_884_105_727
{{{with code "en" "identifiers"}}}
-- file.cue --
uint: >=0
uint8: >=0 & <=255
int8: >=-128 & <=127
uint16: >=0 & <=65536
int16: >=-32_768 & <=32_767
rune: >=0 & <=0x10FFFF
uint32: >=0 & <=4_294_967_296
int32: >=-2_147_483_648 & <=2_147_483_647
uint64: >=0 & <=18_446_744_073_709_551_615
int64: >=-9_223_372_036_854_775_808 & <=9_223_372_036_854_775_807
int128: >=-170_141_183_460_469_231_731_687_303_715_884_105_728 & <=170_141_183_460_469_231_731_687_303_715_884_105_727
uint128: >=0 & <=340_282_366_920_938_463_463_374_607_431_768_211_455
{{{end}}}

{{{with code "en" "failure"}}}
exec cue eval -ic bound.cue
cmp stdout result.txt
-- bound.cue --
#positive: uint
#byte: uint8
#word: int32
{{{with code "en" "tour"}}}
! exec cue vet file.cue
cmp stderr out
-- file.cue --
import "math"

a: #positive & -1
b: #byte & 128
c: #word & 2_000_000_000
-- result.txt --
a: _|_ // a: invalid value -1 (out of bound >=0)
b: 128
c: 2000000000
a: uint & -1
b: uint8 & 256
c: int32 & math.Pow(2, 31) // 2^31
-- out --
a: invalid value -1 (out of bound >=0):
./file.cue:3:11
b: invalid value 256 (out of bound <=255):
./file.cue:4:12
c: invalid value 2147483648 (out of bound <=2147483647):
./file.cue:5:12
{{{end}}}
4 changes: 2 additions & 2 deletions content/docs/tour/types/bounddef/gen_cache.cue
Expand Up @@ -8,8 +8,8 @@ package site
page: {
cache: {
code: {
defined: "bEFnv9bjxjzKTq3OC9F0YLlhWa6J2f3wFKwgGJWRz9s="
failure: "YqVxaqlxEnVJUDCerFFjaW+I+7YUkOlw+OQVRj+MhbY="
identifiers: "k92q7Ohf0I/nyPcRCbuFcW348CXrk2nuBzD6GfBasJ0="
tour: "7Xm6l8kkMeSF9hyxKMAdwA/UbpS3nsNMgLE6vkfA3EM="
}
}
}
Expand Down
76 changes: 41 additions & 35 deletions content/docs/tour/types/bounds/en.md
@@ -1,40 +1,46 @@
---
title: "Bounds"
title: Bounds
weight: 130
---

Bounds define a lower bound, upper bound, or inequality for a certain value.
They work on numbers, strings, bytes and null.

The bound is defined for all values for which the corresponding comparison
operation is defined.
For instance `>5.0` allows all floating point values greater than `5.0`,
whereas `<0` allows all negative numbers (int or float).


{{{with code "en" "failure"}}}
exec cue eval -ic bounds.cue
cmp stdout result.txt
-- bounds.cue --
#rn: >=3 & <8 // type int | float

#ri: >=3 & <8 & int // type int

#rf: >=3 & <=8.0 // type float
#rs: >="a" & <"mo"

a: #rn & 3.5
b: #ri & 3.5
c: #rf & 3
d: #rs & "ma"
e: #rs & "mu"

r1: #rn & >=5 & <10
-- result.txt --
a: 3.5
b: _|_ // b: conflicting values int and 3.5 (mismatched types int and float)
c: 3
d: "ma"
e: _|_ // e: invalid value "mu" (out of bound <"mo")
r1: >=5 & <8
**Bounds** define
a lower bound, an upper bound, or inequality for a certain value,
all of which can be combined.
They work on numbers, strings, bytes, and `null`.

A bound is expressed using comparison operators such as `>`, `<=`, and `!=`.
It permits values where the comparison would return `true`,
and we say that *the bound is defined* for these values.

{{{with code "en" "tour"}}}
#nofmt https://github.com/cue-lang/cue/issues/2913

exec cue eval -ic file.cue
cmp stdout out
-- file.cue --
#floatOver5: >5.0 // type: float
#negativeNum: <0 // type: int | float
#afterL: >"L" // type: string
#notNull: !=null // type: any except null

zero: 0 & >10 // failure
float10: 10.0 & #floatOver5
float5: 5.0 & #floatOver5 // failure
"num-6": -6 & #negativeNum
A: "A" & #afterL // failure
Z: "Z" & #afterL
isNull: null & #notNull // failure
isNotNull: "X" & #notNull

float425: 42.5 & #notNull & <100 & #floatOver5
-- out --
zero: _|_ // zero: invalid value 0 (out of bound >10)
float10: 10.0
float5: _|_ // float5: invalid value 5.0 (out of bound >5.0)
"num-6": -6
A: _|_ // A: invalid value "A" (out of bound >"L")
Z: "Z"
isNull: _|_ // isNull: conflicting values null and !=null (mismatched types null and (bool|string|bytes|func|list|struct|number))
isNotNull: "X"
float425: 42.5
{{{end}}}
2 changes: 1 addition & 1 deletion content/docs/tour/types/bounds/gen_cache.cue
Expand Up @@ -8,7 +8,7 @@ package site
page: {
cache: {
code: {
failure: "cXLCZRWhKqSdUiML4qy1kt+hosx9cLWcFbK3zQJC+X0="
tour: "q70Rot4mkt5mlBXrCxd+x1ePVkDvoYwaBoodWPxZ/90="
}
}
}
Expand Down
49 changes: 32 additions & 17 deletions content/docs/tour/types/bytes/en.md
@@ -1,27 +1,42 @@
---
title: "Bytes"
title: Bytes
weight: 60
---

CUE distinguishes between a `string` and a `bytes` type.
Bytes are converted to base64 when emitting JSON.
CUE distinguishes the **`bytes`** type from the `string` type.
Byte literals are defined with single quotes.
The following additional escape sequences are allowed in byte literals:

{{{with code "en" "escapes"}}}
-- plain.txt --
\xnn // arbitrary byte value defined as a 2-digit hexadecimal number
\nnn // arbitrary byte value defined as a 3-digit octal number
{{{end}}}
<!-- jba: this contradicts the spec, which has \nnn (no leading zero) -->
In addition to the escape sequences permitted in string literals,
byte literals also allow these escape sequences:

{{< table >}}
| Sequence | Result |
| ---:| --- |
| **`\xnn`** | Arbitrary byte value defined as the 2-digit hexadecimal number "**`nn`**" |
| **`\nnn`** | Arbitrary byte value defined as the 3-digit octal number "**`nnn`**" |
{{< /table >}}

Bytes are represented as Base64 when exporting concrete data to a format such as JSON or YAML.\
To avoid this, interpolate bytes inside a string value.

{{{with code "en" "tour"}}}
exec cue export file.cue
cmp stdout out
-- file.cue --
aString: "A string"

// Multiple representations of the same underlying
// bytes, which therefore unify succesfully.
Bytes: 'A string'
Bytes: '\(aString)'
Bytes: '\x41\x20\x73\x74\x72\x69\x6e\x67'
Bytes: '\101\040\163\164\162\151\156\147'

{{{with code "en" "bytes"}}}
exec cue export bytes.cue
cmp stdout result.txt
-- bytes.cue --
a: '\x03abc'
-- result.txt --
stringBytes: "\(Bytes)"
-- out --
{
"a": "A2FiYw=="
"aString": "A string",
"Bytes": "QSBzdHJpbmc=",
"stringBytes": "A string"
}
{{{end}}}
3 changes: 1 addition & 2 deletions content/docs/tour/types/bytes/gen_cache.cue
Expand Up @@ -8,8 +8,7 @@ package site
page: {
cache: {
code: {
escapes: "G/941KuFjnDmgViGNIha5BQSXKBhVqouUV28JFifsBw="
bytes: "vfSrwgLl1z5I+8gpp6FxKxfFHlUstjiVnlgnGAlaiT4="
tour: "BTc81SOLy1sTMGWdlEsgJL+XU/JKOIKl4SiwgWtIPLE="
}
}
}
Expand Down

0 comments on commit 7bc69d0

Please sign in to comment.