Home Explore Blog CI



nushell

3rd chunk of `book/how_nushell_code_gets_run.md`
33f9991e633299504db02cc3bb1fa4fefeb695915a295f7c0000000100000ffa
We'll dig deeper into what it means in the next section.

## Implications

Consider this Python example:

```python:line-numbers
exec("def hello(): print('Hello eval!')")
hello()
```

::: note
We're using `exec` in this example instead of `eval` because it can execute any valid Python code rather than being limited to `eval` expressions. The principle is similar in both cases, though.
:::

During interpretation:

1. The entire program is Parsed
2. In order to Evaluate Line 1:
   1. `def hello(): print('Hello eval!')` is Parsed
   2. `def hello(): print('Hello eval!')` is Evaluated
3. (Line 2) `hello()` is evaluated.

Note, that until step 2.2, the interpreter has no idea that a function `hello` even exists! This makes [static analysis](https://en.wikipedia.org/wiki/Static_program_analysis) of dynamic languages challenging. In this example, the existence of the `hello` function cannot be checked just by parsing (compiling) the source code. The interpreter must evaluate (run) the code to discover it.

- In a static, compiled language, a missing function is guaranteed to be caught at compile-time.
- In a dynamic, interpreted language, however, it becomes a _possible_ runtime error. If the `eval`-defined function is conditionally called, the error may not be discovered until that condition is met in production.

::: important
In Nushell, there are **exactly two steps**:

1. Parse the entire source code
2. Evaluate the entire source code

This is the complete Parse/Eval sequence.
:::

::: tip Takeaway
By not allowing `eval`-like functionality, Nushell prevents these types of `eval`-related bugs. Calling a non-existent definition is guaranteed to be caught at parse-time in Nushell.

Furthermore, after parsing completes, we can be certain the bytecode (IR) won't change during evaluation. This gives us a deep insight into the resulting bytecode (IR), allowing for powerful and reliable static analysis and IDE integration which can be challenging to achieve with more dynamic languages.

In general, you have more peace of mind that errors will be caught earlier when scaling Nushell programs.
:::

## The Nushell REPL

As with most any shell, Nushell has a _"Read→Eval→Print Loop"_ ([REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop)) that is started when you run `nu` without any file. This is often thought of, but isn't quite the same, as the _"commandline"_.

::: tip Note
In this section, the `> ` character at the beginning of a line in a code-block is used to represent the commandline **_prompt_**. For instance:

```nu
> some code...
```

Code after the prompt in the following examples is executed by pressing the <kbd>Enter</kbd> key. For example:

```nu
> print "Hello world!"
# => Hello world!

> ls
# => prints files and directories...
```

The above means:

- From inside Nushell (launched with `nu`):
  1. Type `print "Hello world!"`
  1. Press <kbd>Enter</kbd>
  1. Nushell will display the result
  1. Type `ls`
  1. Press <kbd>Enter</kbd>
  1. Nushell will display the result

:::

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.

Title: Implications of No Eval and Nushell REPL
Summary
This section discusses the implications of Nushell's lack of an `eval` function, highlighting how it prevents certain types of runtime errors common in dynamic languages and allows for reliable static analysis. It contrasts this with dynamic languages like Python, where missing functions may only be discovered at runtime. The section then explains the Read-Eval-Print Loop (REPL) in Nushell, detailing the steps involved in processing each commandline input and merging the environment to maintain continuity.