Functions help to build reusable components in a big repository like nixpkgs. The Nix manual has a great explanation of functions. Let's go: pill on one hand, Nix manual on the other hand.
I remind you how to enter the Nix environment: source ~/.nix-profile/etc/profile.d/nix.sh
Nameless and single parameter
Functions are anonymous (lambdas), and only have a single parameter. The syntax is extremely simple. Type the parameter name, then ":", then the body of the function.
nix-repl> x: x*2 «lambda»
So here we defined a function that takes a parameter x, and returns x*2. The problem is that we cannot use it in any way, because it's unnamed... joke!
We can store functions in variables.
nix-repl> double = x: x*2 nix-repl> double «lambda» nix-repl> double 3 6
As usual, please ignore the special syntax for assignments inside nix-repl.
So, we defined a function x: x*2 that takes one parameter x, and returns x*2. This function is then assigned to the variable double.
Finally we did our first function call: double 3.
Big note: it's not like many other programming languages where you write double(3). It really is double 3.
In summary: to call a function, name the variable, then space, then the argument. Nothing else to say, it's as easy as that.
More than one parameter
How do we create a function that accepts more than one parameter? For people not used to functional programming, this may take a while to grasp. Let's do it step by step.
nix-repl> mul = a: (b: a*b) nix-repl> mul «lambda» nix-repl> mul 3 «lambda» nix-repl> (mul 3) 4 12
We defined a function that takes the parameter "a", the body returns another function. This other function takes a parameter "b" and returns a*b.
Therefore, calling "mul 3" returns this kind of function: b: 3*b. In turn, we call the returned function with 4, and get the expected result.
You don't have to use parenthesis at all, Nix has sane priorities when parsing the code:
nix-repl> mul = a: b: a*b nix-repl> mul «lambda» nix-repl> mul 3 «lambda» nix-repl> mul 3 4 12 nix-repl> mul (6+7) (8+9) 221
Much more readable, you don't even notice that functions only receive one argument.
Since the argument is separated by a space, to pass more complex expressions you need parenthesis. In other common languages you would write mul(6+7, 8+9).
Given that functions have only one parameter, it is straightforward to use partial application:
nix-repl> foo = mul 3 nix-repl> foo 4 12 nix-repl> foo 5 15
We stored the function returned by mul 3 into a variable foo, then reused it.
Arguments set
Now this is a very cool feature of Nix. It is possible to pattern match over a set in the parameter. We write an alternative version of mul = a: b: a*b first by using a set as argument, then using pattern matching.
nix-repl> mul = s: s.a*s.b nix-repl> mul { a = 3; b = 4; } 12 nix-repl> mul = { a, b }: a*b nix-repl> mul { a = 3; b = 4; } 12
In the first case we defined a function that accepts a single parameter. We then access attributes "a" and "b" from the given set.
Note how the parenthesis-less syntax for function calls is very elegant in this case, instead of doing mul({ a=3; b=4; }) in other languages.
In the second case we defined an arguments set. It's like defining a set, except without values. We require that the passed set contains the keys "a" and "b". Then we can use those "a" and "b" in the function body directly.
nix-repl> mul { a = 3; b = 4; c = 6; } error: anonymous function at (string):1:2 called with unexpected argument `c', at (string):1:1 nix-repl> mul { a = 3; } error: anonymous function at (string):1:2 called without required argument `b', at (string):1:1
Only a set with exactly the attributes required by the function is accepted, nothing more, nothing less.
Default and variadic attributes
It is possible to specify default values of attributes in the arguments set:
nix-repl> mul = { a, b ? 2 }: a*b nix-repl> mul { a = 3; } 6 nix-repl> mul { a = 3; b = 4; } 12
Also you can allow passing more attributes (variadic) than the expected ones:
nix-repl> mul = { a, b, ... }: a*b nix-repl> mul { a = 3; b = 4; c = 2; }
However, in the function body you cannot access the "c" attribute. The solution is to give a name to the given set with the @-pattern:
nix-repl> mul = s@{ a, b, ... }: a*b*s.c nix-repl> mul { a = 3; b = 4; c = 2; } 24
That's it, you give a name to the whole parameter with name@ before the set pattern.
Advantages of using argument sets:
- Named unordered arguments: you don't have to remember the order of the arguments.
- You can pass sets, that adds a whole new layer of flexibility and convenience.
Disadvantages:
- Partial application does not work with argument sets. You have to specify the whole attribute set, not part of it.
Imports
The "import" function is built-in and provides a way to parse a .nix file. The natural approach is to define each component in a .nix file, then compose by importing these files.
Let's start with the bare metal.
a.nix:
3
b.nix:
4
mul.nix:
a: b: a*b
nix-repl> a = import ./a.nix nix-repl> b = import ./b.nix nix-repl> mul = import ./mul.nix nix-repl> mul a b 12
Yes it's really that straight. You import a file, and it gets parsed as expression. Note that the scope of the imported file does not inherit the scope of the importer.
test.nix:
x
nix-repl> let x = 5; in import ./test.nix error: undefined variable `x' at /home/lethal/test.nix:1:1
So how do we pass information to the module? Use functions, like we did with mul.nix .
A more complex example:
test.nix:
A more complex example:
test.nix:
{ a, b ? 3, trueMsg ? "yes", falseMsg ? "no" }: if a > b then builtins.trace trueMsg true else builtins.trace falseMsg false
nix-repl> import ./test.nix { a = 5; trueMsg = "ok"; } trace: ok true
Explaining:
- In test.nix we return a function. It accepts a set, with default attributes b, trueMsg and falseMsg.
- builtins.trace is a built-in function that takes two arguments. The first is the message to display, the second is the value to return. It's usually used for debugging purposes.
- Then we import test.nix, and call the function with that set.
So when is the message shown? Only when it's in need to be evaluated.
Next pill
...we will finally write our first derivation.
Nix pill 6 is available for reading here.
To be notified about the new pill, stay tuned on #NixPills, follow @lethalman or subscribe to the nixpills rss.
Nix pill 6 is available for reading here.
To be notified about the new pill, stay tuned on #NixPills, follow @lethalman or subscribe to the nixpills rss.
13 comments:
luca, I guess the links to "anchors" in the nix[os] manual are based on auto-generated random IDs which are not stable when the manual gets updated, so many of them are broken.
thanks for the tutorial, pal!
Good post....
Coronavirus Update
Intern Ship In Chennai
Inplant Training In Chennai
Internship For CSE Students
Online Internships
Internship For MBA Students
ITO Internship
kokteyl catering
kokteyl catering fiyatları
istanbul kokteyl catering
catering kokteyl menüleri
fuar yemek organizasyon
fuar yemek organizasyo firmaları
fuar için yemek firmaları
düğün yemek organizasyonu
düğün yemek organizasyonu yapan firmalar
istanbul kokteyl catering
istanbul kokteyl catering firmaları
Kokteyl catering fiyatları
istanbul catering firmaları listesi
istanbul catering şirketleri
istanbul Fuar catering Hizmetleri
catering şirketleri istanbul
istanbul daki catering firmaları
300 kişilik yemek Fiyatları
istanbul fuar yemek organizasyonn
istanbul fuar yemek organizasyon firmaları
istanbul fuar için yemek firmaları
Sağlık Haberleri Sağlıklı Yaşam ve Beslenme Sağlık alanından en son araştırmalar, sağlıklı yaşam için gereklilikler, diyetler, beslenme şekilleri, hastalıklar ve yeni tedavi yöntemleri hakkında güncel bilgiler.
Great post, thanks
SRI ANNAPOORNESHAWARI ASTROLOGY CENTER.Best Astrologer In Pennsylvania
Nice post. Keep sharing. Thanks for sharing.
SRICHAKRAM ASTROLOGY.Best Astrologer In Hebbal
it was great information and very useful
SRI ANNAPOORNESHAWARI ASTROLOGY CENTER.Best Astrologer In Navi Mumbai
Great post, thanks
SRIKRISHANA ASTROLOGY.Best Astrologer In Raichur
it was great information and very useful
DURGAANUGARHA ASTROLOGY.Best Astrologer In kr-puram
Thank you for your post. This is excellent information
ABHIRAM ASTROLOGY CENTER.Best Astrologer In northwest-territories
We produce the best academic assignments and bespoke Macroeconomics assignment help for every academic stream. We take pride in our highly qualified and experienced subject experts onboard and hence guarantee you the best academic grade for each of your assignments.
Sancaktepe Online Psikolog
İstanbul Online Psikolog
istanbul terapist
Germencik Beko Mağazası, evinizin ihtiyaçlarını karşılayacak geniş bir ürün yelpazesi sunar. Mutfakta kullanabileceğiniz son teknoloji fırınlar, ocaklar ve buzdolapları, aynı zamanda çamaşır makineleri, bulaşık makineleri ve kurutma makineleri gibi beyaz eşyaların yanı sıra televizyonlar, klimalar ve daha fazlası mağazamızda bulunabilir. Her bütçeye uygun seçenekler sunarak, herkesin ihtiyaçlarını karşılamayı amaçlıyoruz.
www.aydinbeko.com.tr
Germencik Beko
Aydin Beko
Efeler Beko
Post a Comment