Nix (language): Difference between revisions

imported>Sitwon
m Correcting the grammar of the sentence by removing an extra occurrence of 'into'.
imported>Gabriel-doriath-dohler
No edit summary
Line 287: Line 287:


==== <code>with</code> statement ====
==== <code>with</code> statement ====
The [https://nixos.org/manual/nix/stable/#idm140737321903120 <code>with</code> statement] introduces an attrset's value contents into the lexical scope of the expression which follows. This means that it brings all keys within that set (that do not already exist in an outer scope) into scope in that expression. So, you don't need to use the dot notation.
The [https://nixos.org/manual/nix/stable/#idm140737321903120 <code>with</code> statement] introduces an attrset's value contents into the lexical scope of the expression which follows. This means that it brings all keys within that set into scope in that expression. So, you don't need to use the dot notation. If a key is already in the outer scope, it is only shadowed when it was introduced by a <code>with</code> statement.


Example:
Example:
Line 304: Line 304:
</syntaxHighlight>
</syntaxHighlight>


Note that (perhaps surprisingly) <code>with</code> '''does not shadow''' values from outer scope. For example:
Note that (perhaps surprisingly) <code>with</code> '''does not shadow''' variables from outer scope which were bound in a <code>let</code> statement or a lambda abstraction. For example:


<syntaxHighlight lang=nix>
<syntaxHighlight lang=nix>
Line 320: Line 320:


This is because <code>a</code> was already defined in the scope outside the use of <code>with</code>, and <code>with</code> does ''not'' override it. The outer value takes precedence. (It is suspected by the author of this wiki section that the reason for this non-shadowing logic is lexical code stability: In the common usages of <code>with</code> as shown below, the contents of attrsets given to the statement are often large, community-maintained, and frequently updated. If e.g. <code>let myValue = ...; with lib; doSomethingWith myValue</code> shadowed the outer <code>myValue</code> bindings, the people maintaining `lib` could accidentally break this code by adding <code>lib.myValue</code>.)
This is because <code>a</code> was already defined in the scope outside the use of <code>with</code>, and <code>with</code> does ''not'' override it. The outer value takes precedence. (It is suspected by the author of this wiki section that the reason for this non-shadowing logic is lexical code stability: In the common usages of <code>with</code> as shown below, the contents of attrsets given to the statement are often large, community-maintained, and frequently updated. If e.g. <code>let myValue = ...; with lib; doSomethingWith myValue</code> shadowed the outer <code>myValue</code> bindings, the people maintaining `lib` could accidentally break this code by adding <code>lib.myValue</code>.)
Note that variables are shadowed when (and only when) they were introduced by a <code>with</code> statement. For example:
<syntaxHighlight lang=nix>
nix-repl> with { x = "outer"; }; with { x = "inner"; }; x
"inner"
</syntaxHighlight>


Common usages are:
Common usages are: