Nix Language Quirks: Difference between revisions
Add example of using fromTOML for parsing hex/octal/binary number formats |
m propose merge |
||
(5 intermediate revisions by one other user not shown) | |||
Line 1: | Line 1: | ||
{{merge|Nix | {{merge|Nix (language)}} | ||
== <code>with</code> and <code>let</code> == | == <code>with</code> and <code>let</code> == | ||
Line 36: | Line 36: | ||
Note, that it isn't equivalent to <code>with rec { x = 1; y = x + 1; body = y; }; body</code> because of mentioned <code>with</code> and <code>let</code> quirk, but is same as <code>rec { x = 1; y = x + 1; body = y; }.body</code> | Note, that it isn't equivalent to <code>with rec { x = 1; y = x + 1; body = y; }; body</code> because of mentioned <code>with</code> and <code>let</code> quirk, but is same as <code>rec { x = 1; y = x + 1; body = y; }.body</code> | ||
== Default values are not bound in @ syntax == | == Default values are not bound in <code>@</code> syntax == | ||
Destructured arguments can have default values, but those default values are part of the full function argument. | Destructured arguments can have default values, but those default values are part of the full function argument. | ||
Line 85: | Line 85: | ||
pkgs.runCommand (lib.strings.removePrefix ".... </syntaxHighlight> | pkgs.runCommand (lib.strings.removePrefix ".... </syntaxHighlight> | ||
consider the use of <code>import</code> here similar to using <code>qualified import ...</code> in Haskell or <code>import ...</code> in Python. Another (discouraged and increasingly uncommon) way of importing is [https://nix.dev/manual/nix/2.24/language/syntax#with-expressions <code>with import ...;</code>], which corresponds to Python <code>from ... import *</code>. This use of <code>with</code> imports everything from the target into scope, which has numerous potential gotchas and problems, and so | consider the use of <code>import</code> here similar to using <code>qualified import ...</code> in Haskell or <code>import ...</code> in Python. Another (discouraged and increasingly uncommon) way of importing is [https://nix.dev/manual/nix/2.24/language/syntax#with-expressions <code>with import ...;</code>], which corresponds to Python <code>from ... import *</code>. This use of <code>with</code> imports everything from the target into scope, which has numerous potential gotchas and problems, and so using [https://nix.dev/guides/best-practices#with-scopes <code>inherit</code>] instead is encouraged and preferred. | ||
== builtins.replaceStrings key match on "" == | == <code>builtins.replaceStrings</code> key match on "" == | ||
Syntax: | Syntax: | ||
Line 215: | Line 215: | ||
nix-repl> (builtins.fromTOML "hex = 0x09").hex | nix-repl> (builtins.fromTOML "hex = 0x09").hex | ||
9 | 9 | ||
</syntaxHighlight> | |||
== Mimicking case statements with attribute sets == | |||
Nix doesn't include native support for case statements, however when dealing with string types it's possible to use some string interpolation behavior to achieve something similar to case statement behavior, as described in this [https://discourse.nixos.org/t/case-statement-expr/27741/12 thread]. | |||
In the example from the thread, given some string argument <code>x</code>, the following code would place different values into a text file depending on it's value: | |||
<syntaxHighlight lang=nix> | |||
environment.etc."just/for/test".text = { | |||
"a" = "hello"; | |||
"b" = "hi"; | |||
"c" = "ciao"; | |||
}."${x}"; | |||
</syntaxHighlight> | |||
So if <code>x</code> is set to the string <code>"a"</code> then the <code>just/for/test</code> file contents would be set to the string <code>"hello"</code>. The code above is the same in behavior to the following, more common, if-else-style construct: | |||
<syntaxHighlight lang=nix> | |||
environment.etc."just/for/test".text = | |||
if x == "a" then | |||
"hello" | |||
else if x == "b" then | |||
"hi" | |||
else if x == "c" then | |||
"ciao" | |||
else | |||
abort "x is invalid"; | |||
</syntaxHighlight> | |||
There is an example in <code>coq</code> package code [https://github.com/NixOS/nixpkgs/blob/5185539c51ba658e70b29e01c0c320a85f4e2098/pkgs/build-support/coq/extra-lib.nix#L98 here] where someone used this behavior to build a reusable function <code>switch</code>. | |||
== <code>builtins.toString</code> handling of <code>true</code> and <code>false</code> is inconsistent == | |||
<syntaxHighlight lang=nix> | |||
nix-repl> builtins.toString true | |||
"1" | |||
nix-repl> builtins.toString false | |||
"" | |||
</syntaxHighlight> | </syntaxHighlight> | ||
Line 250: | Line 290: | ||
nix-repl> let code = "(x: x) ''id function was called''"; in import (builtins.toFile "eval" code) | nix-repl> let code = "(x: x) ''id function was called''"; in import (builtins.toFile "eval" code) | ||
"id function was called"</syntaxHighlight> | "id function was called"</syntaxHighlight> | ||
= Resources = | |||
* [https://md.darmstadt.ccc.de/xtNP7JuIQ5iNW1FjuhUccw# A separately maintained list of Nix language quirks] | |||
[[Category:Nix Language]] | [[Category:Nix Language]] |