Skip to content

Commit 7babd31

Browse files
committed
Add description of compound type signatures
list, record and table type signatures were mentioned in several places, but never discussed in detail. The recently added oneof type declaration wasn't documented anywhere (except in the blog post introducing nu 0.105.0, where it was added). Add sections for list, record, table and oneof compound types to the Language Reference Guide. Add a link to the relevant reference page in the "Custom Commands"/"Parameters"/"Parameter Types" section of the book.
1 parent c6ba1a2 commit 7babd31

File tree

2 files changed

+144
-2
lines changed

2 files changed

+144
-2
lines changed

book/custom_commands.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ prev:
33
text: Programming in Nu
44
link: /book/programming_in_nu.md
55
---
6+
67
# Custom Commands
78

89
As with any programming language, you'll quickly want to save longer pipelines and expressions so that you can call them again easily when needed.
@@ -158,7 +159,7 @@ In this case, the final expression is the `match` statement which can return:
158159

159160
- `null` if the directory is empty
160161
- Otherwise, a `record` representing the randomly chosen file
161-
:::
162+
:::
162163

163164
## Custom Commands and Pipelines
164165

@@ -490,6 +491,9 @@ The following [types](./types_of_data.html) can be used for parameter annotation
490491
- `record`
491492
- `string`
492493
- `table`
494+
- `oneof`
495+
496+
See [Type signatures](/lang-guide/chapters/types/type_signatures.html) in the Language Reference Guide for more information.
493497

494498
:::
495499

lang-guide/chapters/types/type_signatures.md

Lines changed: 139 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,145 @@ There are 3 forms of valid type signatures in Nu:
4545
- Basic: E.g. `int`, `bool`, `string`, etc.
4646
- Compound:
4747
- `list<string>`,
48-
`record<type: int, bar: string>`
48+
`record<type: int, bar: string>`,
49+
`table<name: string, age: int>`
50+
- Sum types (aka type alternatives): E.g. `oneof<int, string>`
51+
52+
### List types
53+
54+
- `list<something>` - Read as `list of elements of type something`
55+
56+
For example, `list<int>` would specify a list of integers:
57+
58+
```nu
59+
def sum_two []: list<int> -> int { $in.0 + $in.1 }
60+
61+
[1 11 111 1111] | sum_two
62+
# => 12
63+
64+
["abc" "def" "ghi"] | sum_two
65+
# error: command doesn't support list<string> input
66+
```
67+
68+
- `list` - If no element type is specified, this is equivalent to `list<any>`.
69+
70+
```nu
71+
def second []: list -> any { $in.1 }
72+
73+
[1 11 111 1111] | second
74+
# => 11
75+
76+
["abc" "def" "ghi"] | second
77+
# => def
78+
```
79+
80+
### Record types
81+
82+
- `record<key_name: value_type>` - Read as `record containing a key key_name with value of type value_type`
83+
84+
```nu
85+
def greet [person: record<name: string>] {
86+
$"Hello, ($person.name)!"
87+
}
88+
89+
greet { name: Ellie }
90+
# => Hello, Ellie!
91+
92+
greet "Who"
93+
# error: a string is not a record
94+
95+
greet { given_name: Bob }
96+
# error: the record is missing a "name" key
97+
98+
greet { name: [] }
99+
# error: the record's "name" value can't be coerced to string
100+
101+
# The record may contain more keys besides the specified ones though:
102+
greet { name: Bob, age: 32 }
103+
# => Hello, Bob!
104+
```
105+
106+
We may also specify multiple keys that a record must posess as a comma separated `name: value_type` list. E.g.:
107+
108+
```nu
109+
def greet [person: record<name: string, birthday: datetime, job: string>] {
110+
print $"Hello, ($person.name) the ($person.job)!"
111+
if ($person.birthday | format date "%m-%d") == (date now | format date "%m-%d") {
112+
print "Happy birthday!"
113+
}
114+
}
115+
116+
greet { name: Bob, job: Builder, birthday: 1998-11-28 }
117+
# => Hello, Bob the Builder!
118+
```
119+
120+
Similar to lists, `record` or `record<>` specifies a record with any keys (or even an empty record):
121+
122+
```nu
123+
def first_key []: record -> string {
124+
columns | first
125+
}
126+
127+
{ name: Ellie } | first_key
128+
# => name
129+
130+
{ given_name: Bob } | first_key
131+
# => given_name
132+
133+
# this will pass type checking (but produce a runtime error)
134+
{} | first_key
135+
```
136+
137+
### Table types
138+
139+
- `table<column_name: value_type>` - Read as `table containing a column column_name with values of type value_type`
140+
141+
Tables are just lists of records, so table types work very similarly to record types:
142+
143+
```nu
144+
let data: table<date: datetime, temps: list<number>, condition: string> = [
145+
[date temps condition ];
146+
[2022-02-01T14:30:00+05:00, [38.24, 38.50, 37.99, 37.98, 39.10], 'sunny' ],
147+
[2022-02-02T14:30:00+05:00, [35.24, 35.94, 34.91, 35.24, 36.65], 'sunny' ],
148+
[2022-02-03T14:30:00+05:00, [35.17, 36.67, 34.42, 35.76, 36.52], 'cloudy' ],
149+
[2022-02-04T14:30:00+05:00, [39.24, 40.94, 39.21, 38.99, 38.80], 'rain' ]
150+
]
151+
152+
def temp_avg [] : table<date: datetime, temps: list<number>> -> table<date: datetime, avg_temp: number> {
153+
insert avg_temp {|record| $record.temps | math avg}
154+
| reject temps
155+
}
156+
157+
# Note that both the input and output table contain a column "condition", which
158+
# is not mentioned in the type signature of temp_avg. This is fine.
159+
$data | temp_avg
160+
# => ╭───┬─────────────┬───────────┬──────────╮
161+
# => │ # │ date │ condition │ avg_temp │
162+
# => ├───┼─────────────┼───────────┼──────────┤
163+
# => │ 0 │ 3 years ago │ sunny │ 38.36 │
164+
# => │ 1 │ 3 years ago │ sunny │ 35.60 │
165+
# => │ 2 │ 3 years ago │ cloudy │ 35.71 │
166+
# => │ 3 │ 3 years ago │ rain │ 39.44 │
167+
# => ╰───┴─────────────┴───────────┴──────────╯
168+
```
169+
170+
### Sum types
171+
172+
- `oneof<a, b, c>` - Read: one of `a`, `b` or `c`
173+
174+
Example:
175+
176+
```nu
177+
def foo [
178+
param: oneof<binary, string>
179+
] {
180+
if ($param | describe) == "binary" {
181+
$param | first 3
182+
} else {
183+
$param | str substring 0..<3
184+
}
185+
}
186+
```
49187

50188
## Custom command parameters and flags
51189

0 commit comments

Comments
 (0)