Home Explore Blog CI



nushell

3rd chunk of `book/thinking_in_nu.md`
14ea96f44661bd9cf92172f9400e4883715672714fd32d920000000100000ff0
These can be likely sources of issues in your code.
:::

## Every Command Returns a Value

Some languages have the concept of "statements" which don't return values. Nushell does not.

In Nushell, **_every command returns a value_**, even if that value is `null` (the `nothing` type). Consider the following multiline expression:

```nu:line-numbers
let p = 7
print $p
$p * 6
```

1. Line 1: The integer 7 is assigned to `$p`, but the return value of the
   [`let` command](/commands/docs/let.md) itself is `null`. However, because it is not the last
   value in the expression, it is not displayed.
2. Line 2: The return value of the `print` command itself is `null`, but the `print` command
   forces its argument (`$p`, which is 7) to be _displayed_. As with Line 1, the `null` return value
   is discarded since this isn't the last value in the expression.
3. Line 3: Evaluates to the integer value 42. As the last value in the expression, this is the return
   result, and is also displayed (rendered).

::: warning Thinking in Nushell
Becoming familiar with the output types of common commands will help you understand how
to combine simple commands together to achieve complex results.

`help <command>` will show the signature, including the output type(s), for each command in Nushell.
:::

## Think of Nushell as a Compiled Language

In Nushell, there are exactly two, separate, high-level stages when running code:

1. _Stage 1 (Parser):_ Parse the **_entire_** source code
2. _Stage 2 (Engine):_ Evaluate the **_entire_** source code

It can be useful to think of Nushell's parsing stage as _compilation_ in [static](./how_nushell_code_gets_run.md#dynamic-vs-static-languages) languages like Rust or C++. By this, we mean that all of the code that will be evaluated in Stage 2 must be **_known and available_** during the parsing stage.

::: important
However, this also means that Nushell cannot currently support an `eval` construct as with _dynamic_ languages such as Bash or Python.
:::

### Features Built on Static Parsing

On the other hand, the **_static_** results of Parsing are key to many features of Nushell its REPL, such as:

- Accurate and expressive error messages
- Semantic analysis for earlier and robust detection of error conditions
- IDE integration
- The type system
- The module system
- Completions
- Custom command argument parsing
- Syntax highlighting
- Real-time error highlighting
- Profiling and debugging commands
- (Future) Formatting
- (Future) Saving IR (Intermediate Representation) "compiled" results for faster execution

### Limitations

The static nature of Nushell often leads to confusion for users coming to Nushell from languages where an `eval` is available.

Consider a simple two-line file:

```text
<line1 code>
<line2 code>
```

1. Parsing:
   1. Line 1 is parsed
   2. Line 2 is parsed
2. If parsing was successful, then Evaluation:
   1. Line 1 is evaluated
   2. Line 2 is evaluated

This helps demonstrate why the following examples cannot run as a single expression (e.g., a script) in Nushell:

::: note
The following examples use the [`source` command](/commands/docs/source.md), but similar conclusions apply to other commands that parse Nushell source code, such as [`use`](/commands/docs/use.md), [`overlay use`](/commands/docs/overlay_use.md), [`hide`](/commands/docs/hide.md) or [`source-env`](/commands/docs/source-env.md).

:::

#### Example: Dynamically Generating Source

Consider this scenario:

```nu
"print Hello" | save output.nu
source output.nu
# => Error: nu::parser::sourced_file_not_found
# =>
# =>   × File not found
# =>    ╭─[entry #5:2:8]
# =>  1 │ "print Hello" | save output.nu
# =>  2 │ source output.nu
# =>    ·        ────┬────
# =>    ·            ╰── File not found: output.nu
# =>    ╰────
# =>   help: sourced files need to be available before your script is run
```

This is problematic because:

1. Line 1 is parsed but not evaluated. In other words, `output.nu` is not created during the parsing stage, but only during evaluation.

Title: Nushell as a Compiled Language: Static Parsing and Limitations
Summary
This section explains Nushell's two-stage execution process: parsing and evaluation. It likens parsing to compilation in static languages, emphasizing the need for all code to be known during parsing. This static nature, while beneficial for error detection, IDE integration, and the type system, prevents the use of `eval`. The section illustrates limitations with an example where dynamically generated source code cannot be immediately sourced because the file is not created until the evaluation stage, after parsing is complete.