Skip to content

Commit 2f9380c

Browse files
committed
Updates
1 parent d64bcda commit 2f9380c

File tree

1 file changed

+43
-27
lines changed

1 file changed

+43
-27
lines changed

book/thinking_in_nu.md

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ The most common questions from new users typically fall into one of the followin
1010

1111
### It can sometimes look like Bash
1212

13-
Nushell is both a programming language and a shell. Because of this, it has its own way of working with files, directories, websites, and more. We've modeled this to work closely with what you may be familiar with other shells. Pipelines work by attaching two commands together, just like in other shells. For example, the following commandline works the same in both Bash and Nushell on Unix/Linux platforms:
13+
Nushell is both a programming language and a shell. Because of this, it has its own way of working with files, directories, websites, and more. You'll find that some features in Nushell work similar to those you're familiar with in other shells. For instance, pipelines work by combining two (or more) commands together, just like in other shells.
14+
15+
For example, the following commandline works the same in both Bash and Nushell on Unix/Linux platforms:
1416

1517
```nu
1618
curl -s https://api.github.com/repos/nushell/nushell/contributors | jq '.[].login'
@@ -20,7 +22,7 @@ curl -s https://api.github.com/repos/nushell/nushell/contributors | jq '.[].logi
2022
Nushell has many other similarities with Bash (and other shells) and many commands in common.
2123

2224
::: tip
23-
While the above commandline works, in Nushell there's no need to use the `curl` and `jq` commands for this, since Nushell has a built-in [`http get` command](/commands/docs/http_get.md) and handles JSON data natively. For example:
25+
While the above commandline works, in Nushell there's just no need to use the `curl` and `jq` commands for this, since Nushell has a built-in [`http get` command](/commands/docs/http_get.md) and handles JSON data natively. For example:
2426

2527
```nu
2628
http get https://api.github.com/repos/nushell/nushell/contributors | select login contributions
@@ -45,7 +47,7 @@ echo $?
4547
# => 1
4648
```
4749

48-
In Nushell, however, the `>` is used as the greater-than operator for comparison. This is more in line with modern programming expectations.
50+
In Nushell, however, the `>` is used as the greater-than operator for comparisons. This is more in line with modern programming expectations.
4951

5052
```nu
5153
4 > 10
@@ -74,29 +76,31 @@ echo "Hello, World"
7476
# => Hello, World
7577
```
7678

77-
But while the other shells are sending the argument straight to _standard output_, Nushell's `echo` is
79+
But while the other shells are sending `Hello, World` straight to _standard output_, Nushell's `echo` is
7880
simply _returning a value_. Nushell then _renders_ the return value of a command, or more technically, an _expression_.
7981

8082
More importantly, Nushell _implicitly returns_ the value of an expression. This is similar to PowerShell or Rust in many respects.
8183

82-
And an expression can be more than just a pipeline. Even custom commands (similar to functions in many languages, but we'll cover them more in depth in a [later chapter](./custom_commands.md)) automatically, implicitly _return_ the last value. There's no need for an `echo` or even a [`return` command](/commands/docs/return.md) to return a value - It just _happens_.
84+
::: tip
85+
An expression can be more than just a pipeline. Even custom commands (similar to functions in many languages, but we'll cover them more in depth in a [later chapter](./custom_commands.md)) automatically, implicitly _return_ the last value. There's no need for an `echo` or even a [`return` command](/commands/docs/return.md) to return a value - It just _happens_.
86+
:::
8387

84-
In other words, the string _"Hello, World"_ and the return value from `echo "Hello, World"` are equivalent:
88+
In other words, the string _"Hello, World"_ and the output value from `echo "Hello, World"` are equivalent:
8589

8690
```nu
8791
"Hello, World" == (echo "Hello, World")
8892
# => true
8993
```
9094

91-
An example with a custom command definition:
95+
Here's another example with a custom command definition:
9296

9397
```nu
9498
def latest-file [] {
9599
ls | sort-by modified | last
96100
}
97101
```
98102

99-
The _result_ of that pipeline (its _"value"_) becomes the _return value_ of the `latest-file` custom command.
103+
The _output_ of that pipeline (its _"value"_) becomes the _return value_ of the `latest-file` custom command.
100104

101105
::: warning Thinking in Nushell
102106
Most anywhere you might write `echo <something>`, in Nushell, you can just write `<something>` instead.
@@ -122,14 +126,16 @@ New users might expect:
122126
- Line 2 to output _"Returning the last file"_
123127
- Line 3 to return/output the file
124128

125-
However, remember that `echo` **_returns a value_**. Since only the last value is return, the Line 2 _value_ is discarded. Only the file will be returned.
129+
However, remember that `echo` **_returns a value_**. Since only the last value is returned, the Line 2 _value_ is discarded. Only the file will be returned by line 3.
126130

127131
To make sure the first line is _displayed_, use the [`print` command](/commands/docs/print.md):
128132

133+
```nu
129134
def latest-file [] {
130135
print "Returning last file"
131136
ls | sort-by modified | last
132137
}
138+
```
133139

134140
Also compare:
135141

@@ -138,7 +144,7 @@ Also compare:
138144
```
139145

140146
::: tip
141-
A semicolon is the same as a newline in a Nushell expression. The above is the same as:
147+
A semicolon is the same as a newline in a Nushell expression. The above is the same as a file or multi-line command:
142148

143149
```nu
144150
40
@@ -195,8 +201,8 @@ $p * 6
195201
result, and is also displayed (rendered).
196202

197203
::: warning Thinking in Nushell
198-
Becoming familiar with the return values of common commands will help you understand how
199-
to combine simple commands to achieve complex results.
204+
Becoming familiar with the output types of common commands will help you understand how
205+
to combine simple commands together to achieve complex results.
200206

201207
`help <command>` will show the signature, including the output type(s), for each command in Nushell.
202208
:::
@@ -208,10 +214,10 @@ In most other shells, code is is only _evaluated_. In Nushell, code is:
208214
1. Stage 1: Parsed
209215
2. Stage 2: If the code parsed correctly, the result is then Evaluated
210216

211-
The Nushell Parser is key to many of Nushell's and the REPL features such as:
217+
The Nushell Parser is key to many features of Nushell and its REPL, such as:
212218

213219
- Accurate and expressive error messages
214-
- Earlier and robust detection of error conditions
220+
- Semantic analysis for earlier and robust detection of error conditions
215221
- IDE integration
216222
- The type system
217223
- The module system
@@ -223,9 +229,18 @@ The Nushell Parser is key to many of Nushell's and the REPL features such as:
223229
- (Future) Formatting
224230
- (Future) Saving IR (Intermediate Results) "compiled" results for faster execution
225231

226-
It may be useful to think of this parsing stage as _compilation_ in languages like Rust or C++. This means that all of the code that will evaluated in Stage 2 must be _known_ and available during the parsing stage. However, this also means that Nushell cannot currently support an `eval` construct as with many _dynamic_ languages such as Bash or Python.
232+
It may be useful to think of this parsing stage as _compilation_ in languages like Rust or C++. This means that all of the code that will be evaluated in Stage 2 must be **_known and available_** during the parsing stage. However, this also means that Nushell cannot currently support an `eval` construct as with many _dynamic_ languages such as Bash or Python.
227233

228-
For example, the following cannot run as a single expression (e.g., a script):
234+
Consider a simple two-line file:
235+
236+
1. Parsing:
237+
1. Line 1 is parsed
238+
2. Line 2 is parsed
239+
2. If parsing was successful, then Evaluation:
240+
1. Line 1 is evaluated
241+
2. Line 1 is evaluated
242+
243+
This helps demonstrate why the following cannot run as a single expression (e.g., a script):
229244

230245
```nu
231246
"print Hello" | save output.nu
@@ -244,16 +259,16 @@ source output.nu
244259

245260
This is problematic because:
246261

247-
1. Line 1 gets parsed but not evaluated. In other words, `output.nu` is not created during the parsing stage, but only during evaluation.
248-
2. Line 2 gets parsed, but `output.nu` is not available. This results in the error.
262+
1. Line 1 is parsed but not evaluated. In other words, `output.nu` is not created during the parsing stage, but only during evaluation.
263+
2. Line 2 is parsed. Because `source` is a parser-keyword, resolution of the sourced file is attempted during Parsing (Stage 1). But `output.nu` is not available! This results in the error.
249264

250265
::: note
251266
Typing these as two _separate_ lines in the **_REPL_** will work since the first line will be parsed and evaluated, then the second line will be parsed and evaluated.
252267

253268
The limitation only occurs when both are parsed _together_ as a single expression, which could be part of a script, block, closure, or other expression.
254269
:::
255270

256-
Another common scenario when coming from another shell might be trying to dynamically create a filename that will be sourced:
271+
Another common scenario when coming from another shell might be attempting to dynamically create a filename that will be sourced:
257272

258273
```nu
259274
let my_path = "~/nushell-files"
@@ -284,14 +299,14 @@ As noted in the error message, however, this can work if `my_path` can be define
284299
resolved during parsing.
285300

286301
```nu
287-
> const my_path = ([$nu.home-path nushell] | path join)
288-
> source $"($my_path)/common.nu" # sources /home/user/nushell/common.nu
302+
const my_path = ([$nu.home-path nushell] | path join)
303+
source $"($my_path)/common.nu" # sources /home/user/nushell/common.nu
289304
```
290305

291306
::: tip
292-
The output of many Nushell commands can be a constant value if all of the command's inputs are also constant.
307+
The output of many Nushell commands can be a constant value, as long as all of the command's inputs are also constant.
293308

294-
You can see which Nushell commands operate this way using:
309+
You can see which Nushell commands can return constant results using:
295310

296311
```nu
297312
help commands | where is_const
@@ -309,20 +324,21 @@ Nushell is designed to use a single Parsing stage for each expression or file. T
309324

310325
## Variables are Immutable by Default
311326

312-
Another common surprise for folks coming from other languages is that Nushell variables are immutable by default. Coming to Nushell, you'll want to spend some time becoming familiar with working in a more functional style, as this tends to help write code that works best with immutable variables.
327+
Another common surprise when coming from other languages is that Nushell variables are immutable by default. Coming to Nushell, you'll want to spend some time becoming familiar with working in a more functional style, as this tends to help write code that works best with immutable variables.
313328

314329
Immutable variables are also key to Nushell's [`par-each` command](/commands/docs/par-each.md), which allows you to operate on multiple values in parallel using threads.
315330

316331
See [Immutable Variables](variables.html#immutable-variables) and [Choosing between mutable and immutable variables](variables.html#choosing-between-mutable-and-immutable-variables) for more information.
317332

318-
**Thinking in Nushell:** If you're used to relying on mutable variables, it may take some time to relearn how to code in a more functional style. Nushell has many functional features and commands that operate on and with immutable variables. Learning them will help you write code in a more Nushell-idiomatic style.
333+
::: warning Thinking in Nushell
334+
If you're used to relying on mutable variables, it may take some time to relearn how to code in a more functional style. Nushell has many functional features and commands that operate on and with immutable variables. Learning them will help you write code in a more Nushell-idiomatic style.
319335

320336
A nice bonus is the performance increase you can realize by running parts of your code in parallel.
321337
:::
322338

323339
## Nushell's Environment is Scoped
324340

325-
Nushell takes multiple design cues from compiled languages. One such cue is that languages should avoid global mutable state. Shells have commonly used global mutation to update the environment, but Nushell steers clear of this approach.
341+
Nushell takes multiple design cues from compiled languages. One such cue is that languages should avoid global mutable state. Shells have commonly used global mutation to update the environment, but Nushell attempts to steer clear of this approach.
326342

327343
In Nushell, blocks control their own environment. Changes to the environment are scoped to the block where they occur.
328344

@@ -343,6 +359,6 @@ Having a scoped environment makes commands more predictable, easier to read, and
343359
[`def --env`](/commands/docs/def.md) is an exception to this rule. It allows you to create a command that changes the parent's environment.
344360
:::
345361

346-
::: note Thinking in Nushell
362+
::: warning Thinking in Nushell
347363
Use scoped-environment to write more concise scripts and prevent unnecessary or unwanted global environment mutation.
348364
:::

0 commit comments

Comments
 (0)