Skip to content

Commit

Permalink
docs: add variables; rework scope
Browse files Browse the repository at this point in the history
  • Loading branch information
rhendric committed Jul 25, 2024
1 parent dba1142 commit bea9e3d
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 10 deletions.
2 changes: 2 additions & 0 deletions doc/manual/src/SUMMARY.md.in
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
- [Data Types](language/types.md)
- [String context](language/string-context.md)
- [Syntax and semantics](language/syntax.md)
- [Expressions]()
- [Variables](language/variables.md)
- [Identifiers](language/identifiers.md)
- [Scoping rules](language/scope.md)
- [String interpolation](language/string-interpolation.md)
Expand Down
2 changes: 1 addition & 1 deletion doc/manual/src/language/identifiers.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ A name can be an [identifier](#identifier) or a [string literal](./syntax.md#str
>
> *name**identifier* | *string*
Names are used in [attribute sets](./syntax.md#attrs-literal), [`let` bindings](./syntax.md#let-expressions), and [`inherit`](./syntax.md#inheriting attributes).
Names are used in [attribute sets](./syntax.md#attrs-literal), [`let` bindings](./syntax.md#let-expressions), and [`inherit`](./syntax.md#inheriting-attributes).

# Keywords

Expand Down
38 changes: 29 additions & 9 deletions doc/manual/src/language/scope.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,34 @@
# Scoping rules

Nix is [statically scoped](https://en.wikipedia.org/wiki/Scope_(computer_science)#Lexical_scope), but with multiple scopes and shadowing rules.
A _scope_ in the Nix language is an [identifier]-keyed dictionary, mapping each identifier to an expression and a _definition type_.
The definition type is either _explicit_ or _implicit_.
Each entry in this dictionary is a _definition_.

* primary scope: explicitly-bound variables
* [`let`](./syntax.md#let-expressions)
* [`inherit`](./syntax.md#inheriting-attributes)
* [function](./syntax.md#functions) arguments
[identifier]: identifiers.md

* secondary scope: implicitly-bound variables
* [`with`](./syntax.md#with-expressions)
Explicit definitions are created by the following expressions:
* [let-expressions](syntax.md#let-expressions)
* [recursive attribute set literals](syntax.md#recursive-sets) (`rec`)
* [function literals](syntax.md#functions)

Primary scope takes precedence over secondary scope.
See [`with`](./syntax.md#with-expressions) for a detailed example.
Implicit definitions are only created by [with-expressions].

[with-expressions]: syntax.md#with-expressions

Each of the above expressions defines which of its subexpressions are _enclosed_ by the extended scope.
The outermost expression of a Nix language file is enclosed by the [global scope], which contains only explicit definitions.
Nix is [statically scoped]; the enclosing scope of an expression is always determined only by the expressions that contain it as a subexpression, and not by the context in which it is evaluated.

[global scope]: builtins.md
[statically scoped]: https://en.wikipedia.org/wiki/Scope_(computer_science)#Lexical_scope

The above expressions _extend_ their enclosing scope by adding new definitions, or replacing existing ones with the same name.
An explicit definition can replace a definition of any type; an implicit definition can only replace another implicit definition.
See [with-expressions] for a detailed example.

> **Note**
>
> Expressions entered into the [Nix REPL] are enclosed by a scope that can be extended by command line arguments or previous REPL commands.
> These ways of extending scope are not, strictly speaking, part of the Nix language.
[Nix REPL]: @docroot@/command-ref/new-cli/nix3-repl.md
12 changes: 12 additions & 0 deletions doc/manual/src/language/variables.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Variables

A _variable_ is an [identifier](identifiers.md) used as an expression.

> **Syntax**
>
> *expression**identifier*
A variable must have the same name as a definition in the [scope] that encloses it.
The value of a variable is the value of the corresponding expression in the enclosing scope.

[scope]: scope.md

0 comments on commit bea9e3d

Please sign in to comment.