Home Explore Blog CI



nushell

4th chunk of `book/how_nushell_code_gets_run.md`
2c55f85094a18b6d519209d4f511e14569d136bc6e0d7da10000000100000f25
When you press <kbd>Enter</kbd> after typing a commandline, Nushell:

1. **_(Read):_** Reads the commandline input
1. **_(Evaluate):_** Parses the commandline input
1. **_(Evaluate):_** Evaluates the commandline input
1. **_(Evaluate):_** Merges the environment (such as the current working directory) to the internal Nushell state
1. **_(Print):_** Displays the results (if non-`null`)
1. **_(Loop):_** Waits for another input

In other words, each REPL invocation is its own separate parse-evaluation sequence. By merging the environment back to the Nushell's state, we maintain continuity between the REPL invocations.

Compare a simplified version of the [`cd` example](./thinking_in_nu.md#example-change-to-a-different-directory-cd-and-source-a-file) from _"Thinking in Nu"_:

```nu
cd spam
source-env foo.nu
```

There we saw that this cannot work (as a script or other single expression) because the directory will be changed _after_ the parse-time [`source-env` keyword](/commands/docs/source-env.md) attempts to read the file.

Running these commands as separate REPL entries, however, works:

```nu
> cd spam
> source-env foo.nu
# Yay, works!
```

To see why, let's break down what happens in the example:

1. Read the `cd spam` commandline.
2. Parse the `cd spam` commandline.
3. Evaluate the `cd spam` commandline.
4. Merge environment (including the current directory) into the Nushell state.
5. Read and Parse `source-env foo.nu`.
6. Evaluate `source-env foo.nu`.
7. Merge environment (including any changes from `foo.nu`) into the Nushell state.

When `source-env` tries to open `foo.nu` during the parsing in Step 5, it can do so because the directory change from Step 3 was merged into the Nushell state during Step 4. As a result, it's visible in the following Parse/Eval cycles.

### Multiline REPL Commandlines

Keep in mind that this only works for **_separate_** commandlines.

In Nushell, it's possible to group multiple commands into one commandline using:

- A semicolon:

  ```nu
  cd spam; source-env foo.nu
  ```

- A newline:

  ```
  > cd span
    source-env foo.nu
  ```

  Notice there is no "prompt" before the second line. This type of multiline commandline is usually created with a [keybinding](./line_editor.md#keybindings) to insert a Newline when <kbd>Alt</kbd>+<kbd>Enter</kbd> or <kbd>Shift</kbd>+ <kbd>Enter</kbd> is pressed.

These two examples behave exactly the same in the Nushell REPL. The entire commandline (both statements) are processed a single Read→Eval→Print Loop. As such, they will fail the same way that the earlier script-example did.

::: tip
Multiline commandlines are very useful in Nushell, but watch out for any out-of-order Parser-keywords.
:::

## Parse-time Constant Evaluation

While it is impossible to add parsing into the evaluation stage and yet still maintain our static-language benefits, we can safely add _a little bit_ of evaluation into parsing.

::: tip Terminology
In the text below, we use the term _"constant"_ to refer to:

- A `const` definition
- The result of any command that outputs a constant value when provide constant inputs.
  :::

By their nature, **_constants_** and constant values are known at Parse-time. This, of course, is in sharp contrast to _variable_ declarations and values.

As a result, we can utilize constants as safe, known arguments to parse-time keywords like [`source`](/commands/docs/source.md), [`use`](/commands/docs/use.md), and related commands.

Consider [this example](./thinking_in_nu.md#example-dynamically-creating-a-filename-to-be-sourced) from _"Thinking in Nu"_:

```nu
let my_path = "~/nushell-files"
source $"($my_path)/common.nu"
```

As noted there, we **_can_**, however, do the following instead:

```nu:line-numbers
const my_path = "~/nushell-files"
source $"($my_path)/common.nu"
```

Let's analyze the Parse/Eval process for this version:

Title: Nushell REPL Details, Multiline Commands, and Parse-time Constant Evaluation
Summary
This section delves into the specifics of the Nushell REPL, explaining how commands are processed in separate parse-evaluation sequences, maintaining continuity through environment merging. It contrasts single-expression scripts with REPL commands, highlighting the differences in execution order, particularly regarding the `cd` and `source-env` commands. The section then discusses multiline commandlines in the REPL and their limitations with out-of-order parser keywords. Finally, it introduces the concept of parse-time constant evaluation, emphasizing how constants can be safely used as arguments for parse-time keywords like `source` and `use`.