Nushell has a spread operator (`...`) for unpacking lists and records. You may be familiar with it
if you've used JavaScript before. Some languages use `*` for their spread/splat operator. It can
expand lists or records in places where multiple values or key-value pairs are expected.
There are three places you can use the spread operator:
- [In list literals](#in-list-literals)
- [In record literals](#in-record-literals)
- [In command calls](#in-command-calls)
### In List literals
Suppose you have multiple lists you want to concatenate together, but you also want to intersperse
some individual values. This can be done with `append` and `prepend`, but the spread
operator can let you do it more easily.
```nu
let dogs = [Spot, Teddy, Tommy]
let cats = ["Mr. Humphrey Montgomery", Kitten]
[
...$dogs
Polly
...($cats | each { |elt| $"($elt) \(cat\)" })
...[Porky Bessie]
...Nemo
]
# => ╭───┬───────────────────────────────╮
# => │ 0 │ Spot │
# => │ 1 │ Teddy │
# => │ 2 │ Tommy │
# => │ 3 │ Polly │
# => │ 4 │ Mr. Humphrey Montgomery (cat) │
# => │ 5 │ Kitten (cat) │
# => │ 6 │ Porky │
# => │ 7 │ Bessie │
# => │ 8 │ ...Nemo │
# => ╰───┴───────────────────────────────╯
```
The below code is an equivalent version using `append`:
```nu
$dogs |
append Polly |
append ($cats | each { |elt| $"($elt) \(cat\)" }) |
append [Porky Bessie] |
append ...Nemo
```
Note that each call to `append` results in the creation of a new list, meaning that in this second
example, 3 unnecessary intermediate lists are created. This is not the case with the spread operator,
so there may be (very minor) performance benefits to using `...` if you're joining lots of large
lists together, over and over.
You may have noticed that the last item of the resulting list above is `"...Nemo"`. This is because
inside list literals, it can only be used to spread lists, not strings. As such, inside list literals, it can
only be used before variables (`...$foo`), subexpressions (`...(foo)`), and list literals (`...[foo]`).
The `...` also won't be recognized as the spread operator if there's any whitespace between it and
the next expression:
```nu
[ ... [] ]
# => ╭───┬────────────────╮
# => │ 0 │ ... │
# => │ 1 │ [list 0 items] │
# => ╰───┴────────────────╯
```
This is mainly so that `...` won't be confused for the spread operator in commands such as `mv ... $dir`.
### In Record literals
Let's say you have a record with some configuration information and you want to add more fields to
this record:
```nu
let config = { path: /tmp, limit: 5 }
```
You can make a new record with all the fields of `$config` and some new additions using the spread
operator. You can use the spread multiple records inside a single record literal.