Home Explore Blog CI



nushell

3rd chunk of `book/variables.md`
62b23b0991b1b7220b31b6001e41ec71490fb83bbf9581ac0000000100000eab
For instance, loop counters are a common pattern for mutable variables and are built into most iterating commands. For example, you can get both each item and the index of each item using [`each`](/commands/docs/each.md) with [`enumerate`](/commands/docs/enumerate.md):

```nu
ls | enumerate | each { |elt| $"Item #($elt.index) is size ($elt.item.size)" }
# => ╭───┬───────────────────────────╮
# => │ 0 │ Item #0 is size 812 B     │
# => │ 1 │ Item #1 is size 3.4 KiB   │
# => │ 2 │ Item #2 is size 11.0 KiB  │
# => │ 3 │ ...                       │
# => │ 4 │ Item #18 is size 17.8 KiB │
# => │ 5 │ Item #19 is size 482 B    │
# => │ 6 │ Item #20 is size 4.0 KiB  │
# => ╰───┴───────────────────────────╯
```

You can also use the [`reduce`](/commands/docs/reduce.md) command to work in the same way you might mutate a variable in a loop. For example, if you wanted to find the largest string in a list of strings, you might do:

```nu
[one, two, three, four, five, six] | reduce {|current_item, max|
  if ($current_item | str length) > ($max | str length) {
      $current_item
  } else {
      $max
  }
}

three
```

While `reduce` processes lists, the [`generate`](/commands/docs/generate.md) command can be used with arbitrary sources such as external REST APIs, also without requiring mutable variables. Here's an example that retrieves local weather data every hour and generates a continuous list from that data. The `each` command can be used to consume each new list item as it becomes available.

```nu
generate khot {|weather_station|
  let res = try {
    http get -ef $'https://api.weather.gov/stations/($weather_station)/observations/latest'
  } catch {
    null
  }
  sleep 1hr
  match $res {
    null => {
      next: $weather_station
    }
    _ => {
      out: ($res.body? | default '' | from json)
      next: $weather_station
    }
  }
}
| each {|weather_report|
    {
      time: ($weather_report.properties.timestamp | into datetime)
      temp: $weather_report.properties.temperature.value
    }
}
```

### Performance Considerations

Using [filter commands](/commands/categories/filters.html) with immutable variables is often far more performant than mutable variables with traditional flow-control statements such as `for` and `while`. For example:

- Using a `for` statement to create a list of 50,000 random numbers:

  ```nu
  timeit {
    mut randoms = []
    for _ in 1..50_000 {
      $randoms = ($randoms | append (random int))
    }
  }
  ```

  Result: 1min 4sec 191ms 135µs 90ns

- Using `each` to do the same:

  ```nu
  timeit {
    let randoms = (1..50_000 | each {random int})
  }
  ```

  Result: 19ms 314µs 205ns

- Using `each` with 10,000,000 iterations:

  ```nu
  timeit {
    let randoms = (1..10_000_000 | each {random int})
  }
  ```

  Result: 4sec 233ms 865µs 238ns

  As with many filters, the `each` statement also streams its results, meaning the next stage of the pipeline can continue processing without waiting for the results to be collected into a variable.

  For tasks which can be optimized by parallelization, as mentioned above, `par-each` can have even more drastic performance gains.

## Variable Names

Variable names in Nushell come with a few restrictions as to what characters they can contain. In particular, they cannot contain these characters:

```text
.  [  (  {  +  -  *  ^  /  =  !  <  >  &  |
```

It is common for some scripts to declare variables that start with `$`. This is allowed, and it is equivalent to the `$` not being there at all.

```nu
let $var = 42
# identical to `let var = 42`
```

Title: Functional Alternatives to Mutable Variables and Performance Considerations in Nushell
Summary
Nushell offers functional alternatives to mutable variables, such as using `each` with `enumerate` for indexed iteration and `reduce` for accumulating values. The `generate` command enables creating continuous lists from arbitrary sources like REST APIs without mutation. Filter commands and immutable variables often outperform mutable variables in terms of performance. Variable names in Nushell cannot contain specific special characters, and starting a variable name with `$` is equivalent to omitting it.