Home Explore Blog CI



nushell

lang-guide/chapters/types/other_types/block.md
1ac4036ff63c469d2bd8d839752cc93441e9ca09c42731040000000300000e81
# Block

|                       |                                                                       |
| --------------------- | --------------------------------------------------------------------- |
| **_Description:_**    | A syntactic form used by some Nushell keywords (e.g., `if` and `for`) |
| **_Annotation:_**     | N/A                                                                   |
| **_Literal Syntax:_** | N/A                                                                   |
| **_Casts:_**          | N/A                                                                   |
| **_See also:_**       | [Types of Data - Blocks](/book/types_of_data.md#blocks)               |

## Additional Language Notes

Unlike closures, blocks:

- Don't close over variables
- Don't have parameters
- Can't be passed as a value
- **Can** access mutable variable in the parent scope.

  Example - Mutate a variable inside the block used in an [`if`](/commands/docs/if.md) call

  ```nu
  mut x = 1
  if true {
      $x += 1000
  }
  print $x
  ```

  Result:

  ```nu
  1001
  ```

## Language Notes

- A block consists of any Nushell code enclosed in curly braces: `{`, `}` **in certain specific Nushell constructs.** In other cases code enclosed between braces is a closure.

- A block is not a data type like a closure and cannot be used to type a variable, custom command parameter, its input type, or its return type. You will get a type error if you try this.

  ```nu
  let b: block = {}
  Error:   × Blocks are not support as first-class values
    ╭─[entry #9:1:8]
  1 │ let p: block = {}
    ·        ──┬──
    ·          ╰── blocks are not supported as values
    ╰────
    help: Use 'closure' instead of 'block'
  ```

- A closure that takes no parameters may look like a block but is actually a closure. For example:

  ```nu
  > { echo foo } | describe
  closure
  # Alternatively
  > {|| echo foo } | describe
  closure
  ```

- A block establishes a new variable scope. Variables defined within the new scope having the same name as a variable in an outer scope will alias (a.k.a. shadow) that name for the lifetime of that block's scope. Example:

  ```nu
  # Outer scope:
  let x: int = 9
  if true {
    # inner scope
    let x: string = '8'
    $x | describe
    # => string
  }
  echo $x
  # => 9
  ```

## Mutable variables in blocks

Unlike closures, mutable variables are exposed within the inner scope of the block and can be modified. Once modified, the mutable variable is changed to the value to which it was set in the scope of the block.

E.g.

```nu
# This won't work
mut x = 9
do { $x += 1 }
# => Error: Capture of mutable variable.
# But this will work:
if true { $x += 1 }
# => 10
```

Note: Aliasing still occurs within the block:

```nu
mut x = 9
if true { mut x = 8; $x += 100; echo $x }
# => 108
echo $x
# => 9
```

::: important
For both the if/else and try expressions, the value of the last expression in the block for whichever clause is executed is returned. This is not true
for any of the looping constructs. If you try to assign the result of calling a for or while loop the type of the result will always be `nothing`.

To capture the result of a loop, you can define a mutable variable before the loop and mutate it inside the body of the loop. However, the more idiomatic Nushell way to do it is with a command like `each` which takes a closure. The last expression evaluated in the closure is returned and available to further items in the pipeline.
:::

## Common commands that can be used with a `block`

- `if`/`else`
- `loop`
- `while`
- `for`
- `try`
  - But not the body of the catch clause which is always a closure

Chunks
605dd4e1 (1st chunk of `lang-guide/chapters/types/other_types/block.md`)
Title: Nushell Blocks: Definition, Usage, and Characteristics
Summary
This section defines Nushell blocks, a syntactic form used by keywords like `if` and `for`. Unlike closures, blocks don't close over variables, don't have parameters, and can't be passed as values, but they can access and modify mutable variables in the parent scope. Blocks are not a data type and establish a new variable scope where variables can be aliased. Mutable variables are exposed and modifiable within blocks, and the last expression in the block for `if`/`else` and `try` expressions is returned. Common commands that can be used with blocks include `if`, `loop`, `while`, `for`, and `try`.