about summary refs log tree commit diff
path: root/users/wpcarro/website/blog/content
diff options
context:
space:
mode:
Diffstat (limited to 'users/wpcarro/website/blog/content')
-rw-r--r--users/wpcarro/website/blog/content/english/caffeine.md5
-rw-r--r--users/wpcarro/website/blog/content/english/cell-phone-experiment.md280
-rw-r--r--users/wpcarro/website/blog/content/english/lets-learn-nix-caching.md49
-rw-r--r--users/wpcarro/website/blog/content/english/lets-learn-nix-determinism-vs-reproducibility.md121
-rw-r--r--users/wpcarro/website/blog/content/english/lets-learn-nix-dotfiles.md401
-rw-r--r--users/wpcarro/website/blog/content/english/lets-learn-nix-tutorial-reproducibility.md41
-rw-r--r--users/wpcarro/website/blog/content/english/lets-learn-nix.md58
-rw-r--r--users/wpcarro/website/blog/content/english/nix-and-hugo.md5
-rw-r--r--users/wpcarro/website/blog/content/english/self-hosting.md6
9 files changed, 966 insertions, 0 deletions
diff --git a/users/wpcarro/website/blog/content/english/caffeine.md b/users/wpcarro/website/blog/content/english/caffeine.md
new file mode 100644
index 000000000000..9c3dbac0f120
--- /dev/null
+++ b/users/wpcarro/website/blog/content/english/caffeine.md
@@ -0,0 +1,5 @@
+---
+title: "Caffeine"
+date: 2020-03-11T22:50:40Z
+draft: true
+---
diff --git a/users/wpcarro/website/blog/content/english/cell-phone-experiment.md b/users/wpcarro/website/blog/content/english/cell-phone-experiment.md
new file mode 100644
index 000000000000..550ba4865ee0
--- /dev/null
+++ b/users/wpcarro/website/blog/content/english/cell-phone-experiment.md
@@ -0,0 +1,280 @@
+---
+title: "Cell Phone Experiment"
+date: 2020-04-02T02:02:07Z
+draft: false
+---
+
+### TL;DR
+
+I will not use my cell phone during March to learn more about how much I depend
+on it.
+
+### Explore/Exploit
+
+Ever since I read Charles Duhigg's book, [The Power of Habit](poh), I try to
+habituate as many aspects of my life as I can.
+
+Making my bed every morning is an example of a habit -- so too is flossing at
+night before bed.
+
+The *exploit* axis of the [explore/exploit tradeoff](exp-exp) endows habits with
+their power. Brian Christian and Tom Griffiths explain this concept more clearly
+than I can in Chapter 2 of their exceptional book, [Algorithms to Live
+By](algos).
+
+Habits are powerful, but if I overly exploit an activity, I may settle on a
+local optimum in lieu of settling on a global optimum; these are the opportunity
+costs of exploiting (i.e. habits) versus exploring (i.e. spontaneity).
+
+But what if it was possible to habituate exploration?
+
+### Monthly challenges
+
+Every month since October 2018, I challenge myself to try something new. In the
+past, monthly challenges have been things like:
+- sign up and take Brazilian Jiu Jitsu classes
+- buy a guitar and learn [Freight Train](https://www.youtube.com/watch?v=IUK8emiWabU)
+- study Italian
+- learn a handstand
+
+Typically for an activity to qualify as a challenge, I must spend *at least
+fifteen minutes* working on it *at least five days* each week.
+
+This month (i.e. March) I'm challenging myself to avoid using my cell phone.
+
+My parents gave me a cell phone when when I was a freshman in High School; I was
+14 years old. I am now 28, so I have been using a cell phone semi-daily for over
+a decade.
+
+While I enjoy the convenience that my cell phone provides me, I am curious to
+suspend my usage to more clearly understand how much I depend on it...
+
+### April
+
+Now it is early April, and I completed March's challenge. So how was it?
+
+Below I outline the parts of using a cell phone that I missed and the parts that
+I surprisingly did not miss. I will also mention the two times that I used my
+cell phone and why.
+
+The first three things that I missed all relate to time.
+
+#### Timekeeping
+
+On the first day I realized that unless I was near a computer, I did not know
+what time it was.
+
+I exclusively use my cell phone as my watch; I do not wear a watch. To adapt, I
+started looking for clocks around my office and while I was taking public
+transportation. Thankfully London posts the current time on the digital train
+schedules. This oriented me while I was traveling, which was also when I needed
+to know the time the most.
+
+Most of the month, however, I never precisely knew what time it was.
+
+#### Alarm clocks
+
+While I anticipated living without an alarm clock prior to the experiment, I
+decided against buying a substitute. Prior to this month, I theorized that
+morning alarms probably disrupt the quality of my sleep. If I'm tired, shouldn't
+I keep sleeping?
+
+As the month progressed and my 24 hour day morphed into a 25 hour day, I learned
+that I would prefer waking up at a set time every day and synchronize my
+schedule with the rest of my timezone.
+
+I am still unsure if alarm clocks are helpful in the long-term. I would have
+slept with the curtains drawn to allow the morning sun to wake me
+up. Unfortunately, I live on the ground floor nearby a brightly shining street
+lamp that spills into my bedroom.
+
+If I lived somewhere more remote (perhaps even a suburb would do) I would like
+to repeat an experiment where I live for a month without an alarm clock.
+
+For now, I must return to the Temple of Chronology and supplicate until Father
+Time restores my sanity.
+
+#### Timers
+
+Using timers motivates me to do a bunch of short tasks like cleaning my flat for
+fifteen minutes, stretching, or reading before bed. Thankfully, I already owned
+a physical timer that I keep in my kitchen. This replaced the timer on my phone
+without disrupting my routine.
+
+#### Maps
+
+Speaking of being disoriented, what about living without maps software?  On the
+few occasions where I traveled somewhere that was unfamiliar to me, I had to
+memorize the directions from my computer before I departed.
+
+At least I didn't need to visit gas stations or museums to buy trifold tourist
+maps...
+
+I once left my office mistakenly assuming that I would download the directions
+to my destination while commuting. As I awaited the office elevator, I realized
+that I had no clue where I was heading.
+
+Thankfully I wasn't far from the safety, comfort, and familiarity of my desktop
+computer -- with its fatty WiFi connection. In no time I was studying Google
+Maps in my web browser and memorizing the directions.
+
+Overall this was hardly an inconvenience, and I think I even enjoyed
+stress-testing my memory: a job that I so often outsource to hardware.
+
+#### Rendezvouses
+
+A couple of times I met friends in various parts of the city. Organizing these
+particular rendezvouses was a novel (read: anachronistic) experience. For all
+you young whippersnappers reading, take out your stone tablets and chisels. I'm
+going to explain how this works:
+
+First I would tell my friends where and when to meet me. I emphasized that I
+would be quite helpless to any changes they might make to the plans once I began
+commuting, which made the commitments unusually more binding.
+
+On one occasion my friend -- who is characteristically prompt, and even chides
+me for when I'm late -- was twenty minutes late for our engagement. My friend is
+German, so I figured I should do my civic duty of alerting the German embassy
+that my friend had broken German code, is obscenely late, and should therefore
+hand-in his passport and renounce his citizenship. After awhile my conscience
+advised me to reconsider.
+
+It was fortunate for both of us that I did not fully understand how late he was.
+Remember: I didn't know what time it was.
+
+I decided this would be a useful opportunity to test my patience, so I loitered
+for twenty minutes outside of our meeting point. He couldn't text me to tell me
+that he was late. I couldn't listen to music, call family or friends, or partake
+in any of the other rituals that modern-day loiterers observe to pass the
+time. In the end he showed up, and it was scarcely a big deal.
+
+This experience made me wonder what the policy for abandoning plans is when
+someone is running late. Before smart phones, how long did people wait? Maybe
+the proper etiquette is to wait long enough for you to absolve yourself of the
+guilt of flaking in the unlikely event that your friend arrives shortly after
+you leave.
+
+So... thirty minutes? I'll call my grandma tomorrow and ask her.
+
+#### Boredom
+
+My phone couldn't entertain me while I queued at the grocery store. Same too
+when I commuted.
+
+I also found myself listening to less music than I usually do. I decided to read
+to occupy the void when I could; this helped me progress towards completing this
+year's [GoodReads challenge][gr-annual].
+
+### Cheating
+
+I used my phone twice during March.
+
+1. Once to use my bank's mobile app to internationally transfer money from my
+   U.K. account to my U.S. account. I could have used [TransferWise's][tw]
+   website, but I didn't.
+2. Another time I used my phone to take pictures of an item that I wanted to
+   sell on [CraigsList][cl]. I could have and perhaps should have used my laptop's
+   webcam, but at the time, I didn't want to. I am accustomed to using my phone
+   to take pictures, and I wanted to sell something.
+
+In both of these cases, prior habits eroded my resolve to stay the course. These
+are useful reminders that habits don't distinguish between helpful and hurtful;
+they just exist.
+
+In total I would estimate that I spent somewhere around fifteen minutes using
+my phone in March. While not perfect:
+
+> Better a diamond with a flaw than a pebble without (Confucius)
+
+### Substitution = Dilution
+
+While the explicit goal of this challenge was to avoid using my cell phone for a
+month, the implicit goal was to disengage from many of the
+[nonessential][essentialism] activities that compete for my attention.
+
+There were some activities that I didn't miss while living without a cell
+phone. This wasn't because I don't value these activities, but rather because I
+can adequately replace them with alternatives.
+
+For texting and making phone calls, I used [Telegram][wtf-telegram]. Telegram
+helped me sustain a healthy relationship with my girlfriend while still honoring
+the constraints of the challenge.
+
+While I appreciated the convenience Telegram provided, I felt that I remained
+about as [available][wtf-availability] during March as I was in February. If I
+ever experiment with drastically reducing my availability, I will be more
+explicit about my objectives.
+
+### Distraction displacement (whack-a-mole)
+
+Because cell phones and other electronics have conditioned my behavior, I
+habitually avoid boredom and seek entertainment. On its face this may not sound
+like a harmful practice. My generation drills the aphorism "you only live once",
+suggesting that we may want to embrace a Hedonistic lifestyle.
+
+Hedonism may or may not be a wise way to play the game of Life. All I know is
+that living a life in which I am often stimulated but proportionately distracted
+appeals increasingly less to me as time progresses.
+
+During March I noticed that once I freed my attention from sending/receiving
+texts, my brain quickly reassigned my attention to maintaining a vigil over the
+other social media outposts that I maintain.
+
+I should also admit that I habitually checked Telegram now that it served as my
+new cell phone. Didn't see that coming...
+
+In another case, once I discovered that I could use Instagram in a web browser
+instead of on my phone, I filled my newfound time and attention on
+[Instagram.com][ig] (don't click!): displacing the time that I spent on an app
+on my phone to time that I spent on a website in a web browser.
+
+Holy whack-a-mole!
+
+Halfway through the month, I wrote a [program to block websites][url-blocker] on
+my computer. Surprisingly this worked and forced me to more deliberately fill
+this hard-fought, foreign time with other activities.
+
+### Easy come, easy go?
+
+As the saying for making friends goes, "easy come, easy go", implying that
+friendships that you easily form can just as easily be destroyed.
+
+Habits invert this creation/destruction relationship. In my experience "easy
+come" implies "difficult to go".
+
+For example, I could easily form the habit of eating chocolate around 15:00 at
+work; curbing this habit would require more effort. When I compare this to the
+difficulty I experienced habituating a meditation practice, and how easily I
+can dislodge my meditation practice, it seems to me that the laws of habits
+dictate "easy come, difficult go; difficult come, easy go".
+
+I suspect that while my cravings for using a cell phone have temporarily ceased,
+they will return shortly after I start using my cell phone. And as if nothing
+happened, I return to where I was at the end of February just before I decided
+to curb my cell phone usage.
+
+Because of this, I'm planning on keeping my cell phone in my closet where I
+stored it during the month of March. As noted, enough substitutes exist for me
+to live a mostly normal life: one where I am not unnecessarily straining the
+relationships of my friends and my family. After all these are the people who
+matter most to me and those who drive me to explore new ways to improve.
+
+I recognize that the "self" in self-experimentation is a misnomer. Can you truly
+conduct an [N of 1 trial][nof1]? My decisions impact the people in my life, and
+I want to thank everyone who tolerates my eccentric and oftentimes annoying
+experimentation.
+
+Thank you for reading.
+
+[pod]: https://www.goodreads.com/book/show/12609433-the-power-of-habit
+[exp-exp]: https://en.wikipedia.org/wiki/Multi-armed_bandit
+[algos]: https://www.goodreads.com/book/show/25666050-algorithms-to-live-by
+[gr-annual]: https://www.goodreads.com/user_challenges/19737920
+[cl]: http://craigslist.com
+[tw]: https://transferwise.com
+[url-blocker]: https://github.com/wpcarro/url-blocker
+[wtf-telegram]: https://telegram.org
+[wtf-availability]: https://landing.google.com/sre/sre-book/chapters/availability-table
+[essentialism]: https://www.goodreads.com/book/show/18077875-essentialism
+[ig]: https://instagram.com
+[nof1]: https://en.wikipedia.org/wiki/N_of_1_trial
diff --git a/users/wpcarro/website/blog/content/english/lets-learn-nix-caching.md b/users/wpcarro/website/blog/content/english/lets-learn-nix-caching.md
new file mode 100644
index 000000000000..a436d4de25eb
--- /dev/null
+++ b/users/wpcarro/website/blog/content/english/lets-learn-nix-caching.md
@@ -0,0 +1,49 @@
+---
+title: "Lets Learn Nix Caching"
+date: 2020-03-17T18:05:38Z
+draft: true
+---
+
+## TL;DR
+
+1. I use `NixOS/nixpkgs-channels` instead of `NixOS/nixpkgs` and avoid
+   `nix-channel`.
+
+## More information
+
+- By default the Nix package manager uses cache.nixos.org as a binary cache.
+- Visit status.nixos.org
+- `git clone git@github.com:NixOS/nixpkgs-channels` instead of
+  `NixOS/nixpkgs`. The former mirrors the latter and uses Git branches to track
+  the published channels.
+
+## What is a Nix channel
+
+If you run...
+
+```shell
+$ git clone git@github.com:NixOS/nixpkgs ~/nixpkgs
+$ export NIX_PATH="nixpkgs=$(realpath ~/nixpkgs)"
+```
+
+One benefit to cloning nixpkgs is that you can browse the source code on your
+machine using tools like `git` and `emacs`. You can also experimentally patch
+and test Nix code this way.
+
+If any of the above appeals to you, clone `nixpkgs-channels` instead.
+
+The Nix maintainers build and test the commits from `nixpkgs` using Hydra. Tests
+include reproducibility tests, etc.
+
+Various channels have different verification phases.
+
+The cache at cache.nixos.org is populate the cache at cache.nixos.org.
+
+You want to increase the likelihood that you are hitting this cache. For
+example, `google-chrome` takes hours to build.
+
+## What is a binary cache?
+
+## What is Hydra (Nix CI)?
+
+## What is Cachix?
diff --git a/users/wpcarro/website/blog/content/english/lets-learn-nix-determinism-vs-reproducibility.md b/users/wpcarro/website/blog/content/english/lets-learn-nix-determinism-vs-reproducibility.md
new file mode 100644
index 000000000000..2e12a6b06fcc
--- /dev/null
+++ b/users/wpcarro/website/blog/content/english/lets-learn-nix-determinism-vs-reproducibility.md
@@ -0,0 +1,121 @@
+---
+title: "Lets Learn Nix: Reproducibility"
+date: 2020-03-17T12:06:47Z
+draft: true
+---
+
+I am dedicating this page to defining and disambiguating some terminology. I
+think it is important to use these terms precisely, so it may be worthwhile to
+memorize these definitions and ensure that you are clarifying the discourse
+rather than muddying it.
+
+## Terms
+
+- repeatable build:
+- reproducible build:
+- deterministic build:
+- pure function:
+- impure function:
+- idempotent function:
+
+TODO(wpcarro): Consistently and deliberately use reproducible and
+deterministic.
+
+## Repeatable vs. Reproducible
+
+Is NixOS reproducible? Visit [@grhmc][who-grhmc]'s website,
+[r13y.com](https://r13y.com), to find out.
+
+At the time of this writing, 1519 of 1568 (i.e. 96.9%) of the paths in the
+`nixos.iso_minimal.x86_64-linux` installation image are reproducible.
+
+## What hinders reproducibility?
+
+Timestamps.
+
+If package A encodes a timestamp into its build artifact, then we can
+demonstrate that package A is *not reproducible* simply by building it at two
+different times and doing a byte-for-byte comparison of the build artifacts.
+
+## Does Nix protect developers against non-determinism
+
+Yes. But not entirely. How?
+
+## Deterministic Nix derivation
+
+```nix
+{ pkgs ? import <nixpkgs> {}, ... }:
+
+with pkgs;
+
+stdenv.mkDerivation {
+  name = "reproducible";
+  phases = [ "buildPhase" ];
+  buildPhase = "echo reproducible >$out";
+}
+```
+
+## Non-deterministic Nix derivation
+
+We can introduce some non-determinism into our build using the `date` function.
+
+```nix
+# file: /tmp/test.nix
+{ pkgs ? import <nixpkgs> {}, ... }:
+
+with pkgs;
+
+stdenv.mkDerivation {
+  name = "non-reproducible";
+  phases = [ "buildPhase" ];
+  buildPhase = "date >$out";
+}
+```
+
+Then run...
+
+```shell
+$ nix-build /tmp/test.nix
+$ nix-build /tmp/test.nix --check --keep-failed
+```
+
+## How do you test reproducibility?
+
+We can use `cmp` to compare files byte-for-byte. The following comparison should
+fail:
+
+```shell
+$ echo foo >/tmp/a
+$ echo bar >/tmp/b
+$ cmp --silent /tmp/{a,b}
+$ echo $?
+```
+
+And the following comparison should succeed:
+
+```shell
+$ echo hello >/tmp/a
+$ echo hello >/tmp/b
+$ cmp --silent /tmp/{a,b}
+$ echo $?
+```
+
+## Reproducible vs. deterministic
+
+Reproducible builds *are* deterministic builds and deterministic build
+
+## Deterministic, Reproducible, Pure, Idempotent, oh my
+
+- A pure function has no side-effects.
+
+- An idempotent function can be executed more than once with the same arguments
+  without altering the side-effects.
+
+- A deterministic function ensures that
+
+## Deterministic vs. Reproducible
+
+I can check if a build is reproducible using [these tools][wtf-repro-tools].
+
+[wtf-repro-tools]: https://reproducible-builds.org/tools/
+[who-grhmc]: https://twitter.com/grhmc
diff --git a/users/wpcarro/website/blog/content/english/lets-learn-nix-dotfiles.md b/users/wpcarro/website/blog/content/english/lets-learn-nix-dotfiles.md
new file mode 100644
index 000000000000..084fb19e4406
--- /dev/null
+++ b/users/wpcarro/website/blog/content/english/lets-learn-nix-dotfiles.md
@@ -0,0 +1,401 @@
+---
+title: "Let's Learn Nix: Dotfiles"
+date: 2020-03-13T22:23:02Z
+draft: true
+---
+
+## Let's Learn Nix: Dotfiles
+
+### Dependencies
+
+Speaking of dependencies, here's what you should know before reading this tutorial.
+
+- Basic Nix syntax: Nix 1p
+
+What version of Nix are we using? What version of `<nixpkgs>` are we using? What
+operating system are we using? So many variables...
+
+Cartesian product of all possibilities...
+
+TODO(wpcarro): Create a graphic of the options.
+
+### The problems of dotfiles
+
+How do you manage your dependencies?
+
+You can use `stow` to install the dotfiles.
+
+### home-manager
+
+What we are going to write is most likely less preferable to the following
+alternatives:
+- using Nix home-manager
+- committing your `.gitconfig` into your
+
+In the next tutorial, we will use [home-manager][wtf-home-mgr] to replace the
+functionality that we wrote.
+
+So why bother completing this?
+
+### Let's begin
+
+Welcome to the first tutorial in the [Let's Learn Nix][wtf-lln] series. Today we
+are going to create a Nix derivation for one of your dotfiles.
+
+"Dotfiles" refers to a user's collection of configuration files. Typically these
+files look like:
+- `.vimrc`
+- `.xsessionrc`
+- `.bashrc`
+
+The leading "dot" at the beginning gives dotfiles their name.
+
+You probably have amassed a collection of dotfiles whether or not you are
+aware. For example, if you use [git][wtf-git], the file `~/.gitconfig` should
+exist on your machine. You can verify this with:
+
+```shell
+$ stat ~/.gitconfig
+```
+
+When I was first learning `git`, I learned to configure it using commands I
+found in books and tutorials that often looked like:
+
+```shell
+$ git config user.email
+```
+
+The `~/.gitconfig` file on your machine may look something like this:
+
+```.gitconfig
+[user]
+	name = John Cleese
+	email = john@flying-circus.com
+	username = jcleese
+[core]
+	editor = emacs
+[web]
+	browser = google-chrome
+[rerere]
+	enabled = 1
+	autoupdate = 1
+[push]
+	default = matching
+[color]
+	ui = auto
+[alias]
+	a = add --all
+	ai = add -i
+	b = branch
+	cl = clone
+	cp = cherry-pick
+	d = diff
+	fo = fetch origin
+	lg = log --oneline --graph --decorate
+	ps = push
+	pb = pull --rebase
+	s = status
+```
+
+As I ran increasingly more `git config` commands to configure my `git`
+preferences, the size of my `.gitconfig` increased, and the less likely I was to
+remember which options I set to which values.
+
+Thankfully a coworker at the time, Ryan ([@rschmukler][who-ryan]), told me that
+he version-controlled his `.gitconfig` file along with his other configuration
+files (e.g. `.vimrc`) in a repository he called "dotfiles".
+
+Version-controlling your dotfiles improves upon a workflow where you have a
+variety of configuration files scattered around your machine.
+
+If you look at the above `.gitconfig`, can you spot the dependencies?
+
+We explicitly depend `emacs` and `google-chrome`. We also *implicitly* depend on
+`git`: there is not much value of having a `.gitconfig` file if you also do not
+have `git` installed on your machine.
+
+Dependencies:
+- `emacs`
+- `google-chrome`
+
+Let's use Nix to generate this `.gitconfig` file. Here is what I would like our
+API to be:
+
+Let's create a file `gitconfig.nix` and build our function section-by-section:
+
+TODO(wpcarro): Link to sections here
+- options.user
+- options.core
+- options.web
+- options.rerere
+- options.push
+- options.color
+- options.alias
+
+```shell
+$ touch gitconfig.nix
+```
+
+### options.user
+
+```haskell
+AttrSet -> String
+```
+
+```nix
+user = {
+  name = "John Cleese";
+  email = "john@flying-circus.com";
+  username = "jcleese";
+};
+```
+
+```.gitconfig
+[user]
+	name = John Cleese
+	email = john@flying-circus.com
+	username = jcleese
+```
+
+### options.core
+
+```nix
+core = {
+  editor = "${pkgs.emacs}/bin/emacs";
+};
+```
+
+```.gitconfig
+[core]
+	editor = /nix/store/<hash>-emacs-<version>/bin/emacs
+```
+
+### options.web
+
+```nix
+web.browser = "${pkgs.google-chrome}/bin/google-chrome";
+```
+
+```.gitconfig
+[web]
+	browser = /nix/store/<hash>-google-chrome-<version>/bin/google-chrome
+```
+
+### options.rerere
+
+```nix
+rerere = {
+  enabled = true;
+  autoupdate = true;
+};
+```
+
+```.gitconfig
+[rerere]
+	enabled = 1
+	autoupdate = 1
+```
+
+### options.push
+
+```nix
+push.default = "matching";
+```
+
+```.gitconfig
+[push]
+	default = matching
+```
+
+### options.color
+
+```nix
+color.ui = "auto";
+```
+
+```.gitconfig
+[color]
+	ui = auto
+```
+
+We need to define a function named `gitconfig` that creates a Nix [derivation][wtf-derivation]:
+
+```nix
+# file: gitconfig.nix
+let
+  # Import the <nixpkgs> package repository.
+  pkgs = import <nixpkgs> {};
+
+  # Stringify the attribute set, `xs`, as a multilined string formatted as "<key> = <value>".
+  # See attrsets.nix for more functions that work with attribute sets.
+  encodeAttrSet = xs: lib.concatStringsSep "\n" (lib.mapAttrsToList (k: v: "${k} = ${v}") xs);
+
+  # Define out function name `gitconfig` that accepts an `options` argument.
+  gitconfig = options: pkgs.stdenv.mkDerivation {
+    # The gitconfig file that Nix builds will be located /nix/store/some-hash-gitconfig.
+    name = "gitconfig";
+    src = pkgs.writeTextFile ".gitconfig" ''
+      [user]
+          name = ${options.user.name}
+          email = ${options.user.email}
+          username = ${options.user.username}
+      [core]
+          editor = ${options.core.editor}
+      [web]
+          editor = ${options.web.browser}
+      [rerere]
+          enabled = ${if options.rerere.enabled "1" else "0"}
+          autoupdate = ${if options.rerere.autoupdate "1" else "0"}
+      [push]
+          default = ${options.push.default}
+      [color]
+          ui = ${options.color.ui}
+      [alias]
+          ${encodeAttrSet options.aliases}
+    '';
+    buildPhase = ''
+      ${pkgs.coreutils}/bin/cp $src $out
+    '';
+    installPhase = ''
+      ${pkgs.coreutils}/bin/ln -s $out ~/.gitconfig
+    '';
+  };
+} in gitconfig {
+  user = {
+    name = "John Cleese";
+    email = "john@flying-circus.com";
+    username = "jcleese";
+  };
+  core = {
+    editor = "${pkgs.emacs}/bin/emacs";
+  };
+  web.browser = "${pkgs.google-chrome}/bin/google-chrome";
+  rerere = {
+    enabled = true;
+    autoupdate = true;
+  };
+  push.default = "matching";
+  color.ui = "auto";
+  aliases = {
+	a  = "add --all";
+	ai = "add -i";
+	b  = "branch";
+	cl = "clone";
+	cp = "cherry-pick";
+	d  = "diff";
+	fo = "fetch origin";
+	lg = "log --oneline --graph --decorate";
+	ps = "push";
+	pb = "pull --rebase";
+	s  = "status";
+  };
+}
+```
+
+### options.alias
+
+We want to write a function that accepts an attribute set and returns a
+string. While Nix is a dynamically typed programming language, thinking in types
+helps me clarify what I'm trying to write.
+
+```haskell
+encodeAttrSet :: AttrSet -> String
+```
+
+I prefer using a Haskell-inspired syntax for describing type signatures. Even if
+you haven't written Haskell before, you may find the syntax intuitive.
+
+Here is a non comprehensive, but demonstrative list of example type signatures:
+- `[String]`: A list of strings (i.e. `[ "cogito" "ergo" "sum" ]`)
+- `AttrSet`: A nix attribute set (i.e. `{ name = "John Cleese"; age = 80; }`).
+- `add :: Integer -> Integer -> Integer`: A function named `add` that accepts
+  two integers and returns an integer.
+
+Specifically, we want to make sure that when we call:
+
+```nix
+encodeAttrSet {
+  a = "add --all";
+  b = "branch";
+}
+```
+
+...it returns a string that looks like this:
+
+```.gitconfig
+a = "add --all"
+b = "branch"
+```
+
+
+TODO(wpcarro): @tazjin's nix-1p mentions this. Link to it.
+Nix has useful functions scattered all over the place:
+- `lib.nix`
+- `list.nix`
+- `lib.attrSet`
+
+But I cannot recall exactly which functions we will need to write
+`encodeAttrSet`. In these cases, I do the following:
+1. Run `nix repl`.
+2. Browse the Nix source code.
+
+Google "nix attribute sets" and find the Github link to `attrsets.nix`.
+
+You should consider repeating this search but instead of searching for
+"attribute sets" search for "lists" and "strings". That is how I found the
+functions needed to write `encodeAttrSet`. Let's return to our `nix repl`.
+
+Load the nixpkgs set:
+
+```nix
+nix-repl> :l <nixpkgs>
+Added 11484 variables.
+```
+
+Define a test input called `attrs`:
+
+```nix
+nix-repl> attrs = { fname = "John"; lname = "Cleese"; }
+```
+
+Map the attribute set into `[String]` using `lib.mapAttrsToList`:
+
+```nix
+nix-repl> lib.mapAttrsToList (k: v: "${k} = ${toString v}") attrs
+[ "fname = John" "lname = Cleese" ]
+```
+
+Now join the `[String]` together using `lib.concatStringsSep`:
+
+```nix
+nix-repl> lib.concatStringsSep "\n" (lib.mapAttrsToList (k: v: "${k} = ${v}") attrs)
+"fname = John\nlname = Cleese"
+```
+
+Now let's use this to define our function `encodeAttrSet`:
+
+```nix
+# file: gitconfig.nix
+encodeAttrSet = xs: lib.concatStringsSep "\n" (lib.mapAttrsToList (k: v: "${k} = ${v}") xs);
+```
+
+### Using nixpkgs search
+
+[Nixpkgs search][wtf-nixpkgs-search].
+
+### Conclusion
+
+We learned how to help ourselves.
+
+- Where does `emacs` exist? What about `google-chrome`? [nixpkgs search][wtf-nixpkgs-search]
+- Verify that I have it? [nix REPL][using-nix-repl]
+
+We used Nix to create our first derivation.
+
+[wtf-lln]: /lets-learn-nix
+[wtf-git]: https://git-scm.com/
+[wtf-derivation]: https://nixos.org/nixos/nix-pills/our-first-derivation.html
+[wtf-nixpkgs-search]: https://nixos.org/nixos/packages.html?channel=nixos-19.09
+[using-nix-repl]: /using-the-nix-repl
+[wtf-home-mgr]: https://github.com/rycee/home-manager
+[who-ryan]: https://twitter.com/rschmukler
diff --git a/users/wpcarro/website/blog/content/english/lets-learn-nix-tutorial-reproducibility.md b/users/wpcarro/website/blog/content/english/lets-learn-nix-tutorial-reproducibility.md
new file mode 100644
index 000000000000..c80892164dbe
--- /dev/null
+++ b/users/wpcarro/website/blog/content/english/lets-learn-nix-tutorial-reproducibility.md
@@ -0,0 +1,41 @@
+---
+title: "Lets Learn Nix: Tutorial Reproducibility"
+date: 2020-03-17T18:34:58Z
+draft: true
+---
+
+## Install Nix
+
+Link to nixos page.
+
+## The rest
+
+Start with this...
+
+```shell
+$ mkdir ~/lets-learn-nix
+$ cd ~/lets-learn-nix
+```
+
+...done. Copy the following and paste it into a file name `shell.nix`.
+
+```nix
+# file: shell.nix
+let
+  pkgs = import (builtins.fetchGit {
+    url = "https://github.com/NixOS/nixpkgs-channels";
+    ref = "refs/heads/nixos-19.09";
+  }) {}
+in pkgs.mkShell {
+  buildInputs = with pkgs; [
+    git
+  ];
+  NIX_PATH = "nixpkgs=${pkgs}";
+};
+```
+
+...then...
+
+```shell
+$ nix-shell
+```
diff --git a/users/wpcarro/website/blog/content/english/lets-learn-nix.md b/users/wpcarro/website/blog/content/english/lets-learn-nix.md
new file mode 100644
index 000000000000..a7c9a22e422e
--- /dev/null
+++ b/users/wpcarro/website/blog/content/english/lets-learn-nix.md
@@ -0,0 +1,58 @@
+---
+title: "Lets Learn Nix"
+date: 2020-03-13T21:50:47Z
+draft: false
+---
+
+## Background
+
+[Nix][wtf-nix] may be the most useful tool that I use. I consider it as valuable
+as [Git][wtf-git] or [Emacs][wtf-emacs]. My friend, David ([@dmjio][who-dmjio]),
+first introduced me to Nix when we worked together at a Haskell startup in
+NYC. Before this, I had been managing my system configuration using software
+that I wrote -- first in Bash, then in Python, then in Golang.
+
+It took me awhile to understand Nix. I left the NYC startup, joined Google, and
+relocated to London. Here I met another Nix-enlightened monk, Vincent
+([@tazjin][who-tazjin]), who patiently taught me enough Nix to become
+self-reliant and productive.
+
+Many resources exist to learn Nix; the Nix community on IRC continues to help me
+and others effectively use Nix. I'm creating this series to write the tutorials
+that I would have found useful when I started learning Nix. If you are just
+beginning your Nix journey, I hope these tutorials help you.
+
+## Goals
+
+I aim to make each tutorial in the "Let's Learn Nix" series:
+- Actionable: Readers will be writing code.
+- Digestible: Readers should be able to finish each tutorial in fifteen minutes.
+- Reproducible: Readers should expect the output of their code to match what
+  these tutorials claim they should see.
+
+## About the author
+
+My name is William ([@wpcarro][who-wpcarro]). My three favorite tools are Git,
+Emacs, and Nix. I am an American expat currently working at Google in
+London. While during the day I primarily write Java, Python, and TypeScript, I
+prefer functional programming. I use Nix to deploy software and manage the
+multiple machines across which I work.
+
+## Let's Begin
+
+Before we get started, Nix is a programming language. To familiarize yourself
+with the syntax, semantics, and idioms, consider reading this brief [Nix One
+Pager][nix-1p]. I recommend keeping it around as a reference.
+
+When I was first learning Nix, I wanted to use it to manage my dotfiles. Our
+first tutorial will help you get started: [Let's Learn Nix:
+Dotfiles][lln-dotfiles]
+
+[wtf-nix]: https://nixos.org
+[wtf-git]: https://git-scm.com
+[wtf-emacs]: https://www.gnu.org/software/emacs
+[who-dmjio]: https://twitter.com/dmjio
+[who-tazjin]: https://twitter.com/tazjin
+[who-wpcarro]: https://twitter.com/wpcarro
+[lln-dotfiles]: /lets-learn-nix-dotfiles
+[nix-1p]: https://github.com/tazjin/nix-1p
diff --git a/users/wpcarro/website/blog/content/english/nix-and-hugo.md b/users/wpcarro/website/blog/content/english/nix-and-hugo.md
new file mode 100644
index 000000000000..ff0fe70205da
--- /dev/null
+++ b/users/wpcarro/website/blog/content/english/nix-and-hugo.md
@@ -0,0 +1,5 @@
+---
+title: "Deploy Hugo blog with Nix"
+date: 2020-03-11T18:42:32Z
+draft: true
+---
diff --git a/users/wpcarro/website/blog/content/english/self-hosting.md b/users/wpcarro/website/blog/content/english/self-hosting.md
new file mode 100644
index 000000000000..1705541d820c
--- /dev/null
+++ b/users/wpcarro/website/blog/content/english/self-hosting.md
@@ -0,0 +1,6 @@
+---
+title: "Self Hosting"
+date: 2020-03-11T22:53:56Z
+draft: true
+---
+