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.