<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>NixLang | Christopher Coverdale Blog</title><link>https://www.christophercoverdale.com/tag/nixlang/</link><atom:link href="https://www.christophercoverdale.com/tag/nixlang/index.xml" rel="self" type="application/rss+xml"/><description>NixLang</description><generator>Hugo Blox Builder (https://hugoblox.com)</generator><language>en-us</language><lastBuildDate>Wed, 25 Sep 2024 00:00:00 +0000</lastBuildDate><image><url>https://www.christophercoverdale.com/media/icon_hu68170e94a17a2a43d6dcb45cf0e8e589_3079_512x512_fill_lanczos_center_3.png</url><title>NixLang</title><link>https://www.christophercoverdale.com/tag/nixlang/</link></image><item><title>Nix 101: Part 3</title><link>https://www.christophercoverdale.com/blog/nix-101-part-3/</link><pubDate>Wed, 25 Sep 2024 00:00:00 +0000</pubDate><guid>https://www.christophercoverdale.com/blog/nix-101-part-3/</guid><description>&lt;p>The third part of Nix 101 will explain and go through nix flakes.&lt;/p>
&lt;h2 id="flakes---what-are-they-and-why">Flakes - what are they and why&lt;/h2>
&lt;p>Nix Flakes are another way to create reproducible environments. They are arguably
more reproducible than shells and are the community favoured strategy in creating
environments.&lt;/p>
&lt;p>Flakes improve on Nix Shells by addressing the problem inherent in pulling dependencies from Nixpkgs.&lt;/p>
&lt;p>In Nix shells, the upstream version of Nixpkgs is not locked, meaning two engineers using the same shell file
might use different versions of Nixpkgs (e.g. nixpkgs 1.2.3 vs nixpkgs 1.2.4). This could result in different
versions of the dependencies being pulled, leading to breaking builds or inconsistencies between the different environments.&lt;/p>
&lt;p>With Nix Flakes, the version of nixpkgs and source is explicitly declared, this generates a &lt;code>flake.lock&lt;/code> file that locks in the version.&lt;/p>
&lt;h3 id="example-flake">Example Flake&lt;/h3>
&lt;p>Using our zig shell in the previous blog post, we&amp;rsquo;ll create a flake to lock in the nixpkg dependency version.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-gdscript3" data-lang="gdscript3">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">inputs&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">nixpkgs&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">url&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;github:NixOS/nixpkgs/nixos-unstable&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">outputs&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="bp">self&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">nixpkgs&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="o">...&lt;/span> &lt;span class="p">}:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">let&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">system&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;x86_64-linux&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">pkgs&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">import&lt;/span> &lt;span class="n">nixpkgs&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="n">inherit&lt;/span> &lt;span class="n">system&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Helper function to build different versions of each zig version.&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">zigDerivation&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="n">version&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nb">hash&lt;/span> &lt;span class="p">}&lt;/span> &lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">pkgs&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">stdenv&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">mkDerivation&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">pname&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;zig&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">version&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">version&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">src&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pkgs&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">fetchurl&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">url&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;https://ziglang.org/download/${version}/zig-linux-x86_64-${version}.tar.xz&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">sha256&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">hash&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">buildPhase&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">mkdir&lt;/span> &lt;span class="o">-&lt;/span>&lt;span class="n">p&lt;/span> &lt;span class="o">$&lt;/span>&lt;span class="n">out&lt;/span>&lt;span class="o">/&lt;/span>&lt;span class="n">bin&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cp&lt;/span> &lt;span class="o">./&lt;/span>&lt;span class="n">zig&lt;/span> &lt;span class="o">$&lt;/span>&lt;span class="n">out&lt;/span>&lt;span class="o">/&lt;/span>&lt;span class="n">bin&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="ow">in&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">packages&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">x86_64&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">linux&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">zig0130&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">zigDerivation&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="n">version&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;0.13.0&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="nb">hash&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;1FMS5h68xIAyt3vEz3/WkVwR+hbkqtEWtmyUaCESMOo=&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">x86_64&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">linux&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">zig0120&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">zigDerivation&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="n">version&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;0.12.0&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="nb">hash&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;x66Ga4p2pWji1c/TH+ic22Kb3RYf3VAYsppKChcEXK0=&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">devShells&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">x86_64&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">linux&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">default&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pkgs&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">mkShell&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">buildInputs&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span> &lt;span class="bp">self&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">packages&lt;/span>&lt;span class="o">.$&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="n">system&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">zig0130&lt;/span> &lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">devShells&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">x86_64&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">linux&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">zig0130&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pkgs&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">mkShell&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">buildInputs&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span> &lt;span class="bp">self&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">packages&lt;/span>&lt;span class="o">.$&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="n">system&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">zig0130&lt;/span> &lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">devShells&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">x86_64&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">linux&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">zig0120&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pkgs&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">mkShell&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">buildInputs&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span> &lt;span class="bp">self&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">packages&lt;/span>&lt;span class="o">.$&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="n">system&lt;/span>&lt;span class="p">}&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">zig0120&lt;/span> &lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>There&amp;rsquo;s a lot more going on than the shell, we&amp;rsquo;ll step through each line:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;code>inputs.nixpkgs.url = &amp;quot;github:NixOS/nixpkgs/nixos-unstable&amp;quot;;&lt;/code> - This line declares the upstream source which will contain the version of nixpkgs for this flake&lt;/p>
&lt;/li>
&lt;li>
&lt;p>We create the derivation and build phase for the flake. We are downloading and going to use the parameters of &lt;code>version&lt;/code> and &lt;code>hash&lt;/code> when creating this derivation&lt;/p>
&lt;/li>
&lt;li>
&lt;p>This will download the binary using fetchurl and copy the binary to the &lt;code>$out/bin&lt;/code> directory, which is the environment for the shell&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Important to note, this is still not totally reproducible since this flake would only work correctly on systems that are &lt;code>x86_64-linux&lt;/code>&lt;/p>
&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-gdscript3" data-lang="gdscript3">&lt;span class="line">&lt;span class="cl"> &lt;span class="n">outputs&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="bp">self&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">nixpkgs&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="o">...&lt;/span> &lt;span class="p">}:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">let&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">system&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;x86_64-linux&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">pkgs&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">import&lt;/span> &lt;span class="n">nixpkgs&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="n">inherit&lt;/span> &lt;span class="n">system&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Helper function to build different versions of each zig version.&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">zigDerivation&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="n">version&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nb">hash&lt;/span> &lt;span class="p">}&lt;/span> &lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">pkgs&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">stdenv&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">mkDerivation&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">pname&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;zig&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">version&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">version&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">src&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pkgs&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">fetchurl&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">url&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;https://ziglang.org/download/${version}/zig-linux-x86_64-${version}.tar.xz&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">sha256&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">hash&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">buildPhase&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">mkdir&lt;/span> &lt;span class="o">-&lt;/span>&lt;span class="n">p&lt;/span> &lt;span class="o">$&lt;/span>&lt;span class="n">out&lt;/span>&lt;span class="o">/&lt;/span>&lt;span class="n">bin&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cp&lt;/span> &lt;span class="o">./&lt;/span>&lt;span class="n">zig&lt;/span> &lt;span class="o">$&lt;/span>&lt;span class="n">out&lt;/span>&lt;span class="o">/&lt;/span>&lt;span class="n">bin&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="ow">in&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>After definig the inputs (the derivation, system and pkgs) we create the zig derivation for certain versions (0.13.0, 0.12.0)&lt;/li>
&lt;li>We create the shells for each version, using the packages built from the derivations&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl"> in
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> packages = {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> x86_64-linux.zig0130 = zigDerivation { version = &amp;#34;0.13.0&amp;#34;; hash = &amp;#34;1FMS5h68xIAyt3vEz3/WkVwR+hbkqtEWtmyUaCESMOo=&amp;#34;; };
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> x86_64-linux.zig0120 = zigDerivation { version = &amp;#34;0.12.0&amp;#34;; hash = &amp;#34;x66Ga4p2pWji1c/TH+ic22Kb3RYf3VAYsppKChcEXK0=&amp;#34;; };
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> };
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> devShells.x86_64-linux.default = pkgs.mkShell {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> buildInputs = [ self.packages.${system}.zig0130 ];
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> };
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> devShells.x86_64-linux.zig0130 = pkgs.mkShell {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> buildInputs = [ self.packages.${system}.zig0130 ];
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> };
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> devShells.x86_64-linux.zig0120 = pkgs.mkShell {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> buildInputs = [ self.packages.${system}.zig0120 ];
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> };
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> };
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>And finally, to run the dev shell within the flake:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">// example: nix develop &amp;lt;path-to-flake-folder&amp;gt;/#&amp;lt;shell-name&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">nix develop ./zig-flake/#zig0130
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>A &lt;code>flake.lock&lt;/code> file will be generated after running the flake:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">{
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;#34;nodes&amp;#34;: {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;#34;nixpkgs&amp;#34;: {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;#34;locked&amp;#34;: {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;#34;lastModified&amp;#34;: 1722185531,
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;#34;narHash&amp;#34;: &amp;#34;sha256-veKR07psFoJjINLC8RK4DiLniGGMgF3QMlS4tb74S6k=&amp;#34;,
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;#34;owner&amp;#34;: &amp;#34;NixOS&amp;#34;,
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;#34;repo&amp;#34;: &amp;#34;nixpkgs&amp;#34;,
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;#34;rev&amp;#34;: &amp;#34;52ec9ac3b12395ad677e8b62106f0b98c1f8569d&amp;#34;,
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;#34;type&amp;#34;: &amp;#34;github&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> },
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;#34;original&amp;#34;: {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;#34;owner&amp;#34;: &amp;#34;NixOS&amp;#34;,
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;#34;ref&amp;#34;: &amp;#34;nixos-unstable&amp;#34;,
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;#34;repo&amp;#34;: &amp;#34;nixpkgs&amp;#34;,
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;#34;type&amp;#34;: &amp;#34;github&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> }
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> },
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;#34;root&amp;#34;: {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;#34;inputs&amp;#34;: {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;#34;nixpkgs&amp;#34;: &amp;#34;nixpkgs&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> }
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> }
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> },
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;#34;root&amp;#34;: &amp;#34;root&amp;#34;,
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;#34;version&amp;#34;: 7
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="summary">Summary&lt;/h2>
&lt;p>Flakes solve a reproducibility issue in nix shells by pinning the upstream nixpkg
version, allowing different engineers to run the same flake and ensure they have
the exact same dependencies.&lt;/p>
&lt;h2 id="did-you-find-this-page-helpful-consider-sharing-it-">Did you find this page helpful? Consider sharing it 🙌&lt;/h2></description></item><item><title>Nix 101: Part 2</title><link>https://www.christophercoverdale.com/blog/nix-101-part-2/</link><pubDate>Tue, 30 Jul 2024 00:00:00 +0000</pubDate><guid>https://www.christophercoverdale.com/blog/nix-101-part-2/</guid><description>&lt;p>The second part of Nix 101 will use the language features described in Part 1,
and create a real life use case.&lt;/p>
&lt;h2 id="creating-a-zig-package">Creating a Zig package&lt;/h2>
&lt;p>In this example, we are going to create a derivation of the Zig language.&lt;/p>
&lt;p>Specifically, we want to be able to build a derivation where a certain version
of Zig can be built e.g. &amp;ldquo;Give me Zig 0.13.0&amp;rdquo;.&lt;/p>
&lt;h3 id="derivation">Derivation&lt;/h3>
&lt;p>First lets define a derivation.&lt;/p>
&lt;p>A derivation is a Nix file that represents the build process of software.&lt;/p>
&lt;p>A derivation is a Nix expression that declares the dependencies and required build steps
to compile/build the sofware.&lt;/p>
&lt;p>The process is reproducible meaning, the same inputs always evaluate to the same outputs.
The Nix derivation can also be used as an import in shells or other derivations as a dependency.&lt;/p>
&lt;h3 id="shells">Shells&lt;/h3>
&lt;p>Nix Shells are reproducible environments.&lt;/p>
&lt;p>This means that we can use the Nix Language to declaretively express the dependencies of a shell and any required hooks in a reproducible manner.&lt;/p>
&lt;p>The shell should evaluate to the same output given the same declared input.&lt;/p>
&lt;p>These shells can also be isolated from the underlying environment, creating a pure development environment.&lt;/p>
&lt;h2 id="creating-the-derivation">Creating the Derivation&lt;/h2>
&lt;p>We are going to create an example derivation of the Zig language.&lt;/p>
&lt;p>First we are going to start with getting Zig version 0.13.0.&lt;/p>
&lt;p>This derivation is in a file named &lt;code>zig.nix&lt;/code>.&lt;/p>
&lt;p>We import &lt;code>stdenv&lt;/code> to be able to call &lt;code>mkDerivation&lt;/code> to create the derivation.&lt;/p>
&lt;p>&lt;code>fetchurl&lt;/code> will download the binary and note the hash &lt;code>sha256&lt;/code>. This is the hash of
the binary. This is important since it provides a reproducible step, if the downloadable content were to change
upstream, we can tell that it wouldn&amp;rsquo;t evaluate to the same hash. This could be due to a malicious
upstream change to the software or an accidental one, either way, this protects our derivation
and subsequent use of this package as a dependency.&lt;/p>
&lt;p>Note the &lt;code>buildPhase&lt;/code>. This is a hook in the derivation, and we are saying at this phase,
make a directory at &lt;code>$out/bin&lt;/code> and copy the downloaded binary to that path.&lt;/p>
&lt;p>&lt;code>$out&lt;/code> is a Nix environment variable for the designated output path for the result of the output build.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nix" data-lang="nix">&lt;span class="line">&lt;span class="cl">&lt;span class="n">zig&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">nix&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span> &lt;span class="n">stdenv&lt;/span>&lt;span class="o">,&lt;/span> &lt;span class="n">fetchurl&lt;/span>&lt;span class="o">,&lt;/span> &lt;span class="p">}:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">stdenv&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">mkDerivation&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">pname&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;zig&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">version&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;0.13.0&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">src&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">fetchurl&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">url&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;https://ziglang.org/download/0.13.0/zig-linux-x86_64-0.13.0.tar.xz&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">sha256&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;1FMS5h68xIAyt3vEz3/WkVwR+hbkqtEWtmyUaCESMOo=&amp;#34;&amp;#34;;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> };
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> buildPhase = &amp;#39;&amp;#39;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> mkdir -p $out/bin
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> cp ./zig $out/bin
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2"> &amp;#39;&amp;#39;;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">}
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>We can build this derivation &lt;code>nix-build ./zig.nix&lt;/code> and this will build or derivation with
a resulting output for Zig 0.13.0.&lt;/p>
&lt;p>But let&amp;rsquo;s say we wanted the option to request different versions of Zig. We can achieve
this by passing args to our a derivation.&lt;/p>
&lt;p>Let&amp;rsquo;s create a new nix file, &lt;code>default.nix&lt;/code>.&lt;/p>
&lt;p>&lt;code>default.nix&lt;/code> will allow us to paramertize the build when calling the derivation.&lt;/p>
&lt;p>We&amp;rsquo;re going to pass x2 args:&lt;/p>
&lt;ul>
&lt;li>&lt;code>zigVersion&lt;/code>&lt;/li>
&lt;li>&lt;code>zigHash&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>This will allow us to set the zigVersion we want and it&amp;rsquo;s corresponding hash.&lt;/p>
&lt;p>Notice that we call the package with different versions and hashes. We then
assign the evaluated result to a named variable: &lt;code>zig0130&lt;/code> and &lt;code>zig0120&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nix" data-lang="nix">&lt;span class="line">&lt;span class="cl">&lt;span class="n">default&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">nix&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">let&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">nixpkgs&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">fetchTarball&lt;/span> &lt;span class="s2">&amp;#34;https://github.com/NixOS/nixpkgs/tarball/nixos-24.05&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">pkgs&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">nixpkgs&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="n">config&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{};&lt;/span> &lt;span class="n">overlays&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[];&lt;/span> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">in&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">zig0130&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pkgs&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">callPackage&lt;/span> &lt;span class="sr">./zig.nix&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="n">zigVersion&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;0.13.0&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">zigHash&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;1FMS5h68xIAyt3vEz3/WkVwR+hbkqtEWtmyUaCESMOo=&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">zig0120&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pkgs&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">callPackage&lt;/span> &lt;span class="sr">./zig.nix&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="n">zigVersion&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;0.12.0&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">zigHash&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;x66Ga4p2pWji1c/TH+ic22Kb3RYf3VAYsppKChcEXK0=&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>We&amp;rsquo;ll update the &lt;code>zig.nix&lt;/code> derivation file to accept the args as variables.&lt;/p>
&lt;p>The derivation can now use and build according to the passed zigVersion and corresponding zigHash.&lt;/p>
&lt;p>We can also specify which version we want to build: &lt;code>nix-build -A zig0120&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nix" data-lang="nix">&lt;span class="line">&lt;span class="cl">&lt;span class="n">zig&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">nix&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span> &lt;span class="n">stdenv&lt;/span>&lt;span class="o">,&lt;/span> &lt;span class="n">fetchurl&lt;/span>&lt;span class="o">,&lt;/span> &lt;span class="n">zigVersion&lt;/span>&lt;span class="o">,&lt;/span> &lt;span class="n">zigHash&lt;/span> &lt;span class="p">}:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">stdenv&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">mkDerivation&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">pname&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;zig&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">version&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">zigVersion&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">src&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">fetchurl&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">url&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;https://ziglang.org/download/&lt;/span>&lt;span class="si">${&lt;/span>&lt;span class="n">zigVersion&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">/zig-linux-x86_64-&lt;/span>&lt;span class="si">${&lt;/span>&lt;span class="n">zigVersion&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">.tar.xz&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">sha256&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">zigHash&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">buildPhase&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;&amp;#39;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> mkdir -p $out/bin
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> cp ./zig $out/bin
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> &amp;#39;&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>We can take this another step further by creating a development shell environment where
we can use the local derivation: &lt;code>nix-shell --argstr zigVersion &amp;quot;0.13.0&amp;quot;&lt;/code>&lt;/p>
&lt;p>We can import the local derivation using &lt;code>import ./default.nix&lt;/code> and then call
the named variable in the evaluated attribute. This will grab the built version
we require as a dependency.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">shell.nix
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{ pkgs ? import &amp;lt;nixpkgs&amp;gt; {},
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> zigVersion ? &amp;#34;0.13.0&amp;#34;,
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">}:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">let
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> customPackages = import ./default.nix;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> selectedZig = if zigVersion == &amp;#34;0.13.0&amp;#34; then
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> customPackages.zig0130
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> else if zigVersion == &amp;#34;0.12.0&amp;#34; then
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> customPackages.zig0120
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> else
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> customPackages.zig0130;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">in
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> pkgs.mkShell {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> buildInputs = [ selectedZig ];
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> shellHooks = &amp;#39;&amp;#39;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> echo &amp;#34;Running Zig shell with version: ${zigVersion}&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;#39;&amp;#39;;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="summary">Summary&lt;/h2>
&lt;p>Nix allows us to declaretively create expressions that evaluate to reproducible
build packages and development environments.&lt;/p>
&lt;h2 id="did-you-find-this-page-helpful-consider-sharing-it-">Did you find this page helpful? Consider sharing it 🙌&lt;/h2></description></item><item><title>Nix 101: Part 1</title><link>https://www.christophercoverdale.com/blog/nix-101-part-1/</link><pubDate>Mon, 29 Jul 2024 00:00:00 +0000</pubDate><guid>https://www.christophercoverdale.com/blog/nix-101-part-1/</guid><description>&lt;p>This post goes over the basics of the Nix Language and in later posts will cover
the applications of Nix.&lt;/p>
&lt;h2 id="what-is-nix">What is Nix?&lt;/h2>
&lt;p>Nix is a system to create reproducible builds and shell environments. Nix has a purely functional language to express
the building of reproducible shell environments.&lt;/p>
&lt;p>This post will go over the basics of the language.&lt;/p>
&lt;h2 id="variables">Variables&lt;/h2>
&lt;p>Nix has basic variables found in most high level languages.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nix" data-lang="nix">&lt;span class="line">&lt;span class="cl">&lt;span class="n">string&lt;/span> &lt;span class="err">=&lt;/span> &lt;span class="s2">&amp;#34;Hello, World!&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">integer&lt;/span> &lt;span class="err">=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">bool&lt;/span> &lt;span class="err">=&lt;/span> &lt;span class="no">true&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">list&lt;/span> &lt;span class="err">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">1&lt;/span> &lt;span class="mi">2&lt;/span> &lt;span class="mi">3&lt;/span>&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="variables---letin">Variables - let..in..&lt;/h2>
&lt;p>Variables can be defined using the &lt;code>let ... in ...&lt;/code> syntax.&lt;/p>
&lt;p>The variables are defined in the &lt;code>let&lt;/code> scope and then used for evaluation in the &lt;code>in&lt;/code> scope.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nix" data-lang="nix">&lt;span class="line">&lt;span class="cl">&lt;span class="k">let&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">x&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">y&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">in&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">x&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">y&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">&amp;gt;&amp;gt;&lt;/span> &lt;span class="mi">3&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="strings">Strings&lt;/h2>
&lt;p>String interpolation is achieved using &lt;code>${variable}&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nix" data-lang="nix">&lt;span class="line">&lt;span class="cl">&lt;span class="k">let&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">name&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;Foo&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">in&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;hello &lt;/span>&lt;span class="si">${&lt;/span>&lt;span class="n">name&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="lists">Lists&lt;/h2>
&lt;p>Lists can be declared using &lt;code>[]&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nix" data-lang="nix">&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="mi">1&lt;/span> &lt;span class="mi">2&lt;/span> &lt;span class="mi">3&lt;/span>&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="attributes">Attributes&lt;/h2>
&lt;p>Attributes are a datastructure, similar to JSON. They are defined using &lt;code>{}&lt;/code> and
have named key values.&lt;/p>
&lt;p>The values can be accessed using dot notation to refer to a key name.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nix" data-lang="nix">&lt;span class="line">&lt;span class="cl">&lt;span class="k">let&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">attributes&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="n">x&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">y&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">in&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">attributes&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">x&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">attributes&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">y&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">&amp;gt;&amp;gt;&lt;/span> &lt;span class="mi">3&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="recursive-attributes">Recursive Attributes&lt;/h3>
&lt;p>Recursive Attributes allows the variables within a scope to be referenced using
the &lt;code>rec&lt;/code> keyword.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">rec {
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> one = 1;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> two = one + 1;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> three = two + 1;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="with">With&lt;/h3>
&lt;p>Atrributes can be accessed more easily using the &lt;code>with&lt;/code> keyword.&lt;/p>
&lt;p>&lt;code>with&lt;/code> allows access to the attirbutes values without needing to use dot notation.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nix" data-lang="nix">&lt;span class="line">&lt;span class="cl">&lt;span class="k">let&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">a&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">x&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">y&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">z&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">3&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">in&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">with&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="n">x&lt;/span> &lt;span class="n">y&lt;/span> &lt;span class="n">z&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="functions">Functions&lt;/h2>
&lt;p>Functions in Nix are lambda functions with a &lt;code>:&lt;/code> separating arguments from the function body.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nix" data-lang="nix">&lt;span class="line">&lt;span class="cl">&lt;span class="n">x&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">x&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">1&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Attribute sets can be used as arguments.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nix" data-lang="nix">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="o">,&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">}:&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">b&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Default/optional arguments can be provided using &lt;code>?&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nix" data-lang="nix">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="o">,&lt;/span> &lt;span class="n">b&lt;/span> &lt;span class="o">?&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">}:&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">b&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Named arguments can be given using the &lt;code>@&lt;/code> symbol.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nix" data-lang="nix">&lt;span class="line">&lt;span class="cl">&lt;span class="n">args&lt;/span>&lt;span class="o">@&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="o">,&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="o">,&lt;/span> &lt;span class="o">...&lt;/span>&lt;span class="p">}:&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">b&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">args&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">c&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Using let..in.., we can define a function and then call it.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nix" data-lang="nix">&lt;span class="line">&lt;span class="cl">&lt;span class="k">let&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">f&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">x&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">in&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">f&lt;/span> &lt;span class="mi">1&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>We can also pass an attribute set as an argument, which seems to be a common
pattern in Nix.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nix" data-lang="nix">&lt;span class="line">&lt;span class="cl">&lt;span class="k">let&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">f&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">a&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">in&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">f&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>We can also declare functions and variables in the let scope and then apply them.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nix" data-lang="nix">&lt;span class="line">&lt;span class="cl">&lt;span class="k">let&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">f&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">a&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">v&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">in&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">f&lt;/span> &lt;span class="n">v&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Functions can also be immediately callable by wrapping it around &lt;code>()&lt;/code>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nix" data-lang="nix">&lt;span class="line">&lt;span class="cl">&lt;span class="p">(&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">x&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="mi">1&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Functions can be passed to list and have the function evaluated and the result stored in the list.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nix" data-lang="nix">&lt;span class="line">&lt;span class="cl">&lt;span class="k">let&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">f&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">x&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">a&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">in&lt;/span> &lt;span class="p">[&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">f&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Functions can also be passed with out being evaluated along side the arguments.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nix" data-lang="nix">&lt;span class="line">&lt;span class="cl">&lt;span class="k">let&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">f&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">x&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">a&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">in&lt;/span> &lt;span class="p">[&lt;/span> &lt;span class="n">f&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Single attribute sets with multiple values can be used as the argument, as mentioned earlier,
this is a common pattern.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nix" data-lang="nix">&lt;span class="line">&lt;span class="cl">&lt;span class="k">let&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">f&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="o">,&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">}:&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">b&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">in&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">f&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">b&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="inherit">Inherit&lt;/h2>
&lt;p>This keyword is shorthand for assigning variables from the previous scope into the new scope.&lt;/p>
&lt;p>The below is the equivalent of:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nix" data-lang="nix">&lt;span class="line">&lt;span class="cl">&lt;span class="n">x&lt;/span> &lt;span class="err">=&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">y&lt;/span> &lt;span class="err">=&lt;/span> &lt;span class="n">a&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">y&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nix" data-lang="nix">&lt;span class="line">&lt;span class="cl">&lt;span class="k">let&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">a&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="n">x&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="n">y&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">;&lt;/span> &lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">in&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">inherit&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="n">x&lt;/span> &lt;span class="n">y&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="summary">Summary&lt;/h2>
&lt;p>Nix is a reproducible build system for shells and environments. Nix uses a functional
programming language to express and evaluate reproducible builds.&lt;/p>
&lt;h2 id="did-you-find-this-page-helpful-consider-sharing-it-">Did you find this page helpful? Consider sharing it 🙌&lt;/h2></description></item></channel></rss>