Nushell
Get Nu!
Getting Started
  • The Nushell Book
  • Command Reference
  • Cookbook
  • Language Reference Guide
  • Contributing Guide
Blog
  • English
  • 中文
  • Deutsch
  • Français
  • Español
  • 日本語
  • Português do Brasil
  • Русский язык
GitHub
Get Nu!
Getting Started
  • The Nushell Book
  • Command Reference
  • Cookbook
  • Language Reference Guide
  • Contributing Guide
Blog
  • English
  • 中文
  • Deutsch
  • Français
  • Español
  • 日本語
  • Português do Brasil
  • Русский язык
GitHub
  • Language Reference Guide
    • Readme
    • Types in the Nu Language
      • Basic Types
        • Any
        • Boolean
        • Integer
        • Float
        • Filesize
        • Duration
        • Datetime
        • Range
        • String
        • Record
        • List
        • Table
        • Closure
        • Nothing
        • Binary
        • Glob
        • Cell-Path
      • Other Data Types

        • Types that cannot be used to declare variables
          • Path
        • Types which are not declarable
          • Error
          • CustomValue
          • Block
      • Type signatures
      • Commands that interact with types
    • Operators
    • Flow control
      • if/else
      • loop
      • while
      • match
      • try/catch
      • break
      • return
      • continue
    • Filters
      • each and par-each
      • Filters to select subsets of data
      • where and filter
      • Understanding the difference between get and select
    • Custom Commands
    • Declarations
    • Variable Scope
    • Strings and Text Formatting
    • Helpers and debugging commands
    • Pipelines
    • MIME Types for Nushell

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

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 call

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

    Result:

    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.

    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:

    > { 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:

    # 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.

# 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:

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
Edit this page on GitHub
Contributors: NotTheDr01ds, fdncred
Prev
CustomValue