You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: book/thinking_in_nu.md
+43-27Lines changed: 43 additions & 27 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -10,7 +10,9 @@ The most common questions from new users typically fall into one of the followin
10
10
11
11
### It can sometimes look like Bash
12
12
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:
Nushell has many other similarities with Bash (and other shells) and many commands in common.
21
23
22
24
::: 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:
24
26
25
27
```nu
26
28
http get https://api.github.com/repos/nushell/nushell/contributors | select login contributions
@@ -45,7 +47,7 @@ echo $?
45
47
# => 1
46
48
```
47
49
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.
49
51
50
52
```nu
51
53
4 > 10
@@ -74,29 +76,31 @@ echo "Hello, World"
74
76
# => Hello, World
75
77
```
76
78
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
78
80
simply _returning a value_. Nushell then _renders_ the return value of a command, or more technically, an _expression_.
79
81
80
82
More importantly, Nushell _implicitly returns_ the value of an expression. This is similar to PowerShell or Rust in many respects.
81
83
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
+
:::
83
87
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:
85
89
86
90
```nu
87
91
"Hello, World" == (echo "Hello, World")
88
92
# => true
89
93
```
90
94
91
-
An example with a custom command definition:
95
+
Here's another example with a custom command definition:
92
96
93
97
```nu
94
98
def latest-file [] {
95
99
ls | sort-by modified | last
96
100
}
97
101
```
98
102
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.
100
104
101
105
::: warning Thinking in Nushell
102
106
Most anywhere you might write `echo <something>`, in Nushell, you can just write `<something>` instead.
@@ -122,14 +126,16 @@ New users might expect:
122
126
- Line 2 to output _"Returning the last file"_
123
127
- Line 3 to return/output the file
124
128
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.
126
130
127
131
To make sure the first line is _displayed_, use the [`print` command](/commands/docs/print.md):
128
132
133
+
```nu
129
134
def latest-file [] {
130
135
print "Returning last file"
131
136
ls | sort-by modified | last
132
137
}
138
+
```
133
139
134
140
Also compare:
135
141
@@ -138,7 +144,7 @@ Also compare:
138
144
```
139
145
140
146
::: 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:
142
148
143
149
```nu
144
150
40
@@ -195,8 +201,8 @@ $p * 6
195
201
result, and is also displayed (rendered).
196
202
197
203
::: 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.
200
206
201
207
`help <command>` will show the signature, including the output type(s), for each command in Nushell.
202
208
:::
@@ -208,10 +214,10 @@ In most other shells, code is is only _evaluated_. In Nushell, code is:
208
214
1. Stage 1: Parsed
209
215
2. Stage 2: If the code parsed correctly, the result is then Evaluated
210
216
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:
212
218
213
219
- Accurate and expressive error messages
214
-
-Earlier and robust detection of error conditions
220
+
-Semantic analysis for earlier and robust detection of error conditions
215
221
- IDE integration
216
222
- The type system
217
223
- The module system
@@ -223,9 +229,18 @@ The Nushell Parser is key to many of Nushell's and the REPL features such as:
223
229
- (Future) Formatting
224
230
- (Future) Saving IR (Intermediate Results) "compiled" results for faster execution
225
231
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.
227
233
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):
229
244
230
245
```nu
231
246
"print Hello" | save output.nu
@@ -244,16 +259,16 @@ source output.nu
244
259
245
260
This is problematic because:
246
261
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.
249
264
250
265
::: note
251
266
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.
252
267
253
268
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.
254
269
:::
255
270
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:
257
272
258
273
```nu
259
274
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
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.
293
308
294
-
You can see which Nushell commands operate this way using:
309
+
You can see which Nushell commands can return constant results using:
295
310
296
311
```nu
297
312
help commands | where is_const
@@ -309,20 +324,21 @@ Nushell is designed to use a single Parsing stage for each expression or file. T
309
324
310
325
## Variables are Immutable by Default
311
326
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.
313
328
314
329
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.
315
330
316
331
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.
317
332
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.
319
335
320
336
A nice bonus is the performance increase you can realize by running parts of your code in parallel.
321
337
:::
322
338
323
339
## Nushell's Environment is Scoped
324
340
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.
326
342
327
343
In Nushell, blocks control their own environment. Changes to the environment are scoped to the block where they occur.
328
344
@@ -343,6 +359,6 @@ Having a scoped environment makes commands more predictable, easier to read, and
343
359
[`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.
344
360
:::
345
361
346
-
::: note Thinking in Nushell
362
+
::: warning Thinking in Nushell
347
363
Use scoped-environment to write more concise scripts and prevent unnecessary or unwanted global environment mutation.
0 commit comments