Vertical Layout
Do supports YAML-like vertical layout for arguments and data structures. This provides a natural way to format complex commands or function calls, or even define small declarative languages. Vertical layout is started by placing an indented block in the following contexts:
- In the middle of a command (but not
if/whileconditions, orfor/bindscrutinees; in these contexts, indentation is reserved for the body of the statement form) - After a
$at statement level
Dash Items
A line in vertical layout may start with a leading -, in which case it's
considered a positional argument which spans the remainder of the line.
Key Items
A line may instead start with a leading key, in which case it's considered a key argument which spans the remainder of the line.
Bin-packing
A line starting with neither a dash item nor a key item may contain additional positional arguments separated horizontally according to the usual rules. Key arguments can't be bin-packed in vertical layout; place these on the first line of a command or otherwise one per line.
# Horizontal
func arg1 arg2 key1: val1 key2: val2
# Vertical
func
arg1
arg2
key1: val1
key2: val2
# Mixed
func arg1 key1: val1
arg2
key2: val2
# Bin packed
func
arg1 arg2
arg3 arg4
# Not allowed
#func
# key1: val1 key2: val2
Vertical Data
$ followed by indentation introduces an array or dictionary:
# Vertical array
let items = $
- 1
- 2
- 3
# A vertical dictionary will result if at least one key is present
return $
host: localhost
port: 8080
# Vertical dictionary with implicit integer keys
let config = $
name: Bob
- false # integer key 0
- 42 # integer key 1
# Nested
let data = $
name: Example Student
scores:
- 95
- 87
- 92
address:
city: Anytown
zip: "00000"
# As an argument (a single array argument, instead of 3 string arguments)
echo $
- a
- b
- c
A dictionary results if any keys are present; otherwise, an array is constructed.
In a vertical context, further indentation will introduce an array or
dictionary as an argument without $:
my_func
# Positional argument: 2-item dictionary
- name: Bob
age: 45
# Key argument: 3-element array
some_key:
- 1
- a string
- false
# Key argument: 2-item dictionary
dict:
x: 12
y: 34
Line Items
Items that span the line (after - or key:) are treated like ordinary
command arguments, except that whitespace is preserved literally instead being
a separator. There is also a special form: $ followed by a space interprets
the remainder of the line as a full command statement, with the value being its
result.
for in Vertical Layout
Within vertical layout, for generates variadic items or arguments
if in Vertical Layout
if introduces conditional items or arguments in vertical layout:
let items = $
- always_here
if include_extra
- extra_item
- also_always_here
let foo = $
if true
- 1
- 2
assert_eq $foo [1, 2]
let bar = $
if false
- 1
- 2
assert_eq $bar []
Spreading
Use ... to spread in vertical layout. It must not be preceded by -.
The behavior of the spread depends on the context:
| Context | Spread input | Behavior |
|---|---|---|
| Arguments | Iterable | Positional arguments |
| Arguments | Dict-like object or kv() iterator |
Mixed arguments. Monotonic integer keys starting from 0 are positional, symbol keys are keys |
| Array | Iterable | Expanded as individual items in place |
| Dictionary | Iterable | Items assigned incrementing integer keys |
| Dictionary | Dict-like object or kv() iterator |
Key/value pairs, preserving ordering and multiplicity |
Note that a dictionary is only produced if at least one static key exists in addition to any spreads; otherwise, an array results.