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) - Immediately after
=in aletor assignment statement, or immediately afterreturn(constructs an array or dictionary)
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 arg3
# Not allowed
#func
# key1: val1 key2: val2
Vertical Data
In non-argument contexts, vertical layout defines 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"
A dictionary results if any keys are present; otherwise, an array is constructed.
In a vertical argument context, further indentation will introduce an array or dictionary as an argument:
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: the remainder of the line is treated 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 introduced 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 an iterable in vertical context. It must not be preceded by
-.
The behavior of the spread depends on the context:
- Arguments:
- An ordinary iterable is spread as positional arguments
- An iterable yielding key/value pairs is spread as arguments, with integer keys starting from 0 and increasing contiguously treated as positional argument and symbol keys treated as key arguments; all others cause a runtime error
- Array (no static keys specified in vertical layout)
- An iterable is expanded as individual items in place
- Dictionary (at least one static key specified in vertical layout)
- An ordinary iterable is spread as incrementing integer keys
- An iterable yielding key/value pairs is spread as such, preserving ordering and multiplicity