forked from lix-project/lix
document identifier syntax for attribute sets
it's more likely for readers to find it right there. this also slightly rewords examples to make them stand out better. in the long run there probably needs to be a dedicated section on formal syntax, and better highlighting of examples.
This commit is contained in:
parent
dfc393ffd3
commit
d8bfeda164
|
@ -2,8 +2,11 @@
|
||||||
|
|
||||||
## Recursive sets
|
## Recursive sets
|
||||||
|
|
||||||
Recursive sets are just normal sets, but the attributes can refer to
|
Recursive sets are like normal [attribute sets](./values.md#attribute-set), but the attributes can refer to each other.
|
||||||
each other. For example,
|
|
||||||
|
> *rec-attrset* = `rec {` [ *name* `=` *expr* `;` `]`... `}`
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
rec {
|
rec {
|
||||||
|
@ -12,7 +15,9 @@ rec {
|
||||||
}.x
|
}.x
|
||||||
```
|
```
|
||||||
|
|
||||||
evaluates to `123`. Note that without `rec` the binding `x = y;` would
|
This evaluates to `123`.
|
||||||
|
|
||||||
|
Note that without `rec` the binding `x = y;` would
|
||||||
refer to the variable `y` in the surrounding scope, if one exists, and
|
refer to the variable `y` in the surrounding scope, if one exists, and
|
||||||
would be invalid if no such variable exists. That is, in a normal
|
would be invalid if no such variable exists. That is, in a normal
|
||||||
(non-recursive) set, attributes are not added to the lexical scope; in a
|
(non-recursive) set, attributes are not added to the lexical scope; in a
|
||||||
|
@ -33,7 +38,10 @@ will crash with an `infinite recursion encountered` error message.
|
||||||
## Let-expressions
|
## Let-expressions
|
||||||
|
|
||||||
A let-expression allows you to define local variables for an expression.
|
A let-expression allows you to define local variables for an expression.
|
||||||
For instance,
|
|
||||||
|
> *let-in* = `let` [ *identifier* = *expr* ]... `in` *expr*
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
let
|
let
|
||||||
|
@ -42,18 +50,19 @@ let
|
||||||
in x + y
|
in x + y
|
||||||
```
|
```
|
||||||
|
|
||||||
evaluates to `"foobar"`.
|
This evaluates to `"foobar"`.
|
||||||
|
|
||||||
## Inheriting attributes
|
## Inheriting attributes
|
||||||
|
|
||||||
When defining a set or in a let-expression it is often convenient to
|
When defining an [attribute set](./values.md#attribute-set) or in a [let-expression](#let-expressions) it is often convenient to copy variables from the surrounding lexical scope (e.g., when you want to propagate attributes).
|
||||||
copy variables from the surrounding lexical scope (e.g., when you want
|
This can be shortened using the `inherit` keyword.
|
||||||
to propagate attributes). This can be shortened using the `inherit`
|
|
||||||
keyword. For instance,
|
Example:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
let x = 123; in
|
let x = 123; in
|
||||||
{ inherit x;
|
{
|
||||||
|
inherit x;
|
||||||
y = 456;
|
y = 456;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -62,15 +71,23 @@ is equivalent to
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
let x = 123; in
|
let x = 123; in
|
||||||
{ x = x;
|
{
|
||||||
|
x = x;
|
||||||
y = 456;
|
y = 456;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
and both evaluate to `{ x = 123; y = 456; }`. (Note that this works
|
and both evaluate to `{ x = 123; y = 456; }`.
|
||||||
because `x` is added to the lexical scope by the `let` construct.) It is
|
|
||||||
also possible to inherit attributes from another set. For instance, in
|
> **Note**
|
||||||
this fragment from `all-packages.nix`,
|
>
|
||||||
|
> This works because `x` is added to the lexical scope by the `let` construct.
|
||||||
|
|
||||||
|
It is also possible to inherit attributes from another attribute set.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
In this fragment from `all-packages.nix`,
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
graphviz = (import ../tools/graphics/graphviz) {
|
graphviz = (import ../tools/graphics/graphviz) {
|
||||||
|
|
|
@ -35,17 +35,14 @@
|
||||||
|
|
||||||
## Attribute selection
|
## Attribute selection
|
||||||
|
|
||||||
|
> *attrset* `.` *attrpath* \[ `or` *expr* \]
|
||||||
|
|
||||||
Select the attribute denoted by attribute path *attrpath* from [attribute set] *attrset*.
|
Select the attribute denoted by attribute path *attrpath* from [attribute set] *attrset*.
|
||||||
If the attribute doesn’t exist, return the *expr* after `or` if provided, otherwise abort evaluation.
|
If the attribute doesn’t exist, return the *expr* after `or` if provided, otherwise abort evaluation.
|
||||||
|
|
||||||
<!-- FIXME: the following should to into its own language syntax section, but that needs more work to fit in well -->
|
An attribute path is a dot-separated list of [attribute names](./values.md#attribute-set).
|
||||||
|
|
||||||
An attribute path is a dot-separated list of attribute names.
|
> *attrpath* = *name* [ `.` *name* ]...
|
||||||
An attribute name can be an identifier or a string.
|
|
||||||
|
|
||||||
> *attrpath* = *name* [ `.` *name* ]... \
|
|
||||||
> *name* = *identifier* | *string* \
|
|
||||||
> *identifier* ~ `[a-zA-Z_][a-zA-Z0-9_'-]*`
|
|
||||||
|
|
||||||
[Attribute selection]: #attribute-selection
|
[Attribute selection]: #attribute-selection
|
||||||
|
|
||||||
|
|
|
@ -164,9 +164,17 @@ Note that lists are only lazy in values, and they are strict in length.
|
||||||
|
|
||||||
An attribute set is a collection of name-value-pairs (called *attributes*) enclosed in curly brackets (`{ }`).
|
An attribute set is a collection of name-value-pairs (called *attributes*) enclosed in curly brackets (`{ }`).
|
||||||
|
|
||||||
|
An attribute name can be an identifier or a [string](#string).
|
||||||
|
An identifier must start with a letter (`a-z`, `A-Z`) or underscore (`_`), and can otherwise contain letters (`a-z`, `A-Z`), numbers (`0-9`), underscores (`_`), apostrophes (`'`), or dashes (`-`).
|
||||||
|
|
||||||
|
> *name* = *identifier* | *string* \
|
||||||
|
> *identifier* ~ `[a-zA-Z_][a-zA-Z0-9_'-]*`
|
||||||
|
|
||||||
Names and values are separated by an equal sign (`=`).
|
Names and values are separated by an equal sign (`=`).
|
||||||
Each value is an arbitrary expression terminated by a semicolon (`;`).
|
Each value is an arbitrary expression terminated by a semicolon (`;`).
|
||||||
|
|
||||||
|
> *attrset* = `{` [ *name* `=` *expr* `;` `]`... `}`
|
||||||
|
|
||||||
Attributes can appear in any order.
|
Attributes can appear in any order.
|
||||||
An attribute name may only occur once.
|
An attribute name may only occur once.
|
||||||
|
|
||||||
|
@ -182,15 +190,19 @@ Example:
|
||||||
|
|
||||||
This defines a set with attributes named `x`, `text`, `y`.
|
This defines a set with attributes named `x`, `text`, `y`.
|
||||||
|
|
||||||
Attributes can be selected from a set using the `.` operator. For
|
Attributes can be accessed with the [`.` operator](./operators.md#attribute-selection).
|
||||||
instance,
|
|
||||||
|
Example:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
{ a = "Foo"; b = "Bar"; }.a
|
{ a = "Foo"; b = "Bar"; }.a
|
||||||
```
|
```
|
||||||
|
|
||||||
evaluates to `"Foo"`. It is possible to provide a default value in an
|
This evaluates to `"Foo"`.
|
||||||
attribute selection using the `or` keyword:
|
|
||||||
|
It is possible to provide a default value in an attribute selection using the `or` keyword.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
{ a = "Foo"; b = "Bar"; }.c or "Xyzzy"
|
{ a = "Foo"; b = "Bar"; }.c or "Xyzzy"
|
||||||
|
|
Loading…
Reference in a new issue