“hello ${{a=“1”; b=“2”;}.b}” “1 2 ${toString 3}” “${pkgs.bash}/bin/sh”
Data types
/etc
./foo.png
~/.config
{ foo.bar = 1; } { foo = { bar = 1; }; }
rec {}
Primitives
- String
“foo bar”
’'
foo
bar
’'
“foo\nbar\n”
- string interpolation ${} ‘’${} ‘’\n
- Number 123 .23e13
- Path /bin/sh ./builder.sh (relative to the directory of the Nix expression that contained it) ~/foo at least one slash must appear before any interpolated expresssion. <>
- Boolean true and false
- Null null
List
[ 123 “jfalkdjf” ./foo.nix (f {x=y;}) ]
builtins.elemAt
Attribute Set
A collection of name-value-pairs (called attributes)
identifier: [a-zA-Z_][a-zA-Z0-9_'-]*
name : identifier | string
attrset : {[name = expr;]...}
.
operator or
keyword
{ a = "Foo"; b = "Bar"; }.c.d.e.f.g or "Xyzzy"
Attr names string interpolation:
let bar = "foo"; in
{ foo = 123; }.${bar}
let bar = "foo"; in
{ ${bar} = 123; }.foo
{ ${if foo then "bar" else null} = true; }
__functor
let add = { __functor = self: x: x + self.x; };
inc = add // { x = 1; };
in inc 1
Recursive sets
rec-attrset: rec { [ name = expr ; ]… }
rec {
x = y;
y = x;
}.x
`infinite recursion encountered`
## Operator
String: +
Number: + - * /
Relation: == !=
Boolean: !
Attr: a.x
a.x or 1
Sets: {} // {}
## expression
### Let-expressions
let-in: let [ identifier = expr; ]... in expr
let x = 1; y = 2; in x + y
### Inheriting attributes
inherit pkgs src;
inherit (pkgs) src pkg1 pkg2 pkg3;
Adds the variables to the current scope (attribute set
or `let` bindings).
let x = { a = 1; b = 2; }; inherit (builtins) attrNames; in { names = attrNames x; }
let x = { a = 1; b = 2; }; in { names = builtins.attrNames x; }
### With-expressions
with e1; e2
with builtins; head [ 1 2 3 ]
with (import ./def.nix); ...
let a = 3; in with { a = 1; }; let a = 4; in with { a = 2; }; a let a = 3; in with { a = 1; }; let a = 4; in with { a = 2; }; a
### Conditionals
if 1 + 1 == 2
then "yes!"
else "no!
### Assertions
assert 1+1==2;
"yes!"
{ localServer ? false , httpServer ? false , sslSupport ? false , pythonBindings ? false , javaSwigBindings ? false , javahlBindings ? false , stdenv, fetchurl , openssl ? null, httpd ? null, db4 ? null, expat, swig ? null, j2sdk ? null }:
assert localServer -> db4 != null; ① assert httpServer -> httpd != null && httpd.expat == expat; ② assert sslSupport -> openssl != null && (httpServer -> httpd.openssl == openssl); ③ assert pythonBindings -> swig != null && swig.pythonSupport; assert javaSwigBindings -> swig != null && swig.javaSupport; assert javahlBindings -> j2sdk != null;
stdenv.mkDerivation { name = “subversion-1.1.1”; … openssl = if sslSupport then openssl else null; ④ … }
## Functions
pattern: body
x: x + 1
x: y: x + y
(x: x + 1) 100
let inc = x: x + 1; in inc (inc (inc 100))
{ x, y }: x + y
{ x, y ? "bar" }: x + y
{ x, y, ... }: x + y
{ x, y } @ args: x + y
args @ { x, y }: x + y
args@{ x, y, z, ... }: z + y + x + args.a
### eg
let concat = x: y: x+y; f = concat “foo”; g = concat “goo”; in [(f “bar”) (f “xxx”) (g “bar”) (g “xxx”)]
let f = args@{ a ? 23, … }: [ a args ]; in f {}
let f = args @ { … }: [ (args.a or 23) args ]; in f {}
## Built-in functions
import ./foo.nix
map (x: x + x) [ 1 2 3 ]
## Comments
ccccoments
/* … */