<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: domagoj miskovic</title>
    <description>The latest articles on Forem by domagoj miskovic (@stablejoy).</description>
    <link>https://forem.com/stablejoy</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F361211%2F3604d1e0-fab8-4cf4-8ec3-8aed129ebf05.jpeg</url>
      <title>Forem: domagoj miskovic</title>
      <link>https://forem.com/stablejoy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/stablejoy"/>
    <language>en</language>
    <item>
      <title>Flake My Life 3 - a snowstorm of errors!</title>
      <dc:creator>domagoj miskovic</dc:creator>
      <pubDate>Thu, 20 Apr 2023 11:47:30 +0000</pubDate>
      <link>https://forem.com/stablejoy/flake-my-life-3-a-snowstorm-of-errors-21b3</link>
      <guid>https://forem.com/stablejoy/flake-my-life-3-a-snowstorm-of-errors-21b3</guid>
      <description>&lt;p&gt;In my last post, I discussed mapping functions from the &lt;code&gt;builtins&lt;/code&gt; and &lt;code&gt;lib&lt;/code&gt; in the minimal template &lt;code&gt;flake.nix&lt;/code&gt;. Now, let's finish configuring NixOS as a flake.&lt;/p&gt;

&lt;h3&gt;
  
  
  Initializing the directory with git
&lt;/h3&gt;

&lt;p&gt;I initialized the directory using &lt;code&gt;git init nix-config&lt;/code&gt; and loaded it into Vscode. After making necessary changes to &lt;code&gt;flake.nix&lt;/code&gt;, I copied extra configuration parts from my &lt;code&gt;configuration.nix&lt;/code&gt;. I won't modify &lt;code&gt;home.nix&lt;/code&gt; for now and will keep the programs declared in &lt;code&gt;configuration.nix&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resolving git issues
&lt;/h3&gt;

&lt;p&gt;I messed up something while uploading the directory to git through Vscode, so I deleted the .git directory and tried initializing it again. Not the elegant solution yeah.&lt;/p&gt;

&lt;p&gt;I found a helpful tutorial by Tweag on understanding Git concepts &lt;a href="https://youtu.be/ANNboouhNHE"&gt;here&lt;/a&gt;. After committing my changes and creating a repository on GitHub, I tried to apply the flake configuration without uploading the directory, but it didn't work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Debugging flake rebuild failure
&lt;/h3&gt;

&lt;p&gt;I got an error when running &lt;code&gt;sudo nixos-rebuild switch --flake .#nixos&lt;/code&gt;. I tried changing the input section of my &lt;code&gt;flake.nix&lt;/code&gt; to reference &lt;code&gt;nixos-unstable&lt;/code&gt; and even removed the unstable option, but still faced errors.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="err"&gt;❯&lt;/span&gt; &lt;span class="nv"&gt;sudo&lt;/span&gt; &lt;span class="nv"&gt;nixos-rebuild&lt;/span&gt; &lt;span class="nv"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nv"&gt;flake&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="c"&gt;#nixos&lt;/span&gt;
&lt;span class="nv"&gt;warning&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;updating&lt;/span&gt; &lt;span class="nv"&gt;lock&lt;/span&gt; &lt;span class="nv"&gt;file&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="sx"&gt;/home/stablejoy/nix-config/flake.lock&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="err"&gt;•&lt;/span&gt; &lt;span class="nv"&gt;Updated&lt;/span&gt; &lt;span class="nv"&gt;input&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nv"&gt;github&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="sx"&gt;nixos/nixpkgs/0cf4274b5d06325bd16dbf879a30981bc283e58a&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2023&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;02&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nv"&gt;github&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="sx"&gt;nixos/nixpkgs/bb2009ca185d97813e75736c2b8d1d8bb81bde05&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2023&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;warning&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;Git&lt;/span&gt; &lt;span class="nv"&gt;tree&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="sx"&gt;/home/stablejoy/nix-config&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="nv"&gt;is&lt;/span&gt; &lt;span class="nv"&gt;dirty&lt;/span&gt;
&lt;span class="nv"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;attribute&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;allowUnfree&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="nv"&gt;already&lt;/span&gt; &lt;span class="nv"&gt;defined&lt;/span&gt; &lt;span class="nv"&gt;at&lt;/span&gt; &lt;span class="sx"&gt;/nix/store/8ji8d4jrs8w8p59x39j3krq3kmay8h85-source/nixos/configuration.nix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;34&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;

&lt;span class="nv"&gt;at&lt;/span&gt; &lt;span class="sx"&gt;/nix/store/8ji8d4jrs8w8p59x39j3krq3kmay8h85-source/nixos/configuration.nix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;137&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

          &lt;span class="mi"&gt;136&lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;   &lt;span class="c"&gt;# Allow unfree packages&lt;/span&gt;
          &lt;span class="mi"&gt;137&lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;   &lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;allowUnfree&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
             &lt;span class="err"&gt;|&lt;/span&gt;   &lt;span class="err"&gt;^&lt;/span&gt;
          &lt;span class="mi"&gt;138&lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;use&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nv"&gt;show-trace&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="nv"&gt;to&lt;/span&gt; &lt;span class="nv"&gt;show&lt;/span&gt; &lt;span class="nv"&gt;detailed&lt;/span&gt; &lt;span class="nv"&gt;location&lt;/span&gt; &lt;span class="nv"&gt;information&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OK, so I removed the double entry and tried again the flake build command and.. it works! But something looks odd. Why is it downloading so much? I thought a flake kind of transforms the system into a flake. What is happening? I guess since I haven't updated my NixOS system in more than couple days already it is downloading the new versions of dependencies and packages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe1wanb3wdck2w9in4k6q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe1wanb3wdck2w9in4k6q.png" alt="flake download" width="800" height="150"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After 14 minutes I get this output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;nix-config&lt;/span&gt; &lt;span class="nv"&gt;on&lt;/span&gt; &lt;span class="err"&gt;&lt;/span&gt; &lt;span class="nv"&gt;master&lt;/span&gt; 
&lt;span class="err"&gt;❯&lt;/span&gt; &lt;span class="nv"&gt;sudo&lt;/span&gt; &lt;span class="nv"&gt;nixos-rebuild&lt;/span&gt; &lt;span class="nv"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nv"&gt;flake&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="c"&gt;#nixos&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;sudo&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nv"&gt;password&lt;/span&gt; &lt;span class="nv"&gt;for&lt;/span&gt; &lt;span class="nv"&gt;stablejoy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
&lt;span class="nv"&gt;building&lt;/span&gt; &lt;span class="nv"&gt;the&lt;/span&gt; &lt;span class="nv"&gt;system&lt;/span&gt; &lt;span class="nv"&gt;configuration&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="nv"&gt;activating&lt;/span&gt; &lt;span class="nv"&gt;the&lt;/span&gt; &lt;span class="nv"&gt;configuration&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="nv"&gt;setting&lt;/span&gt; &lt;span class="nv"&gt;up&lt;/span&gt; &lt;span class="sx"&gt;/etc...&lt;/span&gt;
&lt;span class="nv"&gt;restarting&lt;/span&gt; &lt;span class="nv"&gt;systemd&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="nv"&gt;the&lt;/span&gt; &lt;span class="nv"&gt;following&lt;/span&gt; &lt;span class="nv"&gt;new&lt;/span&gt; &lt;span class="nv"&gt;units&lt;/span&gt; &lt;span class="nv"&gt;were&lt;/span&gt; &lt;span class="nv"&gt;started&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;NetworkManager-dispatcher&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;service&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;run-credentials-systemd&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nv"&gt;x2dvconsole&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nv"&gt;x2dsetup&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;service&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;systemd-hostnamed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;service&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;systemd-vconsole-setup&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;service&lt;/span&gt;

&lt;span class="nv"&gt;nix-config&lt;/span&gt; &lt;span class="nv"&gt;on&lt;/span&gt; &lt;span class="err"&gt;&lt;/span&gt; &lt;span class="nv"&gt;master&lt;/span&gt; &lt;span class="nv"&gt;took&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="nv"&gt;m46s&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Is this it? I copy paste the output to GPT4 wishing for someone to just say yes, you did it. You got yourself a flake.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Congratulations! It seems like your NixOS rebuild has succeeded this time. The output you provided shows that the system configuration was built, and various services were stopped, changed, restarted, or started as needed. Now that you have successfully applied the flake configuration, you can continue to make changes to your NixOS setup and rebuild as necessary.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So how do we now update the system? I don't think I can use the &lt;code&gt;sudo nixos-rebulid switch&lt;/code&gt; command anymore.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's next now that we have a flake?
&lt;/h3&gt;

&lt;p&gt;So the &lt;code&gt;flake.lock&lt;/code&gt; is a generated file that records the exact versions of the flake inputs, like nixpkgs. When we update our flake enabled NixOS we will use &lt;code&gt;nix flake update&lt;/code&gt; which will update the &lt;code&gt;flake.lock&lt;/code&gt; to the latest available versions of the flake inputs. So the process goes like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;nix&lt;/span&gt; &lt;span class="nv"&gt;flake&lt;/span&gt; &lt;span class="nv"&gt;update&lt;/span&gt;
&lt;span class="nv"&gt;sudo&lt;/span&gt; &lt;span class="nv"&gt;nixos-rebuild&lt;/span&gt; &lt;span class="nv"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nv"&gt;flake&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="c"&gt;#hostname&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, the &lt;code&gt;#hostname&lt;/code&gt; should be changed to one's own &lt;code&gt;hostname&lt;/code&gt; (as declared in &lt;code&gt;configuration.nix&lt;/code&gt;) in case this looks confusing. Yes, Nix is declarative and functional so when I first saw this &lt;code&gt;#hostname&lt;/code&gt; I was thinking this is could be like &lt;code&gt;bultins.currentSystem&lt;/code&gt; which gets the current system version so maybe I don't have to write my own hostname, maybe the &lt;code&gt;#hostname&lt;/code&gt; picks up the system hostname. But this isn't the case apparently.&lt;/p&gt;

&lt;h3&gt;
  
  
  Let's add the Neovim flake
&lt;/h3&gt;

&lt;p&gt;I'd like to add this &lt;a href="https://github.com/jordanisaacs/neovim-flake"&gt;Neovim flake&lt;/a&gt; now to my flake-enabled NixOS. We can run the flake with &lt;code&gt;nix run github:jordanisaacs/neovim-flake&lt;/code&gt; but it won't stay in the system so how do we do we add it permanently? We need to add the neovim flake to our &lt;code&gt;inputs&lt;/code&gt; section in the &lt;code&gt;flake.nix&lt;/code&gt; as it says in the &lt;code&gt;TODO:&lt;/code&gt; part of the minimal &lt;code&gt;flake.nix&lt;/code&gt;. Let's do that! Our &lt;code&gt;inputs&lt;/code&gt; attribute set looks like this now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;inputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;# Nixpkgs&lt;/span&gt;
    &lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"github:nixos/nixpkgs"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c"&gt;# Use unstable channel instead of release&lt;/span&gt;

    &lt;span class="c"&gt;# Home manager&lt;/span&gt;
    &lt;span class="nv"&gt;home-manager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"github:nix-community/home-manager"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
    &lt;span class="nv"&gt;home-manager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;inputs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;follows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"nixpkgs"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

    &lt;span class="c"&gt;# TODO: Add any other flake you might need&lt;/span&gt;
    &lt;span class="c"&gt;# hardware.url = "github:nixos/nixos-hardware"; &lt;/span&gt;

    &lt;span class="c"&gt;# Shameless plug: looking for a way to nixify your themes and make&lt;/span&gt;
    &lt;span class="c"&gt;# everything match nicely? Try nix-colors!&lt;/span&gt;
    &lt;span class="c"&gt;# nix-colors.url = "github:misterio77/nix-colors";&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's add the neovim flake under the &lt;code&gt;hardware.url&lt;/code&gt; set:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="c"&gt;# TODO: Add any other flake you might need&lt;/span&gt;
    &lt;span class="c"&gt;# hardware.url = "github:nixos/nixos-hardware"; &lt;/span&gt;

    &lt;span class="nv"&gt;neovim-flake&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"github:jordanisaacs/neovim-flake"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nv"&gt;inputs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;follows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"nixpkgs"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I asked GPT what does the &lt;code&gt;inputs.nixpkgs.follows = "nixpkgs";&lt;/code&gt; mean in this context?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When you specify follows = "nixpkgs";, you tell the neovim-flake to use the same nixpkgs input as the one defined in your flake, rather than fetching its own version of nixpkgs. This can prevent potential issues that may arise if the neovim-flake were to use a different version of nixpkgs that is not compatible with the packages in your main flake.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;OK, that makes sense. I add the set and then write the file in Vscode. Vscode is then showing &lt;code&gt;1 pending changes&lt;/code&gt;, then with the &lt;code&gt;+&lt;/code&gt; sign in Vscode we stage the changes, and then commit the changes with a commit message: &lt;code&gt;adding the neovim flake into flake.nix so that it can be used as a flake input&lt;/code&gt; and &lt;code&gt;accept commit changes&lt;/code&gt; with that little check mark on the right, then sync changes with the big green button. &lt;/p&gt;

&lt;p&gt;OK, let's try to update our flake and see if this will be enough to have neovim flake on our system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;nix-config&lt;/span&gt; &lt;span class="nv"&gt;on&lt;/span&gt; &lt;span class="err"&gt;&lt;/span&gt; &lt;span class="nv"&gt;master&lt;/span&gt; 
&lt;span class="err"&gt;❯&lt;/span&gt; &lt;span class="nv"&gt;sudo&lt;/span&gt; &lt;span class="nv"&gt;nixos-rebuild&lt;/span&gt; &lt;span class="nv"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nv"&gt;flake&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="c"&gt;#nixos&lt;/span&gt;
&lt;span class="nv"&gt;building&lt;/span&gt; &lt;span class="nv"&gt;the&lt;/span&gt; &lt;span class="nv"&gt;system&lt;/span&gt; &lt;span class="nv"&gt;configuration&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="nv"&gt;stopping&lt;/span&gt; &lt;span class="nv"&gt;the&lt;/span&gt; &lt;span class="nv"&gt;following&lt;/span&gt; &lt;span class="nv"&gt;units&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;accounts-daemon&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;service&lt;/span&gt;
&lt;span class="nv"&gt;NOT&lt;/span&gt; &lt;span class="nv"&gt;restarting&lt;/span&gt; &lt;span class="nv"&gt;the&lt;/span&gt; &lt;span class="nv"&gt;following&lt;/span&gt; &lt;span class="nv"&gt;changed&lt;/span&gt; &lt;span class="nv"&gt;units&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;systemd-fsck&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="nv"&gt;dev-disk-by&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nv"&gt;x2duuid-7A19&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nv"&gt;x2d66BE&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;service&lt;/span&gt;
&lt;span class="nv"&gt;activating&lt;/span&gt; &lt;span class="nv"&gt;the&lt;/span&gt; &lt;span class="nv"&gt;configuration&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="nv"&gt;setting&lt;/span&gt; &lt;span class="nv"&gt;up&lt;/span&gt; &lt;span class="sx"&gt;/etc...&lt;/span&gt;
&lt;span class="nv"&gt;reloading&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt; &lt;span class="nv"&gt;units&lt;/span&gt; &lt;span class="nv"&gt;for&lt;/span&gt; &lt;span class="nv"&gt;stablejoy&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="nv"&gt;setting&lt;/span&gt; &lt;span class="nv"&gt;up&lt;/span&gt; &lt;span class="nv"&gt;tmpfiles&lt;/span&gt;
&lt;span class="nv"&gt;reloading&lt;/span&gt; &lt;span class="nv"&gt;the&lt;/span&gt; &lt;span class="nv"&gt;following&lt;/span&gt; &lt;span class="nv"&gt;units&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;dbus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;service&lt;/span&gt;
&lt;span class="nv"&gt;restarting&lt;/span&gt; &lt;span class="nv"&gt;the&lt;/span&gt; &lt;span class="nv"&gt;following&lt;/span&gt; &lt;span class="nv"&gt;units&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;polkit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;service&lt;/span&gt;
&lt;span class="nv"&gt;starting&lt;/span&gt; &lt;span class="nv"&gt;the&lt;/span&gt; &lt;span class="nv"&gt;following&lt;/span&gt; &lt;span class="nv"&gt;units&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;accounts-daemon&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;service&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great! It looks like it worked. If I try to run &lt;code&gt;neovim&lt;/code&gt; or &lt;code&gt;nvim&lt;/code&gt; will it work?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;nix-config&lt;/span&gt; &lt;span class="nv"&gt;on&lt;/span&gt; &lt;span class="err"&gt;&lt;/span&gt; &lt;span class="nv"&gt;master&lt;/span&gt; &lt;span class="nv"&gt;took&lt;/span&gt; &lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="nv"&gt;s&lt;/span&gt; 
&lt;span class="err"&gt;❯&lt;/span&gt; &lt;span class="nv"&gt;nvim&lt;/span&gt;
&lt;span class="nv"&gt;The&lt;/span&gt; &lt;span class="nv"&gt;program&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nv"&gt;nvim&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="nv"&gt;is&lt;/span&gt; &lt;span class="nv"&gt;not&lt;/span&gt; &lt;span class="kn"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;your&lt;/span&gt; &lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;It&lt;/span&gt; &lt;span class="nv"&gt;is&lt;/span&gt; &lt;span class="nv"&gt;provided&lt;/span&gt; &lt;span class="nv"&gt;by&lt;/span&gt; &lt;span class="nv"&gt;several&lt;/span&gt; &lt;span class="nv"&gt;packages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="nv"&gt;You&lt;/span&gt; &lt;span class="nv"&gt;can&lt;/span&gt; &lt;span class="nv"&gt;make&lt;/span&gt; &lt;span class="nv"&gt;it&lt;/span&gt; &lt;span class="nv"&gt;available&lt;/span&gt; &lt;span class="kn"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;an&lt;/span&gt; &lt;span class="nv"&gt;ephemeral&lt;/span&gt; &lt;span class="nv"&gt;shell&lt;/span&gt; &lt;span class="nv"&gt;by&lt;/span&gt; &lt;span class="nv"&gt;typing&lt;/span&gt; &lt;span class="nv"&gt;one&lt;/span&gt; &lt;span class="nv"&gt;of&lt;/span&gt; &lt;span class="nv"&gt;the&lt;/span&gt; &lt;span class="nv"&gt;following&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nv"&gt;nix-shell&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;p&lt;/span&gt; &lt;span class="nv"&gt;neovim&lt;/span&gt;
  &lt;span class="nv"&gt;nix-shell&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;p&lt;/span&gt; &lt;span class="nv"&gt;neovim-unwrapped&lt;/span&gt;
  &lt;span class="nv"&gt;nix-shell&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;p&lt;/span&gt; &lt;span class="nv"&gt;vimPlugins&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;vim-elixir&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nope! Oh! I didn't add the neovim-flake to my outputs section of the &lt;code&gt;flake.nix&lt;/code&gt;. But after adding it I get an error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;syntax&lt;/span&gt; &lt;span class="nv"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;unexpected&lt;/span&gt; &lt;span class="nv"&gt;ELLIPSIS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;expecting&lt;/span&gt; &lt;span class="err"&gt;'}'&lt;/span&gt;

       &lt;span class="nv"&gt;at&lt;/span&gt; &lt;span class="sx"&gt;/nix/store/1wri85b2fy8f0512pd4gg4dqx3mgjddb-source/flake.nix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;51&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

           &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;
           &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;   &lt;span class="nv"&gt;outputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;home-manager&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;neovim-flake&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="nv"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="err"&gt;|&lt;/span&gt;                                                   &lt;span class="err"&gt;^&lt;/span&gt;
           &lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;     &lt;span class="c"&gt;# NixOS configuration entrypoint&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I forgot to add the comma &lt;code&gt;,&lt;/code&gt; after the neovim-flake but it would be nice if the error message explained that. &lt;/p&gt;

&lt;p&gt;Let's try again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;nix-config&lt;/span&gt; &lt;span class="nv"&gt;on&lt;/span&gt; &lt;span class="err"&gt;&lt;/span&gt; &lt;span class="nv"&gt;master&lt;/span&gt; &lt;span class="nv"&gt;took&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="nv"&gt;s&lt;/span&gt; 
&lt;span class="err"&gt;❯&lt;/span&gt; &lt;span class="nv"&gt;sudo&lt;/span&gt; &lt;span class="nv"&gt;nixos-rebuild&lt;/span&gt; &lt;span class="nv"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nv"&gt;flake&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="c"&gt;#nixos&lt;/span&gt;
&lt;span class="nv"&gt;building&lt;/span&gt; &lt;span class="nv"&gt;the&lt;/span&gt; &lt;span class="nv"&gt;system&lt;/span&gt; &lt;span class="nv"&gt;configuration&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="nv"&gt;activating&lt;/span&gt; &lt;span class="nv"&gt;the&lt;/span&gt; &lt;span class="nv"&gt;configuration&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="nv"&gt;setting&lt;/span&gt; &lt;span class="nv"&gt;up&lt;/span&gt; &lt;span class="sx"&gt;/etc...&lt;/span&gt;
&lt;span class="nv"&gt;reloading&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt; &lt;span class="nv"&gt;units&lt;/span&gt; &lt;span class="nv"&gt;for&lt;/span&gt; &lt;span class="nv"&gt;stablejoy&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="nv"&gt;setting&lt;/span&gt; &lt;span class="nv"&gt;up&lt;/span&gt; &lt;span class="nv"&gt;tmpfiles&lt;/span&gt;

&lt;span class="nv"&gt;nix-config&lt;/span&gt; &lt;span class="nv"&gt;on&lt;/span&gt; &lt;span class="err"&gt;&lt;/span&gt; &lt;span class="nv"&gt;master&lt;/span&gt; &lt;span class="nv"&gt;took&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="nv"&gt;s&lt;/span&gt; 
&lt;span class="err"&gt;❯&lt;/span&gt; &lt;span class="nv"&gt;nvim&lt;/span&gt;
&lt;span class="nv"&gt;The&lt;/span&gt; &lt;span class="nv"&gt;program&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nv"&gt;nvim&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="nv"&gt;is&lt;/span&gt; &lt;span class="nv"&gt;not&lt;/span&gt; &lt;span class="kn"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;your&lt;/span&gt; &lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;It&lt;/span&gt; &lt;span class="nv"&gt;is&lt;/span&gt; &lt;span class="nv"&gt;provided&lt;/span&gt; &lt;span class="nv"&gt;by&lt;/span&gt; &lt;span class="nv"&gt;several&lt;/span&gt; &lt;span class="nv"&gt;packages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nope! So I ask GPT what's the problem and paste in the code and we get an answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In your &lt;code&gt;flake.nix&lt;/code&gt; file, locate the part where you define your system configuration, and add &lt;code&gt;neovim-flake.defaultPackage.${system}&lt;/code&gt; to the list of system packages.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now why do we need to do that? Why do I need to edit two files instead of simply declaring the neovim-flake into the &lt;code&gt;inputs&lt;/code&gt;. If we look at the &lt;code&gt;outputs&lt;/code&gt; in the &lt;code&gt;flake.nix&lt;/code&gt; we can see that the outputs picks up the &lt;code&gt;configuration.nix&lt;/code&gt; from our system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="nv"&gt;outputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;home-manager&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;neovim-flake&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="nv"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;# NixOS configuration entrypoint&lt;/span&gt;
    &lt;span class="c"&gt;# Available through 'nixos-rebuild --flake .#your-hostname'&lt;/span&gt;
    &lt;span class="nv"&gt;nixosConfigurations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c"&gt;# FIXME replace with your hostname&lt;/span&gt;
      &lt;span class="nv"&gt;nixos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;nixosSystem&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;specialArgs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kn"&gt;inherit&lt;/span&gt; &lt;span class="nv"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c"&gt;# Pass flake inputs to our config&lt;/span&gt;
        &lt;span class="c"&gt;# &amp;gt; Our main nixos configuration file &amp;lt;&lt;/span&gt;
        &lt;span class="nv"&gt;modules&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="sx"&gt;./nixos/configuration.nix&lt;/span&gt; &lt;span class="p"&gt;];&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's add the &lt;code&gt;neovim-flake.defaultPackage.${system}&lt;/code&gt; into our &lt;code&gt;configuration.nix&lt;/code&gt;list of packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;environment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;systemPackages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kn"&gt;with&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="c"&gt;# ...&lt;/span&gt;
    &lt;span class="nv"&gt;neovim-flake&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;defaultPackage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;system&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="c"&gt;# ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nope! After trying to rebuild it we get again: &lt;code&gt;error: undefined variable neovim-flake&lt;/code&gt; so GPT was kinda wrong about this. Let's investigate this issue again in the &lt;code&gt;configuration.nix&lt;/code&gt;. Hmm I still don't understand why would I declare the &lt;code&gt;neovim-flake&lt;/code&gt; into my &lt;code&gt;configuration.nix&lt;/code&gt; when this line in &lt;code&gt;flake.nix&lt;/code&gt; says &lt;code&gt;specialArgs = { inherit inputs; }; # Pass flake inputs to our config&lt;/code&gt; so what's the issue here?&lt;/p&gt;

&lt;h3&gt;
  
  
  I forgot to update the flake
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1w9kachz78kew2f4076p.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1w9kachz78kew2f4076p.jpg" alt="facepalm" width="728" height="546"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I completely forgot to do the &lt;code&gt;nix flake update&lt;/code&gt; this whole time and only did the &lt;code&gt;sudo nixos-rebuild switch --flake .#hostname&lt;/code&gt;. What happens now when I run both commands?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="err"&gt;❯&lt;/span&gt; &lt;span class="nv"&gt;nix&lt;/span&gt; &lt;span class="nv"&gt;flake&lt;/span&gt; &lt;span class="nv"&gt;update&lt;/span&gt;
&lt;span class="nv"&gt;warning&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;updating&lt;/span&gt; &lt;span class="nv"&gt;lock&lt;/span&gt; &lt;span class="nv"&gt;file&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="sx"&gt;/home/stablejoy/nix-config/flake.lock&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="err"&gt;•&lt;/span&gt; &lt;span class="nv"&gt;Updated&lt;/span&gt; &lt;span class="nv"&gt;input&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nv"&gt;home-manager&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nv"&gt;github&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="sx"&gt;nix-community/home-manager/72ce74d3eae78a6b31538ea7ebe0c1fcf4a10f7a&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2023&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;02&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nv"&gt;github&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="sx"&gt;nix-community/home-manager/5160039edca28a7e66bad0cfc72a07c91d6768ad&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2023&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;•&lt;/span&gt; &lt;span class="nv"&gt;Removed&lt;/span&gt; &lt;span class="nv"&gt;input&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="sx"&gt;home-manager/utils&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;
&lt;span class="err"&gt;•&lt;/span&gt; &lt;span class="nv"&gt;Updated&lt;/span&gt; &lt;span class="nv"&gt;input&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nv"&gt;nixpkgs&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nv"&gt;github&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="sx"&gt;nixos/nixpkgs/bb2009ca185d97813e75736c2b8d1d8bb81bde05&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2023&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nv"&gt;github&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="sx"&gt;nixos/nixpkgs/ba0027bc70ae3294250cb662516b6571c3f406c9&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2023&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;37&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="nv"&gt;MiB&lt;/span&gt; &lt;span class="nv"&gt;DL&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nv"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;insufficient&lt;/span&gt; &lt;span class="nv"&gt;permission&lt;/span&gt; &lt;span class="nv"&gt;for&lt;/span&gt; &lt;span class="nv"&gt;adding&lt;/span&gt; &lt;span class="nv"&gt;an&lt;/span&gt; &lt;span class="nv"&gt;object&lt;/span&gt; &lt;span class="nv"&gt;to&lt;/span&gt; &lt;span class="nv"&gt;repository&lt;/span&gt; &lt;span class="nv"&gt;database&lt;/span&gt; &lt;span class="sx"&gt;.git/objects&lt;/span&gt;
&lt;span class="nv"&gt;fatal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;cannot&lt;/span&gt; &lt;span class="nv"&gt;create&lt;/span&gt; &lt;span class="nv"&gt;an&lt;/span&gt; &lt;span class="nv"&gt;empty&lt;/span&gt; &lt;span class="nv"&gt;blob&lt;/span&gt; &lt;span class="kn"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;the&lt;/span&gt; &lt;span class="nv"&gt;object&lt;/span&gt; &lt;span class="nv"&gt;database&lt;/span&gt;
&lt;span class="nv"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;program&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nv"&gt;git&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="nv"&gt;failed&lt;/span&gt; &lt;span class="kn"&gt;with&lt;/span&gt; &lt;span class="nv"&gt;exit&lt;/span&gt; &lt;span class="nv"&gt;code&lt;/span&gt; &lt;span class="mi"&gt;128&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;use&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nv"&gt;show-trace&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="nv"&gt;to&lt;/span&gt; &lt;span class="nv"&gt;show&lt;/span&gt; &lt;span class="nv"&gt;detailed&lt;/span&gt; &lt;span class="nv"&gt;location&lt;/span&gt; &lt;span class="nv"&gt;information&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great! Another error! Do I have to use &lt;code&gt;sudo&lt;/code&gt; with flakes? I thought not? &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;if you're updating a flake that is managed system-wide and owned by the root user (such as when using flakes for your NixOS system), you might need to use sudo to update the lock file. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After using the &lt;code&gt;sudo&lt;/code&gt; with &lt;code&gt;sudo nix flake update&lt;/code&gt; and trying the rebuild command now the system is fetching another gigabyte of packages. Why? It is fetching &lt;code&gt;llvm&lt;/code&gt; and &lt;code&gt;ark&lt;/code&gt; for example. Let's see what comes after this. The reason for this is probably that I forgot to even update the flake in the first place, I don't even remember now after all this error hunting. By watching the running output it seems it is rebuilding Plasma DE too and on top of that it is building something from source so it is taking some time now already. &lt;/p&gt;

&lt;p&gt;OK, it's been over an hour or so and it is still building the whole source of Plasma DE, currently at 61% build phase. I'm now really confused. I have enabled flakes but somehow I still do not understand flakes. Why isn't this using a binary cache, why is it building from source? On top of that it is building firefox from source which is a nightmare. I have to think what to do next and read more about flakes. I think I will stop the compilation process because it is only making my system slow at the moment. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fttxo8dbagj43vopu8bfg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fttxo8dbagj43vopu8bfg.png" alt="build phase" width="800" height="129"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nixos</category>
      <category>nix</category>
      <category>configuration</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Flake My Life - setting up a minimal flake on NixOS</title>
      <dc:creator>domagoj miskovic</dc:creator>
      <pubDate>Tue, 18 Apr 2023 14:33:51 +0000</pubDate>
      <link>https://forem.com/stablejoy/flake-my-life-setting-up-a-minimal-flake-on-nixos-1l18</link>
      <guid>https://forem.com/stablejoy/flake-my-life-setting-up-a-minimal-flake-on-nixos-1l18</guid>
      <description>&lt;p&gt;These days I have been exploring lambda calculus through Nix language which will be the theme of another blog post. I've been trying out &lt;code&gt;builtins&lt;/code&gt; commands with attribute sets, learning more about flakes, watching some great content on NixOS on YouTube, and playing with &lt;code&gt;nix repl&lt;/code&gt; and &lt;code&gt;nix-instantiate --eval&lt;/code&gt;. Overall, I think it's a great time to be learning Nix.&lt;/p&gt;

&lt;p&gt;However, I haven't transformed my NixOS configuration into a flake yet. This time, I refuse to simply copy and paste an advanced configuration like I did when I started with NixOS.&lt;/p&gt;

&lt;p&gt;The configs I managed to reproduce in the past were from: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://github.com/utdemir/dotfiles-nix" rel="noopener noreferrer"&gt;utdemir/dotfile-nix&lt;/a&gt; - Utdemir was a great help when I ran into issues with reproducing the config. Our conversation on &lt;a href="https://github.com/utdemir/dotfiles-nix/issues/29" rel="noopener noreferrer"&gt;GitHub issue #29&lt;/a&gt; was my first engagement on GitHub, and it was a such a positive and inspiring experience.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Your issue was really useful! Always good to know what's the pain points on a fresh install. To be honest, installing this repository from scratch likely won't be a click&amp;amp;forget experience, since I do not routinely test installing from scratch and using other machines other than mine. Let me know if I can help with anything (even if you're not using this repo).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://gvolpe.com/blog/xmonad-polybar-nixos/" rel="noopener noreferrer"&gt;gvolpe.com/blog/xmonad-polybar-nixos&lt;/a&gt; Reproducing this setup took me a couple of days, especially when dealing with the xmonad tiling window manager, which seemed very difficult to set up on NixOS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/Th0rgal/horus-nix-home" rel="noopener noreferrer"&gt;Th0rgal/horus-nix-home&lt;/a&gt; This config was another great learning experience with a visually appealing theme. The setup was simple enough, requiring only a few tweaks to the sub-modules.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Going all over again, this time with a basic minimal setup.
&lt;/h3&gt;

&lt;p&gt;Although I would love to use any of these three configurations again, I decided to take a more incremental approach. I wanted to find a minimal setup that I could build on with better understanding before attempting more advanced configurations. I discovered the &lt;a href="https://github.com/Misterio77/nix-starter-configs" rel="noopener noreferrer"&gt;NixOS-starter-config&lt;/a&gt; repository, which offers minimal and standard flake templates.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If this is your first trying flakes, or you're attempting to migrate your (simple) config to it; you should use the minimal version.&lt;/p&gt;

&lt;p&gt;If you're here looking for inspiration/tips/good practices (and you already use flakes), or you're migrating a config that already has overlays and custom packages; try the standard version.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;OK, let's try the minimal one for starters and then build on that. The goal is to transform an already installed basic NixOS system running the Plasma DE (so no complicated setups with tiling managers yet!) and then build on that.&lt;/p&gt;

&lt;p&gt;We are first instructed to create a git directory (because flakes by default work with git):&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;

&lt;span class="nv"&gt;cd&lt;/span&gt; &lt;span class="sx"&gt;~/Documents&lt;/span&gt; &lt;span class="c"&gt;# this can be anywhere basically&lt;/span&gt;
&lt;span class="nv"&gt;git&lt;/span&gt; &lt;span class="nv"&gt;init&lt;/span&gt; &lt;span class="nv"&gt;nix-config&lt;/span&gt;
&lt;span class="nv"&gt;cd&lt;/span&gt; &lt;span class="nv"&gt;nix-config&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;So now we have a &lt;code&gt;flake.nix&lt;/code&gt;, a &lt;code&gt;flake.lock&lt;/code&gt;, and two separate directories &lt;code&gt;home-manager&lt;/code&gt; and &lt;code&gt;nixos&lt;/code&gt;. So we can inspect now the files inside of these directories. I recommend not just simply copy pasting one's own &lt;code&gt;configuration.nix&lt;/code&gt; or &lt;code&gt;home.nix&lt;/code&gt; because the &lt;code&gt;configuration.nix&lt;/code&gt; in the &lt;code&gt;nixos&lt;/code&gt; folder is also a template. Yeah.. I see there are these &lt;code&gt;overlays&lt;/code&gt; and &lt;code&gt;overrides&lt;/code&gt; which I have no idea how they work. That's the next other thing I have to learn about. I do remember there is a NixCon 2019 or so, a talk by Graham about overrides and NixOS internals so that's for sure in the next 10 talks I plan to watch on Nix. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;

&lt;span class="nv"&gt;nix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;# This will add each flake input as a registry&lt;/span&gt;
    &lt;span class="c"&gt;# To make nix3 commands consistent with your flake&lt;/span&gt;
    &lt;span class="nv"&gt;registry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;mapAttrs&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;flake&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="nv"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c"&gt;# This will additionally add your inputs to the system's legacy channels&lt;/span&gt;
    &lt;span class="c"&gt;# Making legacy nix commands consistent as well, awesome!&lt;/span&gt;
    &lt;span class="nv"&gt;nixPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;mapAttrsToList&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;=&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;nix&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now here we already face the first obstacle: I do not understand what this means. I read already couple times about this flakes registry. Is this only on my machine? Where is this &lt;em&gt;registry&lt;/em&gt;? And what are the &lt;code&gt;nix3&lt;/code&gt; commands? Is this a typo? What is the number &lt;code&gt;3&lt;/code&gt; next to the &lt;code&gt;nix&lt;/code&gt; command? &lt;/p&gt;

&lt;p&gt;I will ask GPT4 and copy paste this piece of code into it. &lt;/p&gt;

&lt;p&gt;OK, so this piece of code defines two attributes: &lt;code&gt;registry&lt;/code&gt; and &lt;code&gt;nixPath&lt;/code&gt;. That's clear. How are these attributes defined and what do they actually do and what for?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;registry: The purpose of the registry attribute is to create an attribute set that maps each input flake to a registry entry. A registry entry in Nix is a way to map a flake reference to a specific flake. In this case, we are creating a registry entry for each input flake with the same name as the input itself.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So what does this mean. After much talking with GPT it shows me that this registry is not some online package registry of flakes but a local registry simply defined with this piece of code in my &lt;code&gt;configuration.nix&lt;/code&gt;. So I can input one or many flakes that will be pulled into the rebuild cycle. Now this does remind of sub-modules that we can import into a &lt;code&gt;configuration.nix&lt;/code&gt; or a &lt;code&gt;default.nix&lt;/code&gt; but this isn't the same. The flakes are referenced and not simply combined into one flake. Or they are in a way when defined in &lt;code&gt;flake.nix&lt;/code&gt;?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The registry is a user-defined mapping of flake references to specific flakes, and it is not a global, system-wide resource like a package registry in other package managers.&lt;/p&gt;

&lt;p&gt;To achieve this, the lib.mapAttrs function is used. lib.mapAttrs is a higher-order function that takes two arguments: a function and an attribute set. It applies the provided function to each key-value pair in the attribute set and returns a new attribute set with the same keys and the resulting values.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now what and how does this function work? Just by reading this it looks like a general mapping function that maps an operation to a list of things transforming the first list into a new list, or to be precise in our case an attribute set.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;

&lt;span class="nv"&gt;registry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;mapAttrs&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;flake&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="nv"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Let's check the Nix reference manual at &lt;a href="https://nixos.org/manual/nix/stable/language/builtins.html#builtins-mapAttrs" rel="noopener noreferrer"&gt;https://nixos.org/manual/nix/stable/language/builtins.html#builtins-mapAttrs&lt;/a&gt;  to see the what this &lt;code&gt;lib.mapAttrs&lt;/code&gt; does:&lt;/p&gt;

&lt;p&gt;Apply function &lt;em&gt;f&lt;/em&gt; to every element of &lt;em&gt;attrset&lt;/em&gt;. As an example:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;

&lt;span class="nv"&gt;nix-repl&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;builtins&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;mapAttrs&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;So here we come to a higher-order &lt;em&gt;mapping&lt;/em&gt; function which is the bread and butter of functional programming. Nix is a pure functional language based on lambda calculus so these concepts such as &lt;em&gt;map&lt;/em&gt;, &lt;em&gt;reduce&lt;/em&gt;, &lt;em&gt;filter&lt;/em&gt;, and &lt;em&gt;fold&lt;/em&gt; pop out often. This is the thing I love about Nix. It reminds me on Haskell which is dear to my heart but still conceptually difficult for me. Nix might be actually a nice step towards learning Haskell eventually and also Rust with its functional constructs. So let's simplify this a bit and maybe use a simpler &lt;em&gt;map&lt;/em&gt; function with numbers and list of numbers to see how it works:&lt;/p&gt;

&lt;p&gt;Let's create a function that would double its input. So if we give it a number &lt;code&gt;2&lt;/code&gt; it will give us back a &lt;code&gt;4&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;

&lt;span class="nv"&gt;nix-repl&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;double&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

&lt;span class="nv"&gt;nix-repl&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;double&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="mi"&gt;4&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Ok that seems easy enough. Now let's make a list of numbers:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;

&lt;span class="nv"&gt;nix-repl&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nv"&gt;nix-repl&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;numbers&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Great! We have a doubling function and a list of numbers. Can we apply our &lt;code&gt;double&lt;/code&gt; function to a list of numbers as same as we applied it to a single number?&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;

&lt;span class="nv"&gt;nix-repl&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;double&lt;/span&gt; &lt;span class="nv"&gt;numbers&lt;/span&gt;
&lt;span class="nv"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt; &lt;span class="nv"&gt;is&lt;/span&gt; &lt;span class="nv"&gt;a&lt;/span&gt; &lt;span class="nv"&gt;list&lt;/span&gt; &lt;span class="nv"&gt;while&lt;/span&gt; &lt;span class="nv"&gt;an&lt;/span&gt; &lt;span class="nv"&gt;integer&lt;/span&gt; &lt;span class="nv"&gt;was&lt;/span&gt; &lt;span class="nv"&gt;expected&lt;/span&gt;

       &lt;span class="nv"&gt;at&lt;/span&gt; &lt;span class="err"&gt;«&lt;/span&gt;&lt;span class="nv"&gt;string&lt;/span&gt;&lt;span class="err"&gt;»&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

            &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;  &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
             &lt;span class="err"&gt;|&lt;/span&gt;     &lt;span class="err"&gt;^&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Nope. We can't. What do we do now? Now we come to the idea: How could we &lt;em&gt;map&lt;/em&gt; the &lt;code&gt;double&lt;/code&gt; function to each number of the list &lt;code&gt;numbers&lt;/code&gt;? Or in other words, the &lt;code&gt;map&lt;/code&gt; function takes two arguments: the function to be applied and the list of elements to which the function will be applied. Now is there a &lt;code&gt;map&lt;/code&gt; function in Nix that we can use? Yes there is! And it's right above the &lt;code&gt;mapAttrs&lt;/code&gt; function in the Nix reference manual at &lt;a href="https://nixos.org/manual/nix/stable/language/builtins.html#builtins-map" rel="noopener noreferrer"&gt;https://nixos.org/manual/nix/stable/language/builtins.html#builtins-map&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So in Nix we have the &lt;code&gt;map&lt;/code&gt; function that maps over lists and we have the &lt;code&gt;mapAttrs&lt;/code&gt; function that maps over attribute sets.&lt;br&gt;
So the solution is simple then:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;

&lt;span class="nv"&gt;nix-repl&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;map&lt;/span&gt; &lt;span class="nv"&gt;double&lt;/span&gt; &lt;span class="nv"&gt;numbers&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c"&gt;# same could be done with a square function&lt;/span&gt;

&lt;span class="nv"&gt;nix-repl&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;square&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;

&lt;span class="nv"&gt;nix-repl&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kr"&gt;map&lt;/span&gt; &lt;span class="nv"&gt;square&lt;/span&gt; &lt;span class="nv"&gt;numbers&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt; &lt;span class="mi"&gt;36&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;But by observing this behavior we can tell that this will not work with attribute sets because attribute sets have keys and values which is also a kind of map so we are talking about different &lt;em&gt;data structures&lt;/em&gt;. So our &lt;em&gt;mapping&lt;/em&gt; function needs to be modified. Mindblowing right? All of this smells like a &lt;em&gt;Functor&lt;/em&gt; but I won't deep dive into that right now. &lt;/p&gt;

&lt;p&gt;Actually by studying the &lt;code&gt;mapAttrs&lt;/code&gt; function on our double and numbers list will show the difference:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;

&lt;span class="kd"&gt;let&lt;/span&gt;
  &lt;span class="nv"&gt;lib&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;nixpkgs/lib&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;doubleValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;one&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;two&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;three&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nv"&gt;doubledNumbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;mapAttrs&lt;/span&gt; &lt;span class="nv"&gt;doubleValue&lt;/span&gt; &lt;span class="nv"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;in&lt;/span&gt;
  &lt;span class="nv"&gt;doubledNumbers&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We need to import the &lt;code&gt;&amp;lt;nixpkgs/lib&amp;gt;&lt;/code&gt; because our simple &lt;code&gt;map&lt;/code&gt; is built into nix while the &lt;code&gt;mapAttrs&lt;/code&gt; is defined in the &lt;code&gt;lib&lt;/code&gt; library which is a part of &lt;code&gt;nixpkgs&lt;/code&gt; packages. Save that file as let's say mapAttrs.nix and then:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;

&lt;span class="err"&gt;❯&lt;/span&gt; &lt;span class="nv"&gt;nix-instantiate&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nv"&gt;eval&lt;/span&gt; &lt;span class="nv"&gt;mapAttrs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;nix&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;five&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;CODE&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;four&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;CODE&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;one&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;CODE&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;six&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;CODE&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;three&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;CODE&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;two&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;CODE&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Wow! we can see it works! Yes, the &lt;code&gt;&amp;lt;CODE&amp;gt;&lt;/code&gt; parts are not showing because Nix is a lazy language, it only evaluates what is needed or to put it in better terms:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Nix only evaluates the function for a specific key-value pair when the corresponding value is accessed in the resulting attribute set. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If we add &lt;code&gt;--strict&lt;/code&gt; option to our evaluation then we can see the result and the attribute sets will be evaluated:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;

&lt;span class="err"&gt;❯&lt;/span&gt; &lt;span class="nv"&gt;nix-instantiate&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nv"&gt;eval&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nv"&gt;strict&lt;/span&gt; &lt;span class="nv"&gt;mapAttrs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;nix&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;five&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;four&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;one&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;six&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;three&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;two&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Wonderful! But what else can we see from this? We can see that the objects in this resulting set are unordered. While lists in Nix are ordered collections of elements that preserve the order the attribute sets are unordered because they are designed to be accessed by their keys, rather than the order of the elements.&lt;/p&gt;

&lt;h3&gt;
  
  
  So what about our flake?
&lt;/h3&gt;

&lt;p&gt;Let's leave our deep dive into &lt;em&gt;mapping&lt;/em&gt; functions and look again our flake registry definition.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;

&lt;span class="nv"&gt;registry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;mapAttrs&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;flake&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="nv"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;So the result of our function over the flake attribute set will be stored in the registry attribute set which is basically a &lt;em&gt;variable&lt;/em&gt; called &lt;code&gt;registry&lt;/code&gt;. Then it become pretty obvious by now what the &lt;code&gt;lib.mapAttrs&lt;/code&gt; does - a function that transforms the key-value pairs, and an attribute set to apply the transformation on. But now we come to the second part of the definition which is a lambda function that takes two arguments, &lt;code&gt;_:&lt;/code&gt; and &lt;code&gt;values:&lt;/code&gt; Now the underscore is used in cases when the key is not used in the function body same as in our previous example when we doubled the attribute set with &lt;code&gt;doubleValue = _: value: value * 2;&lt;/code&gt; In this case we are interested in the doubling of the value while the key is empty. This is a concept known in functional language but I still need to see more examples of it.&lt;/p&gt;

&lt;p&gt;OK I have talked more with GPT and this quote actually brings things nicely in line:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When you apply lib.mapAttrs (_: value: { flake = value; }) inputs;, it will iterate over the key-value pairs in the inputs attribute set, and for each key-value pair, it will create a new attribute set with the attribute flake set to the original value. The resulting registry attribute set will have the same keys as the inputs attribute set, but the values will be wrapped in a new attribute set with the flake attribute.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So if our &lt;code&gt;inputs&lt;/code&gt; attribute set looks like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;nixpkgs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;flake-utils&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After applying the registry function it will look like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;nixpkgs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;flake&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nv"&gt;flake-utils&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;flake&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This finally makes so much sense. Now I just need to reread all this exploration couple times, meditate on it, sleep over it, and then again try to install flakes. Flake my life, this isn't easy at all but is super interesting. I never had this much fun configuring the system. I am learning programming and configuring at the same time while on top of it all everything is functional and there are lambda functions everywhere. How amazing is that!&lt;/p&gt;

&lt;p&gt;But wait did I setup my flake? No I didn't. But I learned a lot and I have been doing this for hours today whole day. So much from my simple flake setup. But I will flake myself soon! I need to rest and watch some Nix talk and then try out the flake bit again. Then post about it next time. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F339mc5n4un7b4gunu337.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F339mc5n4un7b4gunu337.jpg" alt="Bill Murray happy"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nixos</category>
      <category>functional</category>
      <category>beginners</category>
      <category>configuration</category>
    </item>
    <item>
      <title>Flake my life - how do nix flakes work?</title>
      <dc:creator>domagoj miskovic</dc:creator>
      <pubDate>Wed, 12 Apr 2023 12:29:55 +0000</pubDate>
      <link>https://forem.com/stablejoy/flake-my-life-how-do-nix-flakes-work-2foe</link>
      <guid>https://forem.com/stablejoy/flake-my-life-how-do-nix-flakes-work-2foe</guid>
      <description>&lt;p&gt;So I’m watching the excellent video &lt;a href="https://youtu.be/ARjAsEJ9WVY" rel="noopener noreferrer"&gt;Jake Hamilton "NixOS Flake tour"&lt;/a&gt; because I don't really understand how flakes work. Conceptually it seems clear but there is strange deepness to it too. What are flakes? Are flakes a natural extension or progression of nix expressions? I'd like to setup my system with flakes but it all seems foggy and unclear.&lt;/p&gt;

&lt;p&gt;I used to have my NixOS setup with a tiling manager and various configs I copied from other experienced NixOS users but all that was done with a &lt;code&gt;configuration.nix&lt;/code&gt; and &lt;code&gt;home-manager&lt;/code&gt; and cachix as well. And then there was this really nice xmonad setup by Gabriel Volpe I managed to reproduce and which is a flake too, but after analyzing it and studying all the modules I still haven't actually understand how flakes work. His setup is at  &lt;a href="https://github.com/gvolpe/nix-config" rel="noopener noreferrer"&gt;github link&lt;/a&gt;. Then came the time when I didn't use NixOS and in the mean time flakes have taken over the world it seems. Now I have just the plain plasma DE and simply wish to setup a basic flake system with a home-manager and one output machine. But so far it seems I cannot understand how flakes actually work. I have just applied for Summer of Nix 2023 and although I am incredibly excited about it and wish to do my best if it happens for me, I am almost feeling depressed since I can't seem to understand even how flakes work. How will I jump into the ocean of Nix expressions then?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fne79o4x546a0hznra89h.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fne79o4x546a0hznra89h.jpg" alt="Burnham surprised"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So Jake very quickly mentions the &lt;code&gt;snowfall-lib&lt;/code&gt; he wrote, a project of his. What does that mean? Is the &lt;code&gt;snowflake-lib&lt;/code&gt; a library or a program or just another nix expression that would somehow automate flake related stuff? Jake says it “kind of does the boring work of wiring things together” so I guess I will understand more soon. There is a reason he has the folders organized the way they are setup and maybe the &lt;code&gt;snowfall-lib&lt;/code&gt; does that for him or the folders need to be setup like that in advance?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;.. because those are conventions from snowfall-lib which let’s me just say hey here is my directory with all of my stuff in it and it will import everything and hook it all up. I’m actually using the slightly more complex method here. I could switch this out to &lt;code&gt;snowfall lib.makeFlake&lt;/code&gt; but once upon a time I needed access to this lib here. So &lt;code&gt;snowfall-lib&lt;/code&gt;, go check it out..&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I have no idea what this means. But I'm sure it's just some context beyond my level of understanding for now. I'm still a NixOS newbie. &lt;/p&gt;

&lt;p&gt;So I go now to snowfall-lib on &lt;a href="https://github.com/snowfallorg/lib" rel="noopener noreferrer"&gt;snowfall homepage on github&lt;/a&gt; and here we see that snowflake is built on top of &lt;code&gt;flake-utils-plus&lt;/code&gt; and that snowflake is described as &lt;em&gt;Unified configuration for systems, packages, modules, shells, templates, and more with Nix Flakes&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Oh I see. It seems without this snowfall library two or more users creating different flakes might end up with creating different set of folders or directories in the flake directory. So this means although flakes are reproducible they themselves appear to be impure because of different sets of directories? This is only important for the snowfall library for now since the library can potentially process all the flakes and automate stuff only if the flakes would respect the standard way in which flake directories are created. But since there is no standard way flakes directories are created snowfall enforces that which in turn enables the library to do the automation work. This is so far how I understand how this works.&lt;/p&gt;

&lt;p&gt;Oh, now I see he uses &lt;code&gt;deploy-rs&lt;/code&gt; for deployment which means this is another tool for automating nix flows. So now conceptually we have &lt;code&gt;snowflake-lib&lt;/code&gt;, which is built on top of &lt;code&gt;flake-utils-plus&lt;/code&gt; that uses the &lt;code&gt;deploy-rs&lt;/code&gt; tool for deployment of outputs? Is &lt;code&gt;deploy-rs&lt;/code&gt; something like &lt;strong&gt;NixOps&lt;/strong&gt;? Now why would we need a deployment tool? I guess I will read now the serokell blog post on their tool delpoy-rs&lt;a href="https://serokell.io/blog/deploy-rs" rel="noopener noreferrer"&gt;&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;But reading it I understand that I should go out of this rabbit hole and try to find something on flakes. And in the article the often mentioned article from Tweag is referenced which is at &lt;a href="https://www.tweag.io/blog/2020-06-25-eval-cache/" rel="noopener noreferrer"&gt;https://www.tweag.io/blog/2020-06-25-eval-cache/&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In the past, you might use the &lt;code&gt;NIX_PATH&lt;/code&gt; environment variable to allow your project to find Nixpkgs. In the world of flakes, this is no longer allowed: flakes have to declare their dependencies explicitly,&lt;br&gt;
and these dependencies have to be locked to specific revisions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So this makes sense actually. But now this brings us to cache invalidation which is a serious problem in computer science! The cache itself is not the problem but the stale cache data that is not needed anymore and the problem of updating the cache field. So while on one hand you could update it too much and create much latency you could update it rarely and thus create stale unused data which might bring other problems in the system. This does seem like a hard problem. And this is where apparently flakes come to rescue.&lt;/p&gt;

&lt;p&gt;Flakes bring what is called &lt;em&gt;hermetic evaluation&lt;/em&gt; into the game, hermetic meaning completely sealed of from external influences. I ask now chatgpt4 to explain me the concept of hermetic evaluation in terms of nix flakes and it does a good job of it. &lt;/p&gt;

&lt;p&gt;Chatgpt explains:&lt;/p&gt;

&lt;p&gt;Hermetic evaluation in terms of Nix Flakes has the following implications:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Explicit dependencies: Nix Flakes forces you to declare all dependencies explicitly, making it clear which external resources are required for the build or evaluation process. This helps ensure that the build process is self-contained and reproducible.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Content-addressed storage: Nix Flakes uses content-addressed storage, which means that the outputs of a build are identified by the hash of their content. This ensures that if the inputs to a build haven't changed, the output will remain the same, regardless of external factors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Isolated build environments: Nix creates isolated build environments for each package, with precisely defined inputs and no access to external resources. This ensures that the build process is not influenced by factors outside of the declared dependencies.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Lock files: Nix Flakes automatically generates lock files that "pin" the exact versions of dependencies used in a project. This ensures that the build remains reproducible, even when the upstream dependencies change.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Composability: Nix Flakes enables you to easily compose different projects together, ensuring that the dependencies between them are well-defined and isolated. This helps maintain the hermetic nature of the evaluation process when combining different Nix-based projects.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fukmiudsc0fwplgc02jz6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fukmiudsc0fwplgc02jz6.jpg" alt="Data and Picard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Actually now my understanding is that flakes are a natural extension of the nix system. It's like nix itself built on top of nix. The very reproducible nature of nix enables something such as flakes to work. So it's not even a question of inventing flakes, it is a question of finding them, this new solution that solves reproducibility of entire nix package configurations that have an arbitrary number of inputs. So now a flake can have more information cached in a way which will result in a faster evaluation time.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Since the flake’s lock file contains content hashes of all dependencies, this is enough to efficiently and completely capture all files that might influence the evaluation result. (In the future, we’ll optimise this a bit more: for example, if the flake is a Git repository, we can simply use the Git revision as the cache name.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yeah, so in part three of the series on Nix Flakes the theme is setting up individual NixOS configurations as flakes. One of the things I didn't first like about home-manager is that it was somehow separated from the NixOS &lt;code&gt;configuration&lt;/code&gt; but then there was a possibility to include home-manager as a standalone NixOS module and include it in the &lt;code&gt;configuration.nix&lt;/code&gt; so that when one runs &lt;code&gt;nixos-rebuild switch&lt;/code&gt; it would update the home-manager tree as well. But now when thinking of the flake view on this it does show that let's say I run my setup in a month or so what will happen? My &lt;code&gt;nixos-rebuild switch&lt;/code&gt; will pull out a different git revision of packages from the &lt;code&gt;nixpkgs&lt;/code&gt; tree. Does that mean it will not work? No, on the contrary, it will work but those will be newer versions of my packages. So now we have two points in time which does make the situation &lt;em&gt;impure&lt;/em&gt;. The benefit of flakes is that our system configuration is fully reproducible meaning the packages and the nixpkgs are pinned down to their respective versions at the time when &lt;code&gt;flake.lock&lt;/code&gt; is created. At least this is how I understand it now. &lt;/p&gt;

&lt;p&gt;As the article goes let's check our NixOS version right now:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;

&lt;span class="err"&gt;❯&lt;/span&gt; &lt;span class="nv"&gt;nixos-version&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nv"&gt;json&lt;/span&gt; &lt;span class="err"&gt;|&lt;/span&gt; &lt;span class="nv"&gt;jq&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;r&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;nixpkgsRevision&lt;/span&gt;
&lt;span class="nv"&gt;The&lt;/span&gt; &lt;span class="nv"&gt;program&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nv"&gt;jq&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="nv"&gt;is&lt;/span&gt; &lt;span class="nv"&gt;not&lt;/span&gt; &lt;span class="kn"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;your&lt;/span&gt; &lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;You&lt;/span&gt; &lt;span class="nv"&gt;can&lt;/span&gt; &lt;span class="nv"&gt;make&lt;/span&gt; &lt;span class="nv"&gt;it&lt;/span&gt; &lt;span class="nv"&gt;available&lt;/span&gt; &lt;span class="kn"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;an&lt;/span&gt;
&lt;span class="nv"&gt;ephemeral&lt;/span&gt; &lt;span class="nv"&gt;shell&lt;/span&gt; &lt;span class="nv"&gt;by&lt;/span&gt; &lt;span class="nv"&gt;typing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nv"&gt;nix-shell&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;p&lt;/span&gt; &lt;span class="nv"&gt;jq&lt;/span&gt;

&lt;span class="sx"&gt;~/.config&lt;/span&gt; 
&lt;span class="err"&gt;❯&lt;/span&gt; &lt;span class="nv"&gt;nix-shell&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;p&lt;/span&gt; &lt;span class="nv"&gt;jq&lt;/span&gt;
&lt;span class="nv"&gt;this&lt;/span&gt; &lt;span class="nv"&gt;path&lt;/span&gt; &lt;span class="nv"&gt;will&lt;/span&gt; &lt;span class="nv"&gt;be&lt;/span&gt; &lt;span class="nv"&gt;fetched&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="nv"&gt;MiB&lt;/span&gt; &lt;span class="nv"&gt;download&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;01&lt;/span&gt; &lt;span class="nv"&gt;MiB&lt;/span&gt; &lt;span class="nv"&gt;unpacked&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="sx"&gt;/nix/store/65kn5z9zx4vwpib1v4b2kvc8mbalyrvj-jq-1.6-dev&lt;/span&gt;
&lt;span class="nv"&gt;copying&lt;/span&gt; &lt;span class="nv"&gt;path&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="sx"&gt;/nix/store/65kn5z9zx4vwpib1v4b2kvc8mbalyrvj-jq-1.6-dev&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="nv"&gt;from&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="nv"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="nv"&gt;cache&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;nixos&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;org&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="sx"&gt;~/.config&lt;/span&gt; &lt;span class="nv"&gt;via&lt;/span&gt; &lt;span class="err"&gt;❄&lt;/span&gt;  &lt;span class="nv"&gt;impure&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;shell&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="err"&gt;❯&lt;/span&gt; &lt;span class="nv"&gt;nixos-version&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nv"&gt;json&lt;/span&gt; &lt;span class="err"&gt;|&lt;/span&gt; &lt;span class="nv"&gt;jq&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;r&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;nixpkgsRevision&lt;/span&gt;
&lt;span class="nv"&gt;d9f759f2ea8d265d974a6e1259bd510ac5844c5d&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;So there is a unique number but you apparently can't extract the &lt;code&gt;configuration.nix&lt;/code&gt; or any other modules file from this number.&lt;/p&gt;

&lt;p&gt;Oh wow, and now a really cool quote comes:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It’s worth noting that any NixOS system configuration already violates the monorepo assumption: your system’s configuration.nix is not part of the nixpkgs repository.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I have never thought about this but it does make perfect sense. If my &lt;code&gt;configuration.nix&lt;/code&gt; is not in a common repo this means it is impure and harder to use!&lt;/p&gt;

&lt;p&gt;So another quote nicely outlines what flakes solve:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Reproducibility&lt;/em&gt;: the entire system configuration (including everything it depends on) is captured by the flake and its lock file. So if two people check out the same Git revision of a flake and build it, they should get the same result.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Traceability&lt;/em&gt;: &lt;code&gt;nixos-version&lt;/code&gt; prints the Git revision of the top-level configuration flake, not its &lt;code&gt;nixpkgs&lt;/code&gt; input.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Composability&lt;/em&gt;: it’s easy to pull in packages and modules from other repositories as flake inputs.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1ky8vm5andca9gg9k7oh.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1ky8vm5andca9gg9k7oh.jpg" alt="Burnham happy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OK so here we go. Now I already am on NixOS unstable, so I just need to enable the flake enabling option in my &lt;code&gt;configuration.nix&lt;/code&gt; but here is where the first problem arises because I am not sure if this relates to a pure NixOS system or a system that has just the Nix package manager installed:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;

&lt;span class="nv"&gt;nix&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;extraOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;''&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;  experimental-features = nix-command flakes&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s2"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The thing is that the &lt;a href="https://nixos.wiki/wiki/Flakes" rel="noopener noreferrer"&gt;NixOS wiki on Flakes&lt;/a&gt; states a different nix setting for the &lt;code&gt;configuration.nix&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;

&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;nix&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;experimental-features&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"nix-command"&lt;/span&gt; &lt;span class="s2"&gt;"flakes"&lt;/span&gt; &lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;But then I stumble on this recommendation on &lt;a href="https://discourse.nixos.org/t/using-experimental-nix-features-in-nixos-and-when-they-will-land-in-stable/7401/3" rel="noopener noreferrer"&gt;NixOS discourse&lt;/a&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;

&lt;span class="nv"&gt;nix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nv"&gt;package&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;nixFlakes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="nv"&gt;extraOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;optionalString&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;nix&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;package&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;nixFlakes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
     &lt;span class="s2"&gt;"experimental-features = nix-command flakes"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now yesterday I watched also excellent three hour video on setting up NixOS at &lt;a href="https://youtu.be/AGVXJ-TIv3Y" rel="noopener noreferrer"&gt;NixOS Setup Guide&lt;/a&gt; from which I did:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;

&lt;span class="nv"&gt;nix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;package&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;nixFlakes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;extraOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"experimental-features = nix-command flakes"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now what is going on here and why are these expressions different and yet apparently doing the same thing. Now we come to nix programming! I asked chatgpt to explain me the differences between all these expressions and after some chatting back and forth it is evident now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;that the first expression which was shared on NixOS discourse is actually conditionally enabling experimental features only in the case of flakes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;the last expression actually enables experimental features in whatever case so not just for flakes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How is the first expression conditionally enabling flakes is the cool part! With the &lt;code&gt;lib.optionalString&lt;/code&gt; which is a function provided by the nix library. &lt;/p&gt;

&lt;p&gt;The syntax is like:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;

&lt;span class="nv"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;optionalString&lt;/span&gt; &lt;span class="nv"&gt;condition&lt;/span&gt; &lt;span class="nv"&gt;stringValue&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In the first expression:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;

&lt;span class="nv"&gt;extraOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;optionalString&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;nix&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;package&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nv"&gt;pkgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;nixFlakes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
     &lt;span class="s2"&gt;"experimental-features = nix-command flakes"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;the value of &lt;code&gt;extraOptions&lt;/code&gt; is conditionally set to &lt;code&gt;"experimental-features = nix-command flakes"&lt;/code&gt; only if &lt;code&gt;config.nix.package&lt;/code&gt; is equal to &lt;code&gt;pkgs.nixFlakes&lt;/code&gt;. This means that the &lt;code&gt;"experimental-features"&lt;/code&gt; option will be included only when the system is using the &lt;code&gt;nixFlakes&lt;/code&gt; package.&lt;/p&gt;

&lt;p&gt;Ok so after seeing more chatgpt examples of &lt;code&gt;lib.optionalString&lt;/code&gt; utility I see that it's a really practical way to include flags into builds and configurations that might or might not happen depending on some conditions. &lt;/p&gt;

&lt;p&gt;This flake my life will need to go on. My goal is to make the simplest possible flake of my system and make sort of a spectrum of possible ways how the flake can expand from a simple to more complex system. I often find out complex flake configurations with just enough nix expressions variations and that makes it a bit more difficult for me to understand. But I learned the cool &lt;code&gt;lib.optionalString&lt;/code&gt; though which is awesome!&lt;/p&gt;

</description>
      <category>nixos</category>
      <category>functional</category>
      <category>beginners</category>
      <category>nix</category>
    </item>
    <item>
      <title>Recursive/Attribute Sets of Nix Expressions</title>
      <dc:creator>domagoj miskovic</dc:creator>
      <pubDate>Sat, 08 Apr 2023 13:20:57 +0000</pubDate>
      <link>https://forem.com/stablejoy/recursiveattribute-sets-of-nix-expressions-2m3a</link>
      <guid>https://forem.com/stablejoy/recursiveattribute-sets-of-nix-expressions-2m3a</guid>
      <description>&lt;p&gt;This is going to be a beginner oriented exploration about a fundamental data structure in Nix language - Attribute sets. &lt;/p&gt;

&lt;p&gt;Attribute sets are a collection of key-value pairs where each unique key is associated with a value. These key-value pairs or as we sometimes call them maps are also called in a more general term associative arrays, or dictionaries in Python, hashmaps in Java, objects in Javascript and so on.&lt;/p&gt;

&lt;p&gt;The Nix manual states that attribute set is a collection of name-value-pairs (called &lt;em&gt;attributes&lt;/em&gt;) enclosed in curly brackets (&lt;code&gt;{}&lt;/code&gt;). Names and values are separated by an equal sign (&lt;code&gt;=&lt;/code&gt;). Each value is an arbitrary expression terminated by a semicolon (&lt;code&gt;;&lt;/code&gt;). Attributes can appear in any order and an attribute name may appear only once.&lt;/p&gt;

&lt;p&gt;So this means they are unordered which goes along with Nix being lazy evaluated language. But the reason they are unordered is because they do not represent sequences but mappings of key-value-pairs. This made me think of category theory and another one of brilliant Bartosz Milewski lectures where he compared a table with cached functions. &lt;/p&gt;

&lt;p&gt;In Nix language there are basically two kinds of these attribute sets. There are these regular non-recursive attribute sets that cannot reference any attribute within and then there are the non-regular recursive attribute sets that can access any attribute which means they can construct complex configurations and interdependent relationships between attributes. OK what does that mean? Because It took me a while to really understand the difference.&lt;/p&gt;

&lt;p&gt;So the thing about the recursive attribute set is that one can refer to any attribute within the set. &lt;/p&gt;

&lt;p&gt;A very small example of this would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="kr"&gt;rec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;# b refers to a, which is defined in the same attribute set&lt;/span&gt;
  &lt;span class="nv"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;b&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;# c refers to b, which is defined in the same attribute set&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So what this means is that when we are designing complex build processes we can self reference within the set and access different values. Like deriving a new attribute from an existing one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="kr"&gt;rec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"alice"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;homeDirectory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"/home/&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now this makes me think how come I can't recognize when I look at my &lt;code&gt;configuration.nix&lt;/code&gt; file which expressions are recursive and which are not by just looking at the syntax. What I mean is that my &lt;code&gt;user&lt;/code&gt; is declared with a set but there is no mention of a recursive set or the &lt;code&gt;rec&lt;/code&gt; keyword. Now chatgpt answers me on this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You are correct that recursive attribute sets are typically declared using the rec keyword. However, in NixOS and your configuration.nix file, you might not always see rec being used explicitly. This is because the NixOS configuration is built using the NixOS module system, which automatically handles the creation of recursive attribute sets when needed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Oh cool. Then it explains a bit how that process goes.&lt;/p&gt;

&lt;p&gt;So again what is an attribute set basically? An attribute set is a collection of key-value pairs. Like a dictionary or a phone book we have a key and a value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But we can write any other value such as a number 42, a string of “hello”, a path to a file in a system, a boolean value of true or false, a uri value or an address of a web site to say it more plainly, a list of things such as fruits, or even what is really cool - a nested attribute set:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;intVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;strVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;pathVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sx"&gt;/etc/nixos/configuration.nix&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;boolVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;uriVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"https://example.com"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;listVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"apple"&lt;/span&gt; &lt;span class="s2"&gt;"banana"&lt;/span&gt; &lt;span class="s2"&gt;"cherry"&lt;/span&gt; &lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="nv"&gt;nestedAttrSet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;keyA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"valueA"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;keyB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"valueB"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nv"&gt;functionVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So a nested attribute set in Nix refers to an attribute set that is used as a value within another attribute set. But what does that mean? I asked ChatGPT to quickly create a phonebook of three contacts and show nested attribute sets. Now the same applies when making packages. You have the names of the packages but then you have a different build options and even instructions or functions with these build options. So even though a phonebook example looks pretty clear, this is just a very small example of nested attribute sets.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nix"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;phonebook&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;contact1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Alice"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nv"&gt;phoneNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"555-1234"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nv"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"alice@example.com"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nv"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;street&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"123 Main St"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;city&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Anytown"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"CA"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;zip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"12345"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nv"&gt;contact2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Bob"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nv"&gt;phoneNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"555-5678"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nv"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"bob@example.com"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nv"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;street&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"456 Elm St"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;city&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Sometown"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"NY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;zip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"67890"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nv"&gt;contact3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Charlie"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nv"&gt;phoneNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"555-9876"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nv"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"charlie@example.com"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nv"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;street&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"789 Oak St"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;city&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Othertown"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"TX"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;zip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"24680"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now what this makes me think is are all attribute sets one-dimensional or are there multi-dimensional attribute sets. In some ways recursive sets I guess mimic that behavior. But not really. Recursive sets being able to reference values within themselves during a temporal state doesn't make them multi-dimensional. This just proves I do not quite understand what would multi-dimensional configuration actually mean in this context. &lt;/p&gt;

&lt;p&gt;But that's OK. I am enjoying this exploration of nix attribute sets. Need to explore attribute sets more and how they can be constructed. Also keeping my attention to attribute sets and slowly expanding from that seems helpful because I seem to retain more information between sessions and it is easier to get back to it even for ten minutes.&lt;/p&gt;

</description>
      <category>nix</category>
      <category>beginners</category>
      <category>functional</category>
      <category>linux</category>
    </item>
    <item>
      <title>finding rest in devops</title>
      <dc:creator>domagoj miskovic</dc:creator>
      <pubDate>Sat, 11 Mar 2023 10:52:28 +0000</pubDate>
      <link>https://forem.com/stablejoy/finding-rest-in-devops-h07</link>
      <guid>https://forem.com/stablejoy/finding-rest-in-devops-h07</guid>
      <description>&lt;h3&gt;
  
  
  Going into AWSome clouds
&lt;/h3&gt;

&lt;p&gt;It all began with a question my partner asked me. She asked what is a cloud engineer and what is cloud? I paused for a moment and said the cloud is like the plumbing between people and apps. It makes data and apps available to us at great scale and you don't have to hold the server in your hands and build it yourself. But then the cloud isn’t just that. It's so much more. It’s about connections and how complex relations happen between services and which ones work best for which workloads. And how much work and care and passion there is between the users and machines. Something like that. I began thinking more and more about the cloud days after that. I felt that hacking vibe and a wish to get into it deeper or higher. The thing is once you start thinking about the cloud you start thinking globally like on a massive scale.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1zf8hgndqupzs75mlwkq.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1zf8hgndqupzs75mlwkq.jpeg" alt="image of clouds" width="800" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  aws makes it all together
&lt;/h3&gt;

&lt;p&gt;So yeah, like for example I have used ssh and keys and shells, and have ran scripts on my linux, installed virtual machines and played with archlinuxes and recently spent much time tinkering with NixOS. Or like I know about load balancers from reading the hackernews and how sites are cached around the world for better latency for the users. These things pop out  all the time. But that's just theory for me and constant shifting of my attention from this or that. The thing about AWS is that it actually helps me in staying focused with my learning because  all that seemingly random stuff I read about here and there or have engaged a bit on my individual machines now starts to make sense and is reflected into a global computing picture which is not static at all. AWS makes you hold everything you know and then learn some more by engaging with their services. These services show you how stuff connects actually. You can try stuff out, not just think about it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fosuhviamc7b606qvrud2.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fosuhviamc7b606qvrud2.jpeg" alt="Image of clouds" width="800" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS gives all the playground on massive scale
&lt;/h3&gt;

&lt;p&gt;But the great thing that inspires to go deeper into it is that AWS actually helps with the education and practical tools. There are these aws certifications and training, that test your knowledge of the concepts and the language and give a sort of framework through which one can see, have a bird eye view of what and how these services connect and what are the best and worst practices. I do love gentle hand holding and just love the general idea of certifications and how amazon is actually showing care about education through those. I didn't think like that before sadly. I was proud of being a loner explorer thinking acomplishing certs is boring. I underestimated their educational value and how they can help in seeing a larger picture of processes.&lt;/p&gt;

&lt;h3&gt;
  
  
  I discover that I know more than I thought
&lt;/h3&gt;

&lt;p&gt;OK so I planned to do the cloud practitioner certification and have began a course on youtube. Then I signed up for a AWS online conference event that happened on 9th March because I read they will be offering free 75% off price vouchers for the certificates. Great! I really liked the talks and by the end of the day I got the associate solutions architect badge for the 75% price. I asked on aws reddit and in short I was recommended to do that one instead of the cloud practitioner one because of my poweruser background. So while I am far away from actually knowing how aws works I realized my previous random linux knowledge and lots of reading and trying stuff out is actually helping me to understand aws concepts. Yes they have specific names for theis services like EC2 or S3 or DynamoDB but I did read about NoSQL databases before, and I am familiar with running virtual machines and setting different parameters. So now somehow all that random stuff I did is actually coming together in this aws journey. I can learn how it all works on massive scale and go slowly through it. Yeah, and I bought the Stephane Maarek udemy course on solutions architect so Im studying now with better focus.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fegs090bn8wfx8nydlbor.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fegs090bn8wfx8nydlbor.jpeg" alt="Image of clouds" width="800" height="354"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Im pretty excited in finding the right inspiration to learn devops and cloud with aws. This was the first post of my journey into devops and aws that had more to do with inpiration than technical issues. Stay tuned. I cant wait to write more technical stuff about the cloud. Its so exciting. &lt;/p&gt;

&lt;p&gt;P.s. These images of clouds in Croatia throughout the blog post were taken by me.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>learning</category>
      <category>devops</category>
      <category>cloud</category>
    </item>
    <item>
      <title>n-days of hacking - This is the best way to eat popcorn</title>
      <dc:creator>domagoj miskovic</dc:creator>
      <pubDate>Thu, 14 Apr 2022 17:09:48 +0000</pubDate>
      <link>https://forem.com/stablejoy/n-days-of-hacking-this-is-the-best-way-to-eat-popcorn-2eh3</link>
      <guid>https://forem.com/stablejoy/n-days-of-hacking-this-is-the-best-way-to-eat-popcorn-2eh3</guid>
      <description>&lt;h2&gt;
  
  
  How I discovered Ippsec and online cybersecurity training platforms
&lt;/h2&gt;

&lt;p&gt;I am blogging about my pentesting voyage because it helps me to learn better. It keeps my information scope in control. When one begins to immerse oneself into a field one tends to jump back and forth into various interesting rabbit holes. And hacking has many of those, all pretty and sweet. At the same time the art of hacking is also being able to see through many many of those holes and find the way in. There are so many details and areas so good repetitive practice and documenting thinking through builds motivation and most important inspiration&lt;/p&gt;

&lt;p&gt;Let me introduce my self briefly and the methodology that I will use. I have been tinkering with my linux boxes (Archlinux btw, debians and lately NixOS mostly) for more than a decade. My first linux was Slackware. It seems like ancient history to me honestly. I don’t work in IT, I am a professional classical guitarist and educator,  but always, since my youth have I have felt drawn to computers and linux. Lately, I have been learning Haskell and functional programming because it feels mind expanding, but I kinda gave that up being overwhelmed with functors and monads at the same time being a parent and having a regular job in a local music school. Not to say functional programming did not actually help me in so many ways, like when I see some code now the way I think about it has changed, type oriented thinking helps in seeing how things compose together. I say a regular job because I am not too happy with it. Its kind of a straight jacket. This year I have been learning about NixOS declarative linux distribution which is completely configured with nix expressions. There in a single source of truth, the configuration.nix file and you can roll back and forth from generation to generation, basically you can have many versions of the same program on the same system and nothing gets corrupted. I am no programmer and have not written any kind of program except the most basic ones. I often read and copy-paste too much and enjoy exploring various rabbit holes like category theory, taking a bite too big to swallow. I love reading things I don’t know about. I wonder if that is some kind of imposter syndrome reverse shell.&lt;/p&gt;

&lt;p&gt;I am familiar with various infosec terminology though, in the sense that I do know what nmap does, what TCP/IP means. I even used to read phrack issues from time to time. I spent much time reading all kinds of posts, deep diving on hackernews and on and so on. After ten years sometimes I feel I don't know much, just a bunch of very wide lateral surface like knowledge. Not much has been put into actual deep practice. Since most of these things I don’t really use or practice variations upon a theme I tend to forget them after a while. I am aware I might sound like a complete mess but I feel I am a hacker at heart. I do care for user experience and imagine a world where interacting with computers is well, more interactive. I used to play armagetronad game very well but after noticing my cortisol levels reaching up and wide I stopped suddenly and never played any games after it. I was good at it. But I thought about a gamified learning experience often and Imagined how the future of work are virtual gamified platforms. This is where Hack the Box blew my mind with it’s gamified hacking platform, a place where one can so to say have the cake and eat it too, where one can learn by doing, where one can play and learn at the same time and be a part a kind and receptive community of hackers.&lt;/p&gt;

&lt;p&gt;I recently finished watching the amazing Mr. Robot series on Netflix. Elliot can move through the networks and do all kinds of hacks which inspired me to think more about security and the actions of a user and read bits on security here and there. But there is something else too. A hacker is somehow flexible and creative and has a superior control over his digital senses. He can break in, he can modify all kinds of files, noticing the patterns and knowing how even a tiny change in the code might change the complete state of the system, and all that is visible in the real world too. He can write an exploit, a work of art whose sole purpose is to deliver a payload that will somehow bring the system to its knees. It is sci-fi at its purest.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flykloyry8rcj0o46uebd.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flykloyry8rcj0o46uebd.jpeg" alt="the user" width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I discovered HackTheBox platform and Ippsec walkthroughs. Ippsec is the famous HackTheBox player who also made many, almost 250 and counting, video explanations of the boxes he breached. He works now for HTB and continues to work on new boxes and doing all kinds of interesting work. I read about him and how many people even call him a legend. That is inspiring. I was instantly hooked and blown away into million bits as if Rinzler himself threw that disc at me. He seems like a really nice guy and you can sense his love and enthusiasm when he talks. He is humble too which is an amazing quality to experience when listening to an educator. It helps one progress faster and removes many mental afflictions that may appear along the way. Speaking as an educator myself, having someone like that helps immensely since he is not pulling you into his own afflictions but allowing you to grow as an artist, as a person. Actually seeing someone moving like that and talking back and forth about the possible attacks and defenses made all the difference for me too. Somehow the static images of hacking pages turned into a movie, and seeing this movie opened my eyes to the true beauty of hacking. &lt;/p&gt;

&lt;p&gt;I actually did buy the famous book &lt;em&gt;Hacking The Art of Exploitation&lt;/em&gt; back in 2011 but unfortunately I never read that book, it seemed too hard, too low level for me at that time, which is too bad since it looks like a great book. I needed my Ippsec. But have no regrets! HackTheBox is here to stay and there has never been better time to learn hacking! Isn’t that amazing!? Wait, how amazing is that!?&lt;/p&gt;

&lt;p&gt;Seeing Ippsec kindled that flame again and realizing you could hack all kinds of real boxes on a private virtual network with other players seemed so super exciting and again, mind blowing. But it’s not just that. It is amazing to see how someone moves around the network. While before I would read much and like statically configure something on my system, a hacker actually moves around the network and computers like USS Discovery. That is the inspiration I guess I was missing. Yes watching Ippsec is inspiring to say the least. It motivates you to learn about buffer overflows and php filters. You realize the shell commands are like various senses of a user and editing the code files is like search and replace actions, as if teleporting your actions into the distance of the digital grid you automate them, invoke reverse shells that connect to you and oh so many other goodies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's pop the corn!
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://youtu.be/NMGsnPSm8iw"&gt;ippsec popcorn&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So first I just watch the Ippsec popcorn video couple times and write a couple of notes here and there, not too many since I first want to listen to the way Ippsec speaks and the flow of it. Stuff like the php script into png file conversion eludes me the first time but by the next time I understand the idea of adding the beginning magic bytes from another legitimate file to the script so that the linux file command recognizes the script as a normal file. Looks hard at first but then it does get much easier.&lt;/p&gt;

&lt;p&gt;Now watching it for the third time I am carefully stopping after each phrase and googling everything Ippsec is saying. I do know what is nmap and php and png and what it means to get a reverse shell but of course I have no idea how to do all these things. I am like a hacker impostor, I can follow the conversation but I have no actual idea what is happening. I can only fake it, but that’s a beginning too.&lt;/p&gt;

&lt;p&gt;ppsec begins connecting to the virtual network with tmux which is a terminal multiplexer. He fires it up with a command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tmux new -s HTB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now this is a very nifty program and I am only briefly familiar with it from my xmonad days. In a tmux session you can open multiple terminal windows inside tmux, so in a way it is like a tiling window manager but just for the terminal window. Nice and important feature of tmux is that the session is persistent which means that if you do get disconnected from the server the program on the server will keep running. I still don’t know the full implication on this but let’s go on. There is also a new multiplexer called zellij written in Rust which is a modal multiplexer and visually it also seems really nice to try it out. Zellij shows the commands in the bottom pane which is more user friendly than the tmux way. So I install rustup and then zellij.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
$ cargo install zellij
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ippsec taks about the importance of being organized:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Very first thing to do is find a way to stay organized. I just created a folder called boxes and labeled the hostname of each box. This one is called popcorn&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I have been first using emacs with org mode and then switched to notion.so (I am actually using notion right now to write this) which has a really nice mobile app too but now I am also looking at obsidian too which has this temporal mapping and visual network of things you learn. In any case making good notes is very important. It makes all the difference when one is learning. One is repeating what one learns, formulating it in a variety of ways, thus going deeper into what one learns. It is extremely important. The next thing after taking notes is actually writing write-ups, blogging and streaming about what one learns. This helps in connecting with the community, which then helps in building motivation and persistence. Again, really important to take notes. And the level of expertise is not important, even more so, I wish there are more noobs documenting in detail how they go through these things. There is much to learn from that. Again, user experience and how one learns. It will help more people to learn IT.&lt;/p&gt;

&lt;p&gt;Ippsec begins the reconnaissance phase with a nmap scan with options:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;-sV for version, -sC to run safe scripts against it, it may be redundant to run both of these but I always do it out of habit. I put -oA formats because I don’t know if? I want to use the grepable format, the regular format or the xml. It might as well give me all. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The first thing he does is he goes to the 10.10.10.6 in the browser and gets the standard Apache server page it works!. I have no idea what nmap can actually do. Ok, so  nmap is something called a port scanner. A port scanner is usually used in the initial phase of reconnaissance. It enumerates or tells you information about the system or the networks you’re scanning. nmap is like the eyes through which you can see what is happening around you, what things or systems are doing on the network, what doors or ports are open or closed, how many there are, but also which kind of systems are running behind these doors. It seems it is easy to begin with nmap but there is a lot of depth to it too. &lt;/p&gt;

&lt;p&gt;I take the note to myself to do the corresponding courses on nmap on HackTheBox and TryHackMe and skim through the freely available nmap book by its original coder Fyodor. Again, nmap seems like a huge time investment in itself but for now maybe let’s continue and learn just the basics.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;So my very first step is I turn on my burp proxy and we are going to refresh this, and I am going to change this host to be the domain name of the server (Host: popcorn.htb) and I do this just because of something called virtual host routing. The server is going to look at this header that I sent and if it’s set up as virtual host routing it will read this and potentially service to a different location... Not the case here.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ippsec is using the professional burp license and as I learn the community one which is free has some limitations. I am wondering if these limitations will get in the way when attacking a single box on hackthebox or these limitations are appearing when attacking web applications with potentially several domains across the network. What are the limitations when using it for just a single web application on the hackthebox network? And I google alternatives such as open source tool ZAP. ZAP seems like a similar program so I would like to try to learn the basics of ZAP too. Update: I found this really nice and on point video from John Hammond where he explains the basics of burp and setting the DVWA application using a docker container. It is a really nice down to earth video and one of the best. The other source would be hackersploit videos on burp on youtube.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/G3hpAeoZ4ek"&gt;Burpsuite Basics&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;So the next step is, I am going to run dirb against it, you can use wwwfuzz dirbuster, there are a lot of programs you can run. I just run dirb.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dirb http:10.10.10.6 -r -o tmp.dirb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;-r is going to make it so it doesn’t go into recursive mode and -o saves it as output.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now what is actually dirb and what does it do? DIRB is a Web Content Scanner. It looks for existing (and/or hidden) Web Objects. It basically works by launching a dictionary based attack against a web server and analyzing the responses. Now, Ippsec turned off the reverse search this time because it would attack each subfolder of every folder and so on and so on. That's recursion. So it would take much time. Apparently this was not needed in this case but I learned what an recursive attack means. This is something familiar from Haskell. The output of dirb shows different pages on the server.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We have a &lt;a href="http://popcorn.htb/cgi-bin/"&gt;http://popcorn.htb/cgi-bin/&lt;/a&gt; (CODE:403|SIZE:287) It may be useful, we may wanna dirb this to see if there is any &lt;code&gt;cgi&lt;/code&gt; scripts. We have index, &lt;code&gt;index.html&lt;/code&gt;, &lt;code&gt;server-status&lt;/code&gt;, test is interesting. Let’s open up &lt;code&gt;test&lt;/code&gt;, and we probably have to turn intercept off, and we get the &lt;code&gt;php&lt;/code&gt; info page. This tells us a bunch of information about the server, most importantly it shows us where php scripts are cached so if we have a local file inclusion we may be able to chain some of the knowledge gained from this to give us code execution. So we’ll keep that in our pocket in case it’s useful. We also see a &lt;code&gt;/torrent&lt;/code&gt; link so I click this and see what this is. We do have an application, a torrent-hoster. So my first step is I generally always, and I say generally because I didn’t do it here, but I run &lt;code&gt;searchsploit&lt;/code&gt; against the app. &lt;code&gt;searchsploit&lt;/code&gt; is going to search &lt;code&gt;exploitdb&lt;/code&gt; but it’s all local so it goes really fast.&lt;/p&gt;

&lt;p&gt;And we do see one remote upload exploit&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I will have to finish the blogpost here for now and continue next time. I would like to blog more often than waiting for something to be finished. This took me couple of weeks and juggling between family obligations and work and hacking is hard. Next time I am going to continue commenting the popcorn and eventually popping it myself. In the mean time I am studying burp, then setting up my virtual lab with metasploitable2 and learning more about linux text processing tools. Being quick on the command line and learning to filter files taking into account permissions, users, wildcards and regex is something I need to work on. I have watched the next two boxes from Ippsec. One is October and that one seems hard for me to understand since I don’t know anything about buffer overflows. The Arctic seemed easier but it was a windows machine and Ippsec used metasploit. So there is much learning to come! I am happy and super excited about this. Until soon.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/4P23hSQKCeU"&gt;Tron popcorn&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>100 days of NixOS</title>
      <dc:creator>domagoj miskovic</dc:creator>
      <pubDate>Tue, 25 Jan 2022 19:20:06 +0000</pubDate>
      <link>https://forem.com/stablejoy/100-days-of-nixos-346e</link>
      <guid>https://forem.com/stablejoy/100-days-of-nixos-346e</guid>
      <description>&lt;p&gt;&lt;strong&gt;NixOS&lt;/strong&gt; operating system is a GNU/Linux distribution based on the &lt;strong&gt;Nix&lt;/strong&gt; Package manager. NixOS is a Linux distribution same as Ubuntu is a Linux distribution. A &lt;em&gt;distribution&lt;/em&gt; itself is a customized collection of software and tools packaged together with the Linux kernel. The kernel itself acts as a layer between the user-space where processes or programs live and the hardware, memory, cpu, devices and network devices that programs need to access to &lt;em&gt;do stuff&lt;/em&gt; and move bits and bytes around.&lt;/p&gt;

&lt;p&gt;How does the Nix package manager work and what is so special about the Nix package manager? Why should one care about it? There is a lovely intro with nice pictures about Nix and it's ecosystem on &lt;a href="https://nixos.org/explore.html"&gt;https://nixos.org/explore.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This first day of &lt;em&gt;100 days of code&lt;/em&gt; has a bit of story telling and then some installation details that will come a bit after. I will try to express some things I feel inspired about. I am a beginner and have very limited knowledge and experience of NixOS system except exploring it for less than a year with breaks. So this purely comes from my own experience and the love I feel for its design principles and the declarative approach.&lt;/p&gt;

&lt;p&gt;NixOS system together with the Nix package manager and the Nix programming language is a &lt;em&gt;provisioning&lt;/em&gt; kind of operating environment. What does this really mean? Essentially, to put it simply, you are not supposed to actually do anything. You are supposed to define your actions using a lazy functional domain specific language called Nix to do the stuff for you. You write the wishes and instructions as functional code declarations or recipes and then the system does what you ask it to do. Now, the real difference lies in the fact that you are not simply writing down the commands, automating the steps that you would have to do by hand like in other distros or even on Windows. With Nix you are writing &lt;em&gt;what&lt;/em&gt; and not &lt;em&gt;how&lt;/em&gt;. You are actually using a functional language to express the way packages are built, the way your entire system will be. How cool is that?&lt;/p&gt;

&lt;p&gt;Yes, there are package managers like Ubuntu’s &lt;code&gt;apt-get&lt;/code&gt; and &lt;code&gt;apt&lt;/code&gt; through which we install software by directly interacting with the manager, executing commands in real time such as &lt;code&gt;sudo apt install some-program&lt;/code&gt; and &lt;code&gt;sudo apt remove that program&lt;/code&gt;. But what actually happens when something goes wrong? How do you go back? What happens when your version of program does not play well with the rest of the system? What happens when something breaks and you wish you go back? What happens when you simply would like to try out something within a container like environment? With other package managers I am manually entering the commands. Even with an Ansible like playbook I would still have to write &lt;code&gt;apt install&lt;/code&gt;. I would still have to write the &lt;em&gt;how&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;With Nix you are defining the system and the system then takes care of the commands and the how.&lt;/p&gt;

&lt;p&gt;For example, how do you declare a new user into the system? What is a user in this case?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A User is a human being who operates a computer in the real world. If a user writes and compiles a computer program, the program, inhabiting the micro-civilization in the computer world, often looks exactly like his or her user counterpart in the real world, though exceptions exist for data pushers and programs written by multiple users. Users normally communicate with their programs by speaking or typing commands into their computers; on the other side of the screen, programs receive these impulses as "calls" which summon them to I/O towers to trade information with the other world. Many programs regard their users, both those who write programs and those who simply use them, as akin to gods, while others have been known to reject, deny, or attempt to manipulate them.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Define a user account. Don't forget to set a password with ‘passwd’.
  users.users.dom = {
    createHome = true;
    isNormalUser = true;
    extraGroups = [ "wheel" "video" "audio" "disk" "networkmanager" ]; # Enable ‘sudo’ for the user.
    group = "users";
    home = "/home/dom";
    initialPassword = "nixos";
  };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here we have a user:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwbcvel3xtiu1w3bpfk1o.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwbcvel3xtiu1w3bpfk1o.jpeg" alt="user" width="696" height="464"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ok I love Tron and I fight for the users. Now,&lt;br&gt;
this user declaration is from the &lt;code&gt;configuration.nix&lt;/code&gt; file that defines my current freshly installed NixOS system. It is a simple bare bones configuration file written in a text editor. The beauty is I can write it all there, all the apps, services, the users, the settings, and so on, and the nixos will rebuild the system with these specifications. I just want to boot into a usable system and then work from there. &lt;/p&gt;

&lt;p&gt;There are many complex nix configuration setups and some of those are simply amazing, integrating git actions, binary caches, home manager, but I wanted this time go from the vanilla beginning again.&lt;/p&gt;

&lt;p&gt;So in any other Linux system you might add a user with:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;# useradd -m -G additional_groups -s login_shell username&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Yes, in Ubuntu maybe that is not needed, maybe you could click something and click your way through and setup another user. In Windows it is similar. There are some graphical interfaces from where you create a user. But with nix you simply &lt;em&gt;declare&lt;/em&gt; it in a file as code, and then the system creates the user for you. &lt;/p&gt;

&lt;p&gt;There is no work to be done except thinking about it and writing it down. You are also not learning or going through a variety of ways of how one can create, what one needs to click and so on, no, you are simply declaring what you want. This is very profound. There are much more complex examples like setting a database server with a user and installing for example python too. But again, one is declaring that without writing commands like &lt;code&gt;install this&lt;/code&gt;. This is simply profound. This code can then be shared and reproduced with other users without worrying of the current state of other systems.&lt;/p&gt;



&lt;p&gt;Here I begin again the 100 days of NixOS challenge. My previous attempt was at &lt;a href="https://hackernoon.com/100-days-of-code-death-of-summer-on-the-island-of-nixos-gd1a3ws8"&gt;https://hackernoon.com/100-days-of-code-death-of-summer-on-the-island-of-nixos-gd1a3ws8&lt;/a&gt; and also I documented some of my explorations on my github page at &lt;a href="https://dooygoy.github.io/nixos-zoo/"&gt;https://dooygoy.github.io/nixos-zoo/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then I became a parent a year and a half ago and so after a while my laptop ended up with a windows 10 installed instead. The background is that I am not an IT professional, or as Big Pun would maybe have said it, I am not a player, I just love IT a lot. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs01rms22k6duiqwuz9p7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs01rms22k6duiqwuz9p7.jpg" alt="Big Pun" width="800" height="1066"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Learning about parenting was hard at times, so I have stopped exploring Haskell  and categories, and NixOS too after being with it for less than a year, but I came back just now. What changed? Well I learned as a parent that it is OK to learn in small bits, to find time when there is some, and keep learning without stressing how there is not much time.&lt;/p&gt;

&lt;p&gt;NixOS ecosystem is a huge time investment but no worry, it is worth it, and while learning it, it might just happen that some other things become more clear and less confusing. The same thing happens with Haskell and learning about category theory. Although I ended up not actually implementing anything in Haskell, and most of my time I just wrote simple bits of code and tried to visualize functional structures, recently when I read some python code it made much sense to me, it seemed simple if I may say. Generally, learning functional programming helps in thinking about processes in a relaxed, space-like abstract level. You are not so concerned with the implementation but the meaning of it all, and what are the things that make the problem at hand. Something similar happens with NixOS. NixOS does seem hard and has a steep learning curve, but it also has a huge payoff in terms of understanding what is actually happening with the system. With Archlinux I was involved with the configuration of the system but it seemed more manual to me at times. I didn't automate anything back then but the NixOS invitation seemed much more appealing, something struck me the first time I glimpsed into the depths of the Nix ocean. Instant rollbacks to any previous time generation, rolling a virtual machine in an instant and bunch of other things I do not even understand yet.&lt;/p&gt;

&lt;p&gt;Once you taste the fully declarative approach of the Nix package manager that makes the NixOS, it comes to your mind from time to time this provisional idea, and then it erases all your darling distributions and operating systems that you interacted with before. It comes to your mind when you download a phone app, or need to reinstall a package, or need to wait for a windows update that tries to talk you too. Suddenly, with NixOS, it is all there in the open, all expressed as nix expressions.&lt;/p&gt;

&lt;p&gt;Well, what I really mean to say is that NixOS is something you secretly longed for if you ever spent time tinkering with archlinuxes and windowses of the world, but you still don’t know it. There is this feeling once you get the subtle idea of NixOS you realize, oh my, I can’t go back after this. I would only fool myself.&lt;/p&gt;

&lt;p&gt;And now I stop the romantic ouverture and begin with the concrete steps I made during the installation.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Since I am on Windows 10 I use the program called Rufus to create a USB bootable stick with &lt;a href="https://nixos.org/download.html"&gt;NixOS 21.11 GNOME edition&lt;/a&gt;. I burn it in dd mode.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I disable secure boot option in BIOS setup since this is still not fully resolved with NixOS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;NixOS boots into Gnome desktop environment! Yay! My external wifi usb dongle D-Link DWA-121 is instantly recognized. Awesome! I can connect to my wifi and begin the installation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I start GParted and erase all windows partitions. Then I exit the program.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I check my disks with the &lt;code&gt;lsblk&lt;/code&gt; command in the terminal and there it shows my disk.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I used to have NixOS with zfs but I haven't learned anything about the filesystem. This time I go for the encrypted Btrfs root and unecrypted 10G of swap partition and a boot partition. I follow this &lt;a href="https://jappie.me/nixos-on-encrypted-btrfs.html"&gt;nixos on encrypted btrfs&lt;/a&gt;. This time I would like to learn more about filesystems too.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I am surprised at how fast the installation goes, I follow all the steps and then I simply add a user and some minor settings. I &lt;code&gt;nixos-install&lt;/code&gt; and then it boots right into NixOS! Wow!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;But now, now the adventure truly begins!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is my simple &lt;code&gt;configuration.nix&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
    # Edit this configuration file to define what should be installed on
    # your system.  Help is available in the configuration.nix(5) man page
    # and in the NixOS manual (accessible by running ‘nixos-help’).

    { config, pkgs, ... }:

    {
      imports =
        [ # Include the results of the hardware scan.
          ./hardware-configuration.nix
        ];

      # Use the systemd-boot EFI boot loader.
      boot.loader.systemd-boot.enable = true;
      boot.loader.efi.canTouchEfiVariables = true;

      nixpkgs.config.allowUnfree = true;

      networking.hostName = "lapchi"; # Define your hostname.
      # networking.wireless.enable = true;  # Enables wireless support via wpa_supplicant.
      networking.networkmanager.enable = true;

      # Set your time zone.
      time.timeZone = "Europe/Zagreb";

      # The global useDHCP flag is deprecated, therefore explicitly set to false here.
      # Per-interface useDHCP will be mandatory in the future, so this generated config
      # replicates the default behaviour.
      networking.useDHCP = false;
      networking.interfaces.wlp0s20f0u2.useDHCP = true;

      # Configure network proxy if necessary
      # networking.proxy.default = "http://user:password@proxy:port/";
      # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";

      # Select internationalisation properties.
      i18n.defaultLocale = "en_US.UTF-8";
      console = {
        font = "ter-i32b";
        packages = with pkgs; [ terminus_font ];
        keyMap = "us";
      };

      # Enable the X11 windowing system.
      services.xserver.enable = true;
      services.xserver.libinput.enable = true;

      # Enable the GNOME Desktop Environment.
      services.xserver.displayManager.gdm.enable = true;
      services.xserver.desktopManager.gnome.enable = true;

      # Configure keymap in X11
      services.xserver.layout = "us";
      # services.xserver.xkbOptions = "eurosign:e";

      # Enable CUPS to print documents.
      # services.printing.enable = true;

      # Enable sound.
      sound.enable = true;
      hardware.pulseaudio.enable = true;

      # Enable touchpad support (enabled default in most desktopManager).
      # services.xserver.libinput.enable = true;

      # Define a user account. Don't forget to set a password with ‘passwd’.
      users.users.dom = {
        createHome = true;
        isNormalUser = true;
        extraGroups = [ "wheel" "video" "audio" "disk" "networkmanager" ]; # Enable ‘sudo’ for the user.
        group = "users";
        home = "/home/dom";
        initialPassword = "nixos";
      };

      # List packages installed in system profile. To search, run:
      # $ nix search wget
      environment.systemPackages = with pkgs; [
        vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
        wget
        firefox
        tree unzip unrar
      ];

      # Some programs need SUID wrappers, can be configured further or are
      # started in user sessions.
      # programs.mtr.enable = true;
      # programs.gnupg.agent = {
      #   enable = true;
      #   enableSSHSupport = true;
      # };

      # List services that you want to enable:

      # Enable the OpenSSH daemon.
      # services.openssh.enable = true;

      # Open ports in the firewall.
      # networking.firewall.allowedTCPPorts = [ ... ];
      # networking.firewall.allowedUDPPorts = [ ... ];
      # Or disable the firewall altogether.
      # networking.firewall.enable = false;

      # This value determines the NixOS release from which the default
      # settings for stateful data, like file locations and database versions
      # on your system were taken. It‘s perfectly fine and recommended to leave
      # this value at the release version of the first install of this system.
      # Before changing this value read the documentation for this option
      # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
      system.stateVersion = "21.11"; # Did you read the comment?

    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Haskell day 85 - counting, describing type and function spaces</title>
      <dc:creator>domagoj miskovic</dc:creator>
      <pubDate>Thu, 04 Feb 2021 05:02:53 +0000</pubDate>
      <link>https://forem.com/stablejoy/haskell-day-85-counting-describing-type-and-function-spaces-2nip</link>
      <guid>https://forem.com/stablejoy/haskell-day-85-counting-describing-type-and-function-spaces-2nip</guid>
      <description>&lt;h1&gt;
  
  
  Types
&lt;/h1&gt;

&lt;p&gt;This post explores the &lt;em&gt;types and functions&lt;/em&gt; tutorial by @typeclasses. Their tutorials have this a bit different kind of teaching method, besides pure formalism they seem to try to teach by talking about things, but then at the same time thinking with and through types seem to be very conducive to a different kind of teaching method, different kind of wisdom in which without explicitly stating the set of instructions, for example what needs to go where and when, without merely pointing into the horizon, types take on a much more receptive role and invite the student and the teacher to a different kind of mental state, a much more intuitive, &lt;em&gt;slower&lt;/em&gt; state in which there seems to be much more thinking involved within more precisely formed units. Also each definition could have an infinite number of teaching methods or vehicles which might illuminate certain aspects of it, at the same time there is an infinite number of past or future analogies one could use, for example think of the identity or a boolean value. Still, at the same time because of the functional purity and referential transparency and because no information seems to be discarded within imperative lossy flows, higher and more complex abstraction could be realized by composing these basic abstraction units. So something such as a functor is essentially one of the most precious things there is, and once a student learn about these transformations the student realizes that there are more of those types of transformations. Upon realizing such structures an emotional inspiration arises precisely because these abstraction contain themselves within themselves, so to say they scale perfectly in unison, and so one feels empowered more and more while retaining knowledge to a much higher degree, essentially purifying the view within the mind, or to use the term garbage collecting any knowledge. You could say there is not much garbage to be purified while thinking in pure functions since each and every one of them, totally return what they are asked for.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We can think of types as being like &lt;em&gt;sets&lt;/em&gt;. When we think about numbers, for example - "numbers" is not itself exactly a set. There are different sets of numbers that are useful for different things.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But this brings to mind that there might actually be an infinite limitless number of these sets of numbers, because there are so many ways to count things, some more, some less useful than others. Besides the usefulness of a counting action, the process of numbering things or objects, we also can analyze how many there are ways to count. But then comes the question could there also be a way to count a finite set of numbers using an infinite amount of numbers, basically never reaching the last finite number of the set? But why would anyone do that? This could be like using every possible real number from the number line to count from 1 to 10, we might never reach even the number 2! We notice there is a certain shape how the counting process evolves, what is this actual movement of the counting process, some numbers seem to flow so to say evenly in the sense that there seems to be an equal distance between each numeral of the counting range, like from 1 to 2, from 2 to 3 and so on while some numbers seem to progress in a different way, seemingly going deeper as in 1.1, 1.11, 1.111.. but then I wonder is this really counting? I read about &lt;em&gt;surreal numbers&lt;/em&gt; which are like progressing in a really fascinating way, like they have dual nature, one part of them counts in one way, the other one in a different and both parts of one number consist of one count, as if one number had two numbers within in order to make the count, but I should read more about these surreal numbers, I have no idea how they work. Still sometimes we take for granted the notion of a number and we spend our lives counting with naturals but there is nothing natural about natural numbers, even the name seems confusing at first, why are they called natural, is it just because we have five fingers on each hand? Or twelve little joints on each hand too?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6pq5xdxmel5q63hwc077.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6pq5xdxmel5q63hwc077.jpg" alt="Alt Text" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Still to continue the pursuit, if there are numerous ways to count things, and if there are numerous sets of these numbers then there are also an infinite number of types as well! But still, the mere mention of a certain &lt;em&gt;type&lt;/em&gt; we seem to forget about the size of the set but begin to think about what such a set could contain, how could it be described, because types seem to be described in a much more detail than just a simple number.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What we call numbers are not a fixed set of things, but a group of sets that have some things in common. For example, we can do addition with members of any of these sets - we can add integers, we can add natural numbers, and we can add rational numbers..&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So there are all these operations which we can use with different kinds of numbers, which in turn produce different results, depending on how we want to count something. Hmm, what about these operations then? So there are different types of numbers, different types of things which could have potentially an infinite number of operations defined over them so that means there are also types of collections of operations that could be defined over our space of a variety of number types. How would&lt;/p&gt;

&lt;p&gt;Now comes the kicker. In the next paragraph it says that &lt;em&gt;In Haskell, the concept of "being a number" is represented through a typeclass.&lt;/em&gt; OK, I actually thought that the concept of a number would be represented as a type since for example a type natural contains all the naturals and a type rational contains all the rational numbers and so on but here I stumble on something else. It continues with &lt;em&gt;We have types in Haskell which are like sets, and we have classes - which is sort of a larger concept - that defines some operations that multiple sets have in common.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Fascinating! So basically types are just like images, or like certain actors within some domain and a typeclass is like a collection of these types, these actors and some number of operations or events that are possible to happen between them. So in our number case the type would be a natural or a rational and these types of numbers would then belong to a larger all pervasive &lt;code&gt;Num&lt;/code&gt; typeclass, which is a collection of different types of numbers, different instances of one typeclass. The unique thing that connects them is simply that they are all types of numbers with some operations defined over these numbers because we need operations if we want to do something else besides simply counting from the lowest to the highest number. We naturally come to define other operations when our conditions change. If we were to count how many people are in a room we would start counting 1,2,3 until we reach the last person and so on but if suddenly 10 people were to leave we might just want to simply subtract those 10 from the total number of people instead of counting again from the beginning. This is especially useful if there are a million people in the room and 10 people leave, who would want to start the count all over again? But then does the computer actually count again from the beginning? Is a list of people being counted from the beginning and then if some are to be erased will the computer count again from the beginning? How does the program count the list of people then if it &lt;em&gt;can't see&lt;/em&gt; that 10 people are missing from the room? This is a question that has to do with how lists, a basic data structure is implemented and how the computer constructs these structures.&lt;/p&gt;

&lt;p&gt;What if you could not count at all? What would be the simplest possible way you could count things? You could simply say a word, like "DA", and then "DA" over there, and then "DA" and all the numbers would be "DA". This is very simple, like seeing every thing in the world as a toy you reach out point towards it and happily say "toy!", this is a "toy"! and so on. So this is like a type that is not numeric in the previous sense but that has only two values within, called &lt;code&gt;Bool&lt;/code&gt;. So instead of DA this type can describe things with &lt;code&gt;True&lt;/code&gt; and &lt;code&gt;False&lt;/code&gt; which actually seems like the minimum amount of abstract movement one can make within ones mind. Something could be here or there, something could be true or false, but is it really like that? Is our Bool something like a simple DA? Well maybe it is not, since it contains two symbols. The DA would seem to be some kind of identity which does not even affirm the thing being pointed at, it merely repeats the same thing over and over again without regard to which thing we provide it. So if we give it an apple it says DA, if we give it a string it says DA, is this some kind of an identity? But an identity would be like &lt;code&gt;identity :: a -&amp;gt; a&lt;/code&gt; and in our case this seems more like &lt;code&gt;da :: a -&amp;gt; da&lt;/code&gt;. What is this then? Aha! This might be that super cool type called &lt;code&gt;Void&lt;/code&gt; which always returns void. But why void, is it because it makes no sense and only introspects within itself like a black hole, like some void without any bottom anything that we throw at it becomes simply void? So like DA, void is a form of DA, fascinating!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;But can we think of a typeclass, maybe, that could include both character types and numbers? What could a set of characters and a set of numbers have in common?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yes! When we use numbers we often like to use words too, words that have meanings so what would such a type look like that would contain both words and numbers within. One needs to be a bit more precise because when we say words and numbers what we actually mean are characters and numbers, because characters form words not the other way around, but then some words do form our character too, now that might be confusing, but so words are, they are awfully confusing with many meanings! But let's come back to the question of &lt;em&gt;What could a set of characters and a set of numbers have in common?&lt;/em&gt; Well this is deep, I am kinda staring into the darkness and thinking...&lt;/p&gt;

&lt;p&gt;So I look into the other window and there it says, &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;...they can be put into an order. There's a typeclass for that, called &lt;code&gt;Ord&lt;/code&gt;. That's where the comparison operations like greater thn (&amp;gt;) and less0than (&amp;lt;) are. One value is less than another (x &amp;lt; y) if x comes before y in ordering.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now what is actually happening here? We are actually not counting now but it seems to me we are &lt;em&gt;arranging&lt;/em&gt; the counting numbers into an order, as if we already did the count and now the numbers got all mixed up so we rearrange them again into the counting order. But the thing with order is that it seems we do not have to do the count again, we just have to order them, we put the smaller number before a larger number or maybe do any ordering operation we like. Why are we ordering things? Well we order things all the time, even our thoughts come completely in an unordered form in o ur heads and then we suffer mentally because we are unable to order our thinking so that we don't suffer. Maybe all suffering consists of unordered thought and our brains which love types and mathematics cannot stand that, they cannot stand that some thoughts are larger and some are smaller and then it wants to order things. There is something beautiful and all encompassing when we look at an ordered field, it somehow looses the individual particularities, those numbers that jump out or fall back. An ordered field is like an empty space, each individual unit is like being aware it is a part of something greater than itself, each number is at the right place at the right name. We also understand things much better when we order them and have a better sense of their individual characteristics when we order them. &lt;/p&gt;

&lt;p&gt;But what happens when we see two instances of the same number, of the same thing in front of us, is this even possible? What if there are two equal things or isn't everything actually unique in itself? Are two oranges equal? Well if we are simply counting 2 oranges and 10 apples then maybe yes two oranges are equal and 10 apples are equal, it seems it all depends on what kind of an abstraction level we are standing upon. Some things seem to be equal and then those same things are not when we look at it from a different poin of view. Equality seems like a super deep question, that might be the last question there is? Could it? Well Haskell has an equality class of types called &lt;code&gt;Eq&lt;/code&gt; which has an operator &lt;code&gt;==&lt;/code&gt; which is tests for equality. But what is the difference between the double &lt;code&gt;==&lt;/code&gt; and a single &lt;code&gt;=&lt;/code&gt;? A single &lt;code&gt;=&lt;/code&gt; seems to be forcing us to observe some result from some action while &lt;code&gt;==&lt;/code&gt; is like simply measuring if two sides of an equation are the same. But then why the equations I did in the elementary school contained only a single equality sign and not &lt;code&gt;==&lt;/code&gt;? Maybe because the result was being mixed with the action itself, so some unknown variables were being added and then the result was also intermixed with some extra variables, the result was hidden, obscured so we had to extract the single unknown variable which was the result. This still seems different than the double equality sign. But then how would you judge what is equal, it seems there are infinite levels of double equality signs, meaning there are all kinds of equalities around, some more tight some loose to use a slightly loose terminology...&lt;/p&gt;

&lt;h2&gt;
  
  
  Functions
&lt;/h2&gt;

&lt;p&gt;Now if types were to be understood as concrete images then functions would be like moving images, like movies of those images, just in our case our movie could be arranged in all kinds of ways, we would not have to go only from the beginning to the end but we could like in the recent Nolan movies Tenet go back and forth in time while at the same time some other timeline could meet us in the future. We could arrange our images into whatever we want because we are not bound by the meaning of these images. When we describe a meaning it is usually set in some temporal shape, into some timeline, this is what meaning basically means, but then the more actors we perceive, the more events we engage with the more our timeline warps into itself and introduces different time-shifts within. OK, so what are functions, these super exciting movable objects. Wait are functions objects? Or are they functions? A function is more like an action, so how would we compare an action with an object. Well maybe if we understood an action as an transformation then maybe we could call that particular type of a transformation an object? Hmm..&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;On the left we have numerals, on the right we have the words for numbers, and we are asked to draw a line from each numeral to how it's spelled. In our elementary schools we had to do a lot of these kinds of exercises. This is our mental picture of what defining a function is like: drawing lines from the things on the left to the things on the right, based on some rule that tells us what makes the matching meaningful. A function is a description of how an element from one set gets matched to an element in another set.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is a really nice description of how a function works. Let's check the Wikipedia one which is a bit more formal but still the same:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A function is a process or a relation that associates each element x of a set X, the domain of the function, to a single element y of another set Y(possibly the same set), the codomain of the function. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The one before that is also a bit more compact:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;a function is a binary relation between two sets that associates every element of the first set to exactly one element of the second set. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But let's return to typeclasses where a simple program is introduced! Yay enough theory!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;spell&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Integer&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the &lt;code&gt;spell&lt;/code&gt; is the function name then the &lt;em&gt;empty square with only corners shown&lt;/em&gt; or a double colon sign which symbolizes the action of saying &lt;em&gt;has a type&lt;/em&gt; or basically what the double colon means is that it is raising the abstraction level from naming things into describing which kind of processes are to be uniquely identified with that name, so could our &lt;code&gt;spell&lt;/code&gt; be actually an object? Could this &lt;code&gt;spell&lt;/code&gt; function be understood as an object? Why? Because it has a name? Is every thing that has a name an object too? OK, so what does Integer and String represent here, they represent the &lt;em&gt;domain&lt;/em&gt; of our process and the &lt;em&gt;codomain&lt;/em&gt;, which is like the starting point of our transformation and the endpoint of our transformation. Now it might be the truth that actually the domain and codomain are basically the same thing, though they might seem different if we look at it from a temporal perspective, after all a broken egg is still an egg but it is broken only after and not before so some kind of transformation did take place. So is it then &lt;code&gt;breakfast :: whole egg -&amp;gt; broken egg&lt;/code&gt; or maybe &lt;code&gt;sunny side up :: whole egg -&amp;gt; broken egg&lt;/code&gt;? But let us continue with the typeclasses code example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;spell&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Integer&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;

&lt;span class="n"&gt;spell&lt;/span&gt; &lt;span class="n"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="kr"&gt;case&lt;/span&gt; &lt;span class="n"&gt;int&lt;/span&gt; &lt;span class="kr"&gt;of&lt;/span&gt;
     &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"one"&lt;/span&gt;
     &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"two"&lt;/span&gt;
     &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"four"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to be continued...&lt;/p&gt;

</description>
      <category>haskell</category>
      <category>functional</category>
      <category>100daysofcode</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>day 86: a semigroup of haskellers and a logician walks into a bar</title>
      <dc:creator>domagoj miskovic</dc:creator>
      <pubDate>Sun, 13 Dec 2020 07:59:35 +0000</pubDate>
      <link>https://forem.com/stablejoy/day-86-a-semigroup-of-haskellers-and-a-logician-walks-into-a-bar-569a</link>
      <guid>https://forem.com/stablejoy/day-86-a-semigroup-of-haskellers-and-a-logician-walks-into-a-bar-569a</guid>
      <description>&lt;p&gt;It is 2018. I live in New York City and I am going to NYU to hear a lecture on semigroups, lattices and duality by a visiting expert in the field, who came over from Amsterdam. After the lecture we talk about music composition and some weeks after begin to exchange emails about math and music, he wonders what is music, what does it all mean, what is its connection to math? He seems super nice. The four hour long lecture is a part of an ongoing series of meetings by local mathematicians, category theorists and functional programmers, mostly Haskellers from the local Haskell and lisp meetup. I am happy, amused and excited by the gathering especially since I do not understand almost nothing being said. But I hold my attention for the whole duration and keep my mouth and my mind shut completely. I hold my gaze at the lecturer and carefully observe what is happening in the group giving it my full attention by taking away any obscuring thought I could have at that moment. You could say I meditated, tried to remain calm with concentrated awareness. &lt;/p&gt;

&lt;p&gt;Why am I interested in abstract non sense? I am a trained classical musician, since early childhood, and have practised an instrument for long hours every day. I practised the art of listening for long durations, listening to sonic relations which have no apparent semantic meaning, at least not any common, real world semantic meaning that I know of. A sonic space does not tell a story although it could, no, it is defined by sound, by how the sound moves, as if the sound itself is some kind of life-form that speaks a language unknown to you, but you can listen to it and the best of all, strangely it can make you feel! Most of all you do not criticize it and find errors in it, the better you get the less wrong notes sound like wrong notes, and more like interesting occurrences.  These feelings are the same ones you know but there are also subtle ones, that can only be described by words such as sublime and grace. But there is also a deeper semantic meaning to all this, some kind of mathematical structure to it all, something that maps within different regions in the mind, in the body itself. If sound was a type of a body since it has an origin and a trajectory and can be felt, certain relations move within in a variety of ways. There is something deeply intuitive in all this. I wondered about this from time to time, and its not about C majors and F minors, and G minor scales. These are all afterthoughts made to deconstruct this landscape into something tangible, something physical, something to be seen and not intuitively felt. &lt;/p&gt;

&lt;p&gt;After the lecture he takes some questions and someone carefully develops for almost 10 minutes one question. The lecturer brushes it off saying: No, this is not that, this is something different. But then the mathematician rephrases it again and yet again the lecturer thinks for a second and says.. no.. its not that too.. it could be this or that, but its not that… He didn't really say this but in some sense he didnt really approach the question inclusively, it seemed he dismissed it as inappropriate for that context.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp3faegv0ovyf1h4p7a20.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp3faegv0ovyf1h4p7a20.jpg" alt="Alt Text" width="800" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Among those people is is a cool old logician Jaz Sulzberger who I already met one time in a Lisp meetup, who will give me a lecture of a lifetime on Curry Howard correspondence later in the bar over drinks, when the rest of the Haskellers leave. Some of them seem to be annoyed by his remarks and enthusiasm. I can tell that by the way their faces look down while he speaks about some obscure thing, or begins to inject a variety of related arguments into the discussion. I almost feel sorry for him and at the same time feel inspired by that teenage feeling when being in the presence of a master, when you see no one else, when all you think of is just being in the presence of your master, when imitation is the only form of art you do. When you even try to breathe and make facial expressions as the master. Here is a lecture of his and there are more: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://vimeo.com/39639153"&gt;https://vimeo.com/39639153&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is a picture:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7gtbomlmpgvzebavavk6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7gtbomlmpgvzebavavk6.jpg" alt="Alt Text" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have studied categories on my own by following Milewski lectures on youtube with great enthusiasm and vigor, drawing diagrams on my two room windows in Brooklyn. There is something strange and captivating about category theory, it seems like a perfect abstract tool, something to be discovered rather than operationally invented. I spend the Summer reading dialogues of Plato and notice abstract structures repeating, similar structural entities in which different arguments are injected, in which truth is told and yet there was an abstract notion of yet another kind of truth, the one not talking about objects at all, but simply talking about kinds of transformations that were happening within that space. But I could not find anything written about those happening. I read Hegel and Zizek too and wonder how cool it would be to put some of the philosophy into code but a notable Haskeller tells me over the table: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Hey I just hate philosophers, I can't stand them"&lt;br&gt;
"Oh really? How come?"&lt;br&gt;
"I just can't stand them"&lt;br&gt;
I gaze silently at him and hold my drink. I switch them my view to the logician. I was saddened by that response. I was waiting for some discussion. Seems to me functionally strange to hate something..&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They all leave after few drinks and I stay there with the logician who tells me a story about the Curry Howard Isomorphism. He tells it like the fate of humanity depends on it, today I need to hear it if I want to save the Earth tomorrow. It seemed so important and his tour de force way of going through that forest of arguments made me mesmerized. Again I did not understand a single word, not that I remember now. But I listened closely to him, I watched him, I felt no fear, no boredom, I just followed the words, having faith that eventually I will learn the language. I felt that intuitive hold on my consciousness, the excitement of listening to something unknown to me, something defined by rich relations, something not plain obvious. I often hear how people have much difficulty in engaging something they do not understand and I find that deeply sad. I guess I felt the it more important to be engaged into something with the whole body and mind then just following along something which merely confirms what I already know. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fl80p39a3e3qozbef9pas.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fl80p39a3e3qozbef9pas.jpg" alt="Alt Text" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At the end I tell him, I admit it is all very difficult for me to follow and he tells me like a father, like a close friend:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hey, don't worry, I didn't understand a thing in the beginning, in time you will know, you will begin to understand. Tell me your name, what is your name.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;He wrote my name in his scrapbook and left. I am so grateful to that wonderful logician and I send him warmest hugs where ever he is. Thank you!&lt;/p&gt;

</description>
      <category>haskell</category>
      <category>100daysofcode</category>
      <category>functional</category>
      <category>math</category>
    </item>
    <item>
      <title>Day 87 :: Haskell Holmes tells Watson how to curry sheep</title>
      <dc:creator>domagoj miskovic</dc:creator>
      <pubDate>Fri, 06 Nov 2020 14:32:06 +0000</pubDate>
      <link>https://forem.com/stablejoy/day-87-haskell-holmes-tells-watson-how-to-curry-sheep-2c5g</link>
      <guid>https://forem.com/stablejoy/day-87-haskell-holmes-tells-watson-how-to-curry-sheep-2c5g</guid>
      <description>&lt;p&gt;&lt;strong&gt;Watson&lt;/strong&gt;: Sherlock, I've been meaning to ask you something about pure functions. How do you define these functions, I mean I understand that functions and function types seem to be like morphisms, ephemeral entities that transform data like abstract ideas, a structure describing a pure relation, like &lt;code&gt;f :: e -&amp;gt; e&lt;/code&gt;, a computational context into another kind of context, at least the higher order functions do that, the ones that take functions as arguments which take functions as arguments...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Holmes&lt;/strong&gt;:... But Watson all Haskell functions take functions as arguments, it's actually quite simple, we pass functions to one another and solve our problems, the more a problem seems complicated so we call and combine more complex functions, by complex I mean appropriate for that specific domain, or more abstract and structured. The process is somewhat dual to my deductive method, it just begins bottom up instead top down. &lt;/p&gt;

&lt;p&gt;Listen Watson, try to follow me now and I will show you how we do that. Imagine you were to just count sheep upon some green hill, imagine yourself as a shepard counting sheep, and please Watson try not to fall a sleep. So you see a sheep, call it &lt;code&gt;a&lt;/code&gt; and count one, then you call a function, call it &lt;code&gt;f&lt;/code&gt;, which adds numbers. How does it add numbers? Well it is defined by a method you could say, like a method that describes a typeful operation, &lt;code&gt;(+) :: Num a =&amp;gt; a -&amp;gt; a -&amp;gt; a&lt;/code&gt;. Now this function adds numbers, it is a method to add things. If you observe the method carefully you will see that the plus sign, &lt;code&gt;(+)&lt;/code&gt;, is constrained to an operation, defined to add numbers, all the numbers which belong to a whole class of number, so &lt;code&gt;(+) :: Num a&lt;/code&gt; would mean just that. The rest of the declaration says that the plus function takes an &lt;code&gt;a&lt;/code&gt; variable and returns a variable &lt;code&gt;a&lt;/code&gt; and then returns another variable &lt;code&gt;a&lt;/code&gt;, more correctly said a plus function takes a variable and returns a plus function that takes a variable and returns the result. We can visualise this as &lt;code&gt;(+) :: Num a =&amp;gt; a -&amp;gt; (a -&amp;gt; a)&lt;/code&gt;. Notice the beauty in the fact that plus is defined over numbers and yet we can use it to count sheep, how great is that?! Now forget all that mambo and remember we just saw the first sheep and we have an idea of a number, number &lt;code&gt;1&lt;/code&gt;, now what do we do?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgss9rl6tiwt9p374l53c.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgss9rl6tiwt9p374l53c.jpg" alt="Alt Text" width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Watson&lt;/strong&gt;: Well we look at some other sheep, preferably the one next to it and count that one as two.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Holmes&lt;/strong&gt;: That's brilliant Watson, please fetch me some tea from the replicator! Tea Earl Grey, hot! Well Watson, that is true but try to look beyond, try to abstract away the whole process of counting, it makes no difference that we are counting the sheep next to that first one as number two, and also Watson, there is something dark and sinister happening here. Imagine that you are an idiot, a complete idiot and that you had no idea how to count, imagine that! Haha! What if we could not count?! Imagine you had no idea to count at all, could you? What would you do then?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Watson&lt;/strong&gt;: So I have to count sheep but at the same time I cannot count, I don't have the slightest idea of how to even begin to count? I guess I would call someone who could count for me, who would know how to count? Someone like you naturally I presume?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fx7to359eir291tzh9dnd.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fx7to359eir291tzh9dnd.jpg" alt="Alt Text" width="618" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Holmes&lt;/strong&gt;: Well yes, but you might be taking this game a bit too far into the concrete realm, now imagine you cannot count, so as you say you would call me. Could you say you would call some function be it me or someone else to count the sheep for you? A function after all is some morphism that transforms data, it is more than just a value, it takes a value in and produces a value, it returns a value, and it always returns the same value if it is provided with the same input value. Our function is a pure function, it is defined totally over the whole space of its arguments! I mean if we provide our function two sheep it better count them one, two, equals two right? It's just now quite like that you will find out, the function will simply take one sheep and output another function which will return the one plus the second sheep. But I am getting a head of myself, like taking a head of an empty list it is too early for you to understand what is going on. Just follow along!&lt;/p&gt;

&lt;p&gt;So to get back at our counting adventure you count one sheep and than you call me or let's say our holmes function and ask it to count for you. Now what does the holmes function do then? It simply takes the second sheep as its input and returns another holmes function that takes the third sheep as its input which then again calls another holmes function which takes the fourth sheep as its input and then again, it returns a function that takes...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Watson&lt;/strong&gt;: But wait a minute Holmes, so who is counting? And it seems to me each iteration, each new number we have another function, replicating itself, just taking the next number in line, but still no one is counting, I mean I still do not how many sheep there is in total? Also I don't think I can handle more than one Haskell Holmes, and now you are telling me there are a bunch of them!? Which one is going to sum up the whole list of these sheep??&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Holmes&lt;/strong&gt;: No worries Watson, my replicas will vanish as soon as the calculation finishes, except if you memoize me somewhere within a cache field, then I will remain for some time until you call me again. But never mind that, we will talk about memoization some other time, it is a quite fascinating idea! So basically, we call a new function for each number we add, passing a function to a function we share information, we do not count yet, or sum these numbers why would we? After all we must collect our 🐑 first, we must collect our objects before we add them. You see if we were to begin adding these objects immediatelly we would be making destructive updates creating state along the way and tell me where is the rush, if we want to be correct, truly correct and sure in what we are doing then we must collect them all and then sum them up. It is just our mind that immediatelly sums up these numbers and because notice Watson the number itself is actually the sum of all previous numbers. Look at it, the sheep number &lt;code&gt;5&lt;/code&gt; tell us not just that bit of information but that actually each number is a sum of all the previous numbers, have you noticed that? Have you?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Watson&lt;/strong&gt;: Oh my god, so a number &lt;code&gt;10&lt;/code&gt; is actually the tenth number and at the same time the sum of previous numbers? But isn't the sum of all previous numbers from one to ten, something else? &lt;code&gt;sum [1..10]&lt;/code&gt; is not &lt;code&gt;10&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Holmes&lt;/strong&gt;: Watson that is true but you are actually playing a smart boy now, because the correct list of an unknown number of sheep would be &lt;code&gt;[sheep, sheep, sheep, sheep, sheep, sheep ...]&lt;/code&gt; or to use a variable instead we have a list of things something like &lt;code&gt;[a, a, a, a, a, a, a, a, a ,a]&lt;/code&gt;. Do you see the difference? Now we have lets say ten individual units, ten &lt;code&gt;a&lt;/code&gt;'s which if we sum, if we add together we will get &lt;code&gt;10&lt;/code&gt;, but this does not apply to your example because summing numbers from one to ten is a bit different, a more abstract situation, because you already know the numbers you got, if would be like adding one sheep then adding two sheep, then adding three sheep on that hill over there, than imagine you had four sheep over there, look there, a bit further away, then look you have five sheep over there! How would we describe this?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdgfqgjxxatpj6268ozn6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdgfqgjxxatpj6268ozn6.jpg" alt="Alt Text" width="800" height="420"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="cm"&gt;{- let us unfold the list into its elements, 
[1, 2, ,3, 4, 5, 6, 7, 8, 9, 10]

1 + (2..10)
1 + (2 + (3..10))
1 + (2 + (3 + (4..10)))
1 + (2 + (3 + (4 + (5..10))))
1 + (2 + (3 + (4 + (5 + (6..10)))))
1 + (2 + (3 + (4 + (5 + (6 + (7..10))))))
1 + (2 + (3 + (4 + (5 + (6 + (7 + (8..10)))))))
1 + (2 + (3 + (4 + (5 + (6 + (7 + (8 + (9..10))))))))
1 + (2 + (3 + (4 + (5 + (6 + (7 + (8 + (9 + (10)))))))))
1 + (2 + (3 + (4 + (5 + (6 + (7 + (8 + (9 + (10 + ()))))))))
1 + (2 + (3 + (4 + (5 + (6 + (7 + (8 + (9 + (10 + 0))))))))
1 + (2 + (3 + (4 + (5 + (6 + (7 + (8 + (9 + 10))))))))
1 + (2 + (3 + (4 + (5 + (6 + (7 + (8 + 19))))))
1 + (2 + (3 + (4 + (5 + (6 + (7 + 27))))))
1 + (2 + (3 + (4 + (5 + (6 + 34)))))
1 + (2 + (3 + (4 + (5 + 40))))
1 + (2 + (3 + (4 + 45)))
1 + (2 + (3 + 49))
1 + (2 + 52)
1 + 54
55
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Take a look at this beauty Watson, enjoy this &lt;em&gt;linear recursive process&lt;/em&gt;! And mind you a list is a collection of homogeneous entities, meaning they are similar and uniquely different, you could say they have the same type...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Watson&lt;/strong&gt;: This calculation is amazing Holmes, and just look at it, how the program expands in time and space! How did you do that? But it looks awfully difficult too. I think I can manage to process until it unfolds completely, but then how do you put the numbers together, I mean it seems this is much better suited for computers than humans, but then again this process precisely describes the whole act of counting sheep! And somehow we are fully aware of everything what is happening at every step of the way. I imagine if we merely destructively updated the state with a counter it would look much simpler and yet all the magic would be hidden away! But wait a minute, this is not quite right, how would we sum just a bunch of ones?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))))))&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)))))))&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))))))))&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)))))))))&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))))))))))&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)))))))))&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))))))))&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)))))))&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))))))&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;
&lt;span class="mi"&gt;10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Watson&lt;/strong&gt;: So a list is a collection of numbers? What is its type, a number?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1er56n7e33ottxhhb60b.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1er56n7e33ottxhhb60b.jpg" alt="Alt Text" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Holmes&lt;/strong&gt;: Not quite, a list is a collection of objects, which yes are similar which yes could be numbers, but could also be sheep! We used the &lt;em&gt;numeral&lt;/em&gt; &lt;code&gt;1&lt;/code&gt; to count our sheep but really Watson is that even necessary at all? I mean you could use the variable, a letter &lt;em&gt;s&lt;/em&gt; for all I know and it would have been the same, we would still have to write &lt;em&gt;2ss&lt;/em&gt;, &lt;em&gt;3ss&lt;/em&gt;, &lt;em&gt;4ss&lt;/em&gt;, because when you add a letter &lt;code&gt;s&lt;/code&gt;, or let's better call it a character &lt;code&gt;s&lt;/code&gt; to a character &lt;code&gt;s&lt;/code&gt; you get &lt;code&gt;ss&lt;/code&gt; or you could also say you get two &lt;code&gt;ss&lt;/code&gt;, it's just it is more convenient to use numbers, at least for now while operating on the &lt;em&gt;term-level&lt;/em&gt;. Mind you working at the &lt;em&gt;term-level&lt;/em&gt; is not for everybody, people get hurt here, they leak memory etc. It's gruesome and bloody! &lt;/p&gt;

&lt;p&gt;Now tell me what type is a sheep anyway? Some kind of an animal right? A sheep is not an &lt;code&gt;Int&lt;/code&gt;, or an &lt;code&gt;Integer&lt;/code&gt;, right? Which means a sheep does not belong to a &lt;code&gt;Num&lt;/code&gt; class of numbers, of which certain kinds of number are only instances of this large class of numbers. We have &lt;code&gt;Integer&lt;/code&gt;, &lt;code&gt;Int&lt;/code&gt;, but we also have &lt;code&gt;Float&lt;/code&gt; and &lt;code&gt;Double&lt;/code&gt; and hey you could define any number you like, I myself am intrigued by surreal numbers, I fell in love the moment I heard about these wondrous entities, they seem to encode more information within, but more on surreals some other time! Watson, please notice that the whole idea of a number comes from ordering things, after all you are aware of some order, meaning the idea that some things come before or after some things, after all how do we measure time? One second passes, two second passes, one minute...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Watson&lt;/strong&gt;: After all what are we doing thinking about programs all the time, yes we write our cases, and explain our steps and people read our stories and follow our investigations but at the end of the day what is it that we do actually?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Holmes&lt;/strong&gt;: You find yourself perplexed again my Watson, by the wonderful world of programs, they seem elusive, no matter how hard we try to encode these entities into our frameworks a bitter taste remains, something again to strive for, some new algorithm, but honestly aren't you bored sometimes by the.. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The baby is crying, and it is time for a bath, I enjoyed this a lot, I hope you did too...&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>computerscience</category>
      <category>100daysofcode</category>
      <category>haskell</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Indiscernible types of Haskell Holmes</title>
      <dc:creator>domagoj miskovic</dc:creator>
      <pubDate>Thu, 05 Nov 2020 08:12:19 +0000</pubDate>
      <link>https://forem.com/stablejoy/indiscernible-types-of-haskell-holmes-4no9</link>
      <guid>https://forem.com/stablejoy/indiscernible-types-of-haskell-holmes-4no9</guid>
      <description>&lt;p&gt;There seems to be an ambiguity in the idea, a common vibe I hear on the grid, like an excuse mentioned in some books and papers,  that one of type safety's downsides it the fact that some expressions which would otherwise evaluate to a true value would be rejected on the typing grounds, the reason being that even though for example both expressions in an &lt;code&gt;if then else&lt;/code&gt; may on their own evaluate to true or to some true value within a known type instance of their own, they somehow cannot exist together in a branching statement, one cannot call another one,  meaning &lt;code&gt;if such expression is true then this expression is true&lt;/code&gt;, meaning the second expression will take place, the second event will happen if the first evaluates to true, as if this new event that may take place is to be rejected simply because it does not follow the type in the first expression. The common example would be &lt;code&gt;if True then 1 else False&lt;/code&gt; where if some boolean value in the Bool class of type values which contains two values &lt;code&gt;True&lt;/code&gt; and &lt;code&gt;False&lt;/code&gt; or a boolean function type such as &lt;code&gt;not :: Bool -&amp;gt; Bool&lt;/code&gt; which is a function from one bool to another bool, sou see when you negate something you get the &lt;em&gt;inverse&lt;/em&gt; of that thing or something else within that type universe, what else could it be? Not true is false, negate 5 is -5...  now if such an expression evaluates to true we are to call a number, or any number, in this case an integer number, &lt;code&gt;1 :: Integer&lt;/code&gt; that belongs to a class of numbers, &lt;code&gt;1 :: Num p =&amp;gt; p&lt;/code&gt; but you know all that. Apparently this seems to be an invalid statement, an invalid type inference between two expressions, between a bool and a number one. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Watson&lt;/strong&gt;: Hmmm... what if instead of &lt;code&gt;False&lt;/code&gt; we would have something like &lt;code&gt;otherwise "play me an ambient like Jedimind soundtrack now"&lt;/code&gt;? Would that be any different than a simple &lt;code&gt;False&lt;/code&gt;. What is happening here and why is this a bad thing in the first place? &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0ncovhc8t8a94t4wzlzl.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0ncovhc8t8a94t4wzlzl.jpg" alt="Alt Text" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Haskell&lt;/strong&gt;: But Watson, my dear friend it is not about the rest it is about creating algebraic structure with not enough information. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Watson&lt;/strong&gt;: What information? If something is true then give me 1. What is so strange about that. You seem to question everything, I am not surprised you named your dog Haskell for all I know. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Haskell&lt;/strong&gt;: Watson I do not have a dog, you would be the first to know if I had one. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Watson&lt;/strong&gt;: There, you just said if you had one I would now, could we take that as an example? &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Haskell&lt;/strong&gt;: Watson my boy you cannot just jump from one to another mathematical realm and expect not to spill any milk along the way. The obvious reason your reasoning is currently at its peak is that you are not fully aware of the way types transform from one instance to another. &lt;/p&gt;

&lt;p&gt;To put it simply, the way a computation evolves depends on the language your structure encodes and the way to compose different structures into new ones you will have to do a lot more than a simple if then else  statement! Try to see, if then else statement if we translate it into a typful universe might seem like an instance of a boolean function. I am describing it as a boolean because it is so simple, it actually goes from a bool to a bool. But hey we are Haskellers, and this is an old artefact from medieval times, I suggest you practice defining functions without such if then else statements because Watson my friend life is complicated and no if then else statement is going to save you from your puny little brain, even worse you might have to stitch together a string of such expressions, then when you look at it, you will not know right from wrong. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Watson&lt;/strong&gt;: All right Holmes, and tell me what about the  &lt;code&gt;Either&lt;/code&gt; type? &lt;code&gt;data Either a b&lt;/code&gt;? It also seems like  an if then else statement with maybe more freedom defined since either a or b is for you to pick which could be also realized &lt;code&gt;if True then a&lt;/code&gt; and &lt;code&gt;if True then b&lt;/code&gt;. How about that?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Haskell&lt;/strong&gt;: Bravo Watson, you did it again! &lt;code&gt;Either&lt;/code&gt;data type does represent either one value or another, &lt;code&gt;Either a b&lt;/code&gt; which we can further realize as &lt;code&gt;Left a| Right b&lt;/code&gt; and it might seem like we take these lefts and rights for granted while if we had an &lt;code&gt;if then else&lt;/code&gt; before either, we would be actually checking some precondition and then applying one of these eithers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data Either a b = Left a | Right b

firstCondition = Left True
secondCondition = Right 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Watson&lt;/strong&gt;: This is beyond me Haskell, how did you come up with this?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Haskell&lt;/strong&gt;: My dear Watson let us go then you we must investigate this case immediatelly! Call a cab!&lt;/p&gt;

</description>
      <category>haskell</category>
      <category>computerscience</category>
      <category>beginners</category>
      <category>100daysofcode</category>
    </item>
    <item>
      <title>88th day Haskell meditations: substitutions, structures, identity of a monoid</title>
      <dc:creator>domagoj miskovic</dc:creator>
      <pubDate>Tue, 03 Nov 2020 13:11:47 +0000</pubDate>
      <link>https://forem.com/stablejoy/88th-day-haskell-meditations-substitutions-structures-identity-of-a-monoid-1e4o</link>
      <guid>https://forem.com/stablejoy/88th-day-haskell-meditations-substitutions-structures-identity-of-a-monoid-1e4o</guid>
      <description>&lt;p&gt;I realize that more and more as I learn Haskell, as I think through it and with it, that most of my time programming, what I really enjoy doing, what keeps me at bay or at the sea of simulation, what inspires me to program, to code, is not actually solving a given problem within a specific domain space but exploring what it means to compute, to reason computationally, to think recursively. I find myself visualising in my mind how a program looks like in time and space, how the computation evolves, how the substitution applies, how equivalences are compared, defined by various morphisms I learn to define, how seemingly simple operations I took for granted in my elementary school days are transforming, they remain the essence in forming structures of contexts that seem fluid, defined out of time they directly give it a unique description. After much pondering and wondering about such structures you naturally begin to feel the urge to reach into mathematics which abstractly deals with these entities. You might not know you are doing mathematics, but soon enough you will. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmscwfkcolyt3itfl1nq4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmscwfkcolyt3itfl1nq4.jpg" alt="Alt Text" width="800" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In mathematics such structures are called algebraic structures, which are described as structures with an additional context, a behaviour or a class of behaviours, behaviours being some operations, like a program we can realize these algebraic structures, differentiate between their properties and compare them as well. Many have real world examples but often the human mind is blinded by the example itself, a finger pointing towards the moon, the moon in our case being the essence of the object, stripped out of its concrete implementation in real time and space its abstract shadow looms over it, functionally describing its sequence of operations. &lt;/p&gt;

&lt;p&gt;Let us take a simple operation of multiplying and adding three numbers such as: &lt;code&gt;3 * (5 + 9)&lt;/code&gt;. This example which is from "Haskell School of Music" book is showing the basic abstraction principle happening. We will not "solve" this (the result of &lt;code&gt;3 * (5 + 9) = 42&lt;/code&gt; but try to see how to abstract this whole operation, this set or a collection of two operations into a function called &lt;em&gt;simple&lt;/em&gt; which will compute the result for us. We will think about how the computation unfolds rather than just calculating the end result.&lt;/p&gt;

&lt;p&gt;We can realize that we have two operations in place happening here and three variables, context holders which are already substituted for real numbers. So let us abstract these numbers away and just write &lt;code&gt;a * (b + c)&lt;/code&gt; or even &lt;code&gt;x * (y + z)&lt;/code&gt; because we would like to see how the function works an any three numbers, at least for now let us remain with whole numbers, numbers which are familiar to us. &lt;/p&gt;

&lt;p&gt;But where is the &lt;em&gt;simple&lt;/em&gt; function? We only see the &lt;code&gt;(*)&lt;/code&gt; and &lt;code&gt;(+)&lt;/code&gt; operators between three variables in an infix position, infix positioned meaning between, inside of some expression while prefix positioned meaning before the expressions, at the beginning, something like this: &lt;code&gt;(+ 1 2 3 4 5)&lt;/code&gt; or like this: &lt;code&gt;sum [1,2,3,4,5,6]&lt;/code&gt; or shorter &lt;code&gt;sum [1..100]&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;We will simply call our function &lt;code&gt;simple&lt;/code&gt;. This function will take three variables &lt;code&gt;x y z&lt;/code&gt; and its body will be defined like this: &lt;code&gt;= x * (y + z)&lt;/code&gt;. Notice the left side of the equation, the list of parameters the function &lt;em&gt;simple&lt;/em&gt; and how there are no operators. Only in the body of the function we describe the operations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;simple&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;simple&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;
             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;
             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;27&lt;/span&gt;
             &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice we used the "multiplication distributes over addition" property which seems quite natural to us:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;During mental arithmetic, distributivity is often used unconsciously: 6 ⋅ 16 = 6 ⋅ ( 10 + 6 ) = 6 ⋅ 10 + 6 ⋅ 6 = 60 + 36 = 96. Thus, to calculate 6 ⋅ 16 in one's head, one first multiplies 6 ⋅ 10 and 6 ⋅ 6 and add the intermediate results. Written multiplication is also based on the distributive law. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But a bit later in the book there is an exercise left for the reader, which says: &lt;code&gt;simple (simple 2 3 4) 5 6&lt;/code&gt; What is happening here? It seem like the function simple is applied to one of the three variables, meaning we are passing that very same function back to itself, using the result of that function, holding it, and then putting it into the &lt;code&gt;simple x&lt;/code&gt; variable itself. Notice even the variables we use are not the same, meaning each instance of the simple function has their own set of input variables. So we have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;simple&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;
&lt;span class="c1"&gt;-- into the x we put another function simple x y z&lt;/span&gt;
&lt;span class="n"&gt;simple&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;simple&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;
&lt;span class="n"&gt;simple&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;simple&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;

&lt;span class="n"&gt;simple&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;
&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But maybe we could even take a simpler example, an example of doubling a number with itself, adding it to itself or multiplying it with &lt;code&gt;2&lt;/code&gt;. And we will call our function &lt;code&gt;double&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;double&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
&lt;span class="n"&gt;double&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;

&lt;span class="c1"&gt;-- or with lambda notation&lt;/span&gt;
&lt;span class="n"&gt;double&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
&lt;span class="n"&gt;double&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
         &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;In computer science, many abstract data types can be endowed with a monoid structure. In a common pattern, a sequence of elements of a monoid is "folded" or "accumulated" to produce a final value. For instance, many iterative algorithms need to update some kind of "running total" at each iteration; this pattern may be elegantly expressed by a monoid operation. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This description of a monoid makes me think on how keeping the &lt;em&gt;running total&lt;/em&gt; of for example some elements in a set, or objects in a category, or points in a space, or even observing stars upon the night sky, also thinking of how many seasons ago, how many years ago, how many birthdays ago, is like counting some quantity, like counting the times of some event, using the numbers to track of how many days since or how many nights more, seeing it on an analogue or a digital time keeping device, a clock, any kind of device which would measure time through cycles, returning to itself, touching the zero, zero, &lt;code&gt;00&lt;/code&gt;, or the twelve hours place, or the twenty-four, the identity. Its seems quite intuitive for us when observing time on a time keeping device to instead of saying &lt;code&gt;10 + 4 = 14&lt;/code&gt; to say &lt;code&gt;10 + 4 = 2&lt;/code&gt; meaning &lt;code&gt;10&lt;/code&gt; hours &lt;code&gt;+ 4&lt;/code&gt; hours tracks the time, over twelve, the &lt;code&gt;0&lt;/code&gt; element, the identity of one day or night, or more correct a 12 hour cycle gone by, into a new cycle of a new &lt;em&gt;running total&lt;/em&gt;, a new count, which would be &lt;code&gt;2&lt;/code&gt;. Yes, there is a difference between a 12 hour cycle and a 24 hour cycle which would seem to have two kinds of identities but more subtly the &lt;code&gt;24&lt;/code&gt; hour mark is like a binary relation, the second subset of elements within a some set: &lt;code&gt;{12,24}&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A number of countries, particularly English-speaking, use the 12-hour clock, or a mixture of the 24- and 12-hour time systems. In countries where the 12-hour clock is dominant, some professions prefer to use the 24-hour clock. For example, in the practice of medicine, the 24-hour clock is generally used in documentation of care as it prevents any ambiguity as to when events occurred in a patient's medical history.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs7d8im8gs0yqztm3brw1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs7d8im8gs0yqztm3brw1.jpg" alt="Alt Text" width="800" height="712"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The idea of an identity seems unnecessary when observing &lt;code&gt;identity :: a -&amp;gt; a&lt;/code&gt; which is just a function pointing to itself, an object pointing to itself, but seen in isolation almost with a kind of deep lens we might miss the implication of the identity element and its function. If we think about the &lt;em&gt;operation&lt;/em&gt; of summing some numbers, adding them together we know that if we add a zero to any number we get the same number back:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0 + 1 = 1
0 + 2 = 2
0 + 3 = 3
0 + 4 = 4
0 + 5 = 5
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We see the pattern that the same number returns when we add a zero to it. So this means that when we add a &lt;code&gt;0&lt;/code&gt; to any number, and we will use a variable &lt;code&gt;n&lt;/code&gt; or &lt;code&gt;x&lt;/code&gt; as a context holder, a variable which may represent any number in our number system, again, we get the same number. Mathematically, it could be said:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An additive identity is the identity element in an additive group. It corresponds to the element 0 such that for all x in the group, 0 + x = x + 0 = x. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So &lt;code&gt;0 + x = x + 0 = x&lt;/code&gt; simply means that &lt;code&gt;0&lt;/code&gt; &lt;code&gt;+&lt;/code&gt; any number &lt;code&gt;x&lt;/code&gt; is the same, or equivalent to adding that same number &lt;code&gt;x&lt;/code&gt; to a &lt;code&gt;0&lt;/code&gt;. What just happened? We just switched sides like &lt;code&gt;0 + x&lt;/code&gt; into &lt;code&gt;x + 0&lt;/code&gt;. What does that mean? &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fj8h1jerm9vboyv2gii8r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fj8h1jerm9vboyv2gii8r.png" alt="Alt Text" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In mathematics, a binary operation is commutative if changing the order of the operands does not change the result. It is a fundamental property of many binary operations, and many mathematical proofs depend on it. Most familiar as the name of the property that says "3 + 4 = 4 + 3" or "2 × 5 = 5 × 2", the property can also be used in more advanced settings. The name is needed because there are operations, such as division and subtraction, that do not have it (for example, "3 − 5 ≠ 5 − 3"); such operations are not commutative, and so are referred to as noncommutative operations.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Because it is both at the same time and it is encoded with that extra bit of information of pointing to itself. This kind of a mathematical structure is called a &lt;em&gt;monoid&lt;/em&gt;. We can then realize monoid as an object within a algebraic space of such objects.&lt;/p&gt;

</description>
      <category>100daysofcode</category>
      <category>haskell</category>
      <category>functional</category>
      <category>algebra</category>
    </item>
  </channel>
</rss>
