Commit graph

889 commits

Author SHA1 Message Date
William Carroll
42c6ad3bb4 Simpify top-level nix expression
When I first created the monorepo, I borrowed @tazjin's monorepo's. I adapted
his depot/default.nix, replacing some of his paths with my paths. This worked
for me until recently.

I attemped to include <briefcase/monzo_ynab/job> as a systemd unit for my NixOS
machine, socrates. NixOS failed to build my changes, and I didn't fully
understand my default.nix since I borrowed most of it from @tazjin. I spent the
past week looking at the `fix` function. I realized that I didn't fully
understand how fixed-point recursion worked. This sent me down a rabbit hole
terminating with me studying the Y and Z combinators.

Ironically, after understanding the `fix` function, I realized that I didn't
need to use it where I was consuming it. I ended up pruning most of my
configuration, which resulted in this commit.

Yours truly,
lambda f: (lambda x: f(x(x)))(lambda x: f(x(x)))
2020-03-01 22:32:25 +00:00
William Carroll
b4689761d9 Solve InterviewCake's highest-product-of-3
Write a function that returns the highest product of three integers within a
list of integers. This solution uses a greedy algorithm that solves for the
answer in linear time. The space complexity is constant.
2020-03-01 22:32:25 +00:00
William Carroll
dff621922c Remove HTML-encoded quote
Prefer ' to &#39;
2020-03-01 22:32:25 +00:00
William Carroll
4d2d19f136 Solve InterviewCake's stock-price problem
Write a function that returns the maximum profit that a trader could have made
in a day. I solved this using a greedy algorithm which constantly sets the
maximum profit by tracking the lowest price we've encountered.
2020-03-01 22:32:25 +00:00
William Carroll
3abee3373c Use doom-modeline
Cleaning up my modeline by using the beautiful doom-modeline package.
2020-03-01 22:32:25 +00:00
William Carroll
710849f3b3 Read Paul Graham's "Five Questions about Language Design"
This article felt like a summary of "Being Popular". I'd suggest reading both of
these.
2020-03-01 22:32:24 +00:00
William Carroll
d2aa66a5b1 Solve InterviewCake's top-scores
Using a counting sort to sort a list of values in linear time.
2020-03-01 22:32:24 +00:00
William Carroll
e4cdb5daed Solve InterviewCake's word-cloud problem
Write a function to count the frequency of words in a sentence. Ignore casing
for words; ignore punctuation.
2020-03-01 22:32:24 +00:00
William Carroll
ef2ce90aa7 Consolidate fish configuration
Months ago when I was revisiting Nix, I decided to nixify my fish
configuration. This was a useful learning exercise. I've had two config.fish
files floating around this repository ever since then. I sometimes update one
and other times I update the other. I'm consolidating these files into one, so I
that this is no longer as issue.
2020-03-01 22:32:24 +00:00
William Carroll
ea5db41722 Read Paul Graham's "Being Popular" essay
Maybe this is my recency bias writing, but "Being Popular" may be one of my
favorite Paul Graham essays that I've read.

"Being Popular" outlines Paul Graham's ideas about what an ideal programming
language would look like. This essay took me 1-2 hours to read, but it was worth
the time.

Here are some quotes that I enjoyed (not sorted in any meaningful order):

"A friend of mine rarely does anything the first time someone asks him. He knows
that people sometimes ask for things that they turn out not to want. To avoid
wasting his time, he waits till the third or fourth time he's asked to do
something; by then, whoever's asking him may be fairly annoyed, but at least
they probably really do want whatever they're asking for."

"In this particular case there is a way to finesse our way out of the
problem. If we treat data structures as if they were functions on indexes, we
could write (a x y) instead, which is even shorter than the Perl form. Similar
tricks may shorten other types of expressions."

"The latest hot language, Python, is a watered-down Lisp with infix syntax and
no macros."

"Hackers would think a lot more highly of Lisp if Common Lisp had powerful
string libraries and good OS support."

"I think language designers would do better to consider their target user to be
a genius who will need to do things they never anticipated, rather than a
bumbler who needs to be protected from himself."

Some take-aways:
- Let's refer to Python as "Diet Lisp" from now until the end of time.
- Fight to keep your user-base small for as long as you can. Only fools want
  large user bases.
- Rich Hickey definitely read this article; he took some ideas with him; he left
  some ideas behind.
- Focus language design efforts around defining rich standard libraries,
  especially for string manipulation.
- Worry little about supporting backwards compatibility; design a language that
  can and is often rewritten.
- Shift the burden of optimizing code performance to the user by designing a
  powerful runtime profiler that is tightly integrated into the language
  runtime.
- Minimize the costs users face when experimenting: ensure that your language is
  interactive; ensure users can create REPLs quickly.
- Support OS-level libraries (think about Go).
- Maximize introspection and hackability.

What a useful read!
2020-03-01 22:32:24 +00:00
William Carroll
93d654df77 Solve InterviewCake permutation-palindrome problem
Write a predicate to test whether any permutation of an input string is a
palindrome.
2020-03-01 22:32:24 +00:00
William Carroll
6249e19cdc Add nixos as top-level monorepo package
I'd like to be able to call...
`nix-build -E '(import <briefcase> {}).nixos.socrates'`
...as part of my efforts to wane my dependence off of `nixos-rebuild`.
2020-03-01 22:32:24 +00:00
William Carroll
9e0fdd3973 Remove default values for Nix expression parameters
I'm not sure if this commit breaks everything in my monorepo. I think it
will.

Why am I doing this? Perhaps it's a bad idea. I don't fully understand how
readTree works. My ignorance is costing me hours of time spent debugging. In an
effort to better understand readTree, I'm removing the default values for my Nix
expression parameters, which I believe have preventing errors from surfacing.
2020-03-01 22:32:24 +00:00
William Carroll
fd720fbe4d Nest configuration beneath socrates directory
Create a socrates directory to store configuration for socrates.
2020-03-01 22:32:24 +00:00
William Carroll
6a076e8329 Expose depot and briefcase to rebuild script
At the moment, I don't think nixos-rebuild is reading $NIX_PATH, which
appropriately sets the paths for depot and briefcase. I'm going to explicitly
expose these values in the rebuild script for now.
2020-02-23 20:11:33 +00:00
William Carroll
0973ca006c Define monzo-token-server as a root systemd service
After I considered the security implications of calling
`systemctl --user cat monzo-token-server`, I realized that monzo-token-server
should be a root service instead of a user service.

This service unit now also explicitly depends on briefcase.monzo_ynab.tokens,
which is a big improvement.
2020-02-23 20:01:33 +00:00
William Carroll
a1a4689ad3 Consume updated kv module
Exposing store_path to the tokens module to support the newly updated kv
module, which requires an explicit storePath parameter.
2020-02-23 20:01:15 +00:00
William Carroll
b5d4f547d2 Prefer explicit path for kv.json
Paying off some tech debt. Instead of relying ./kv.json existing, which is
relative to the directory from which I start a program, I'm preferring that a
consumer explicitly provides this path.
2020-02-23 19:58:19 +00:00
William Carroll
3f46ac6513 Change systemd unit type: oneshot -> simple
"oneshot", according to `man systemd.service`, "will consider the unit up after
the main process exits". Since I designed token-server to run continuously, it
will not intentionally exit; therefore, systemd awaits its exit, which never
comes. "simple", on the other hand, does what I want.
2020-02-23 19:32:52 +00:00
William Carroll
f926b4d61a Expose secrets to Monzo / YNAB service
Here is my first attempt to manage secrets when I deploy onto a NixOS machine.

Background: When I develop, I use direnv, which reads an .envrc file in which I
define my secrets. My secrets are read from `pass` using a pattern like this...

```shell
secret_value="$(pass show path/to/secret)"
```

...Thus far, I've found this pattern convenient. `pass show` invokes GPG, which
asks me for a password to authenticate. This means that when I cd into a
directory with an .envrc file using this pattern, I may be prompted by GPG for a
password. When I'm not, it's because gpg-agent is still caching my
password. This works for development, but I currently do not know how to use
direnv for deployments.

Here is what I'm using until I find a more convenient solution:
- Store the secrets in /etc/secrets on socrates. Ensure that the /etc/secrets
  directory and its contents are only readable by root.
- Use systemd's Environment and NixOS's builtins.readFile to read the files in
  /etc/secrets when I can `sudo nixos-rebuild`.

Ideally I could call a function like `builtins.readFromPasswordStore` within
configuration.nix. This would allow me to skip the step where I run...

```shell
> ssh socrates
> pass show finance/monzo/client-id | sudo tee /etc/secrets/monzo-client-id
> pass show finance/monzo/client-secret | sudo tee /etc/secrets/monzo-client-secret
> # etc
```

...I don't know how to manage secrets using NixOS, but at least this is one
answer.
2020-02-23 19:32:49 +00:00
William Carroll
527b472469 Converge naming of Acer laptop to "socrates"
Prefer "socrates" to "flattop".
2020-02-22 19:04:12 +00:00
William Carroll
695de12482 Incorporate NixOS configuration
TL;DR:
- Move /etc/nixos/configuration.nix -> //nixos/configuration.nix
- Move /etc/nixos/hardware-configuration.nix -> //nixos/harware.nix
- Document installer.nix
- Create rebuild.nix wrapper around `sudo nixos-rebuild switch`

Previously I sketched ideas for the configuration.nix for socrates -- also known
as flattop -- the inexpensive Acer laptop residing in my flat and stored that
configuration.nix file in briefcase. Now, however, I have successfully installed
NixOS onto socrates. By default NixOS saves the configuration.nix and
hardware-configuration.nix files to /etc/nixos/. I'm moving both of these files
into briefcase.

Because the command `nixos-rebuild` looks for the NixOS configuration
file in /etc/nixos, I wrote rebuild.nix, which creates a program to
call `nixos-rebuild` with the new location of my configuration.nix.
2020-02-22 18:44:44 +00:00
William Carroll
b53ae61db2 Read PG's Lisp for Web-Based Applications
Read Paul Graham's notes about the benefits of building Viaweb with Lisp. I
found it interesting how his competitors (in the 90s) were using CGI scripts to
build their web applications. I wonder how much of his advice would hold true
today...
2020-02-21 19:47:54 +00:00
William Carroll
00177d2e65 Read two PG essays
- Programming Bottom-Up: Benefits of writing reusable utility functions and
  amassing a personal utility belt. Specifically how lisp makes this easier than
  most or all languages.
- This Year We Can End the Death Penalty: Voting against the death penalty is
  voting against the killing of killers *and* the killing of innocent people,
  since some estimate that 4% of people on death row are in fact innocent.
2020-02-21 12:29:28 +00:00
William Carroll
0dd3987821 Solve InterviewCake's inflight-entertainment problem
Write a predicate that tests whether two films in a list of films can exactly
fill the duration of a flight.
2020-02-21 11:30:01 +00:00
William Carroll
6895b8b1ef Track which Paul Graham essays I've read and haven't read
As I mention at the top of the org file, I cannot rely on my web browser
informing me which of these essays I've read; it only shows me which of the
links I've clicked.
2020-02-21 09:38:34 +00:00
William Carroll
1fbc80359b Support ssh/{sudo-buffer,cd-home}
- Support command to open a dired buffer with wpcarro's $HOME directory for any
  host defined in ssh/hosts.
- Support opening the current buffer with sudo privileges.
2020-02-20 23:18:59 +00:00
William Carroll
79013316a6 Support installer.nix
The command...
nix-build -A config.system.build.isoImage -I nixos-config=installer.nix nixos
...creates an .iso file in the ./result directory. You can then copy this onto a
USB and use it a custom installer...
cp ./result/iso/*-linux.iso /dev/sda

I needed an installer that used a version of the Linux kernel higher than the
one distributed on NixOS's website: 4.19.? -> 5.4.20+. My Acer laptop needed a
version of the kernel that supported its network controller: Intel 3168NGW.

TODO(wpcarro): Pin the nixpkgs git commit SHA inside of installer.nix.
2020-02-20 19:51:51 +00:00
William Carroll
01f0ebfa32 Support basic nixos/configuration.nix
I'm attempting to configure an old Acer laptop that I bought at a used
electronics store in Shepherd's Bush (~100GBP) as my server. I'd like to install
NixOS on it. The configuration.nix herein defines a starting point for the
configuration for that machine. It isn't currently working.

Troubleshooting and solutions forthcoming...
2020-02-20 19:49:15 +00:00
William Carroll
66c38f8656 Solve InterviewCake's cafe-order-checker problem
Write a predicate that tests if a given list of integers, zs, is a possible
interleaving of two other lists, xs and ys.
2020-02-20 15:20:58 +00:00
William Carroll
737bdd0a23 Solve InterviewCake's merge sorted arrays question
Write a function merging two sorted arrays into one sorted array.
2020-02-19 16:02:38 +00:00
William Carroll
00e3526d9a Support SSH config for acer machine
I'd like to setup a NixOS machine that runs in my flat to host my blog and other
projects. For now it's a slow Acer running Manjaro Linux. I'm hoping that I can
install NixOS on it remotely over SSH. But first! SSH access...

I setup port forwarding from my router to this machine for:
- HTTP
- HTTPS
- SSH
2020-02-19 15:01:42 +00:00
William Carroll
ca6bd29ed8 Solve bonus part of reverse-words
InterviewCake asks "How would you handle punctuation?". Without precise specs
about what that entails, I'm supporting sentences ending with punctuation.
2020-02-19 15:01:42 +00:00
William Carroll
acf1b8c4f0 Solve InterviewCake's reverse-words
Wrote a function to reverse the words in a list of characters. A word is a
space-delimited strings of characters.

The trick here is to first reverse the entire string and then reverse each word
individually.
2020-02-19 15:01:42 +00:00
William Carroll
9fc29831e0 Configure ssh preferences
Every Tuesday I work from Google's 6PS office instead of BEL. I work from my
laptop, which often requires that I ssh into the desktop work station in BEL. I
have settled on a locally optimal workflow that I'd like to improve. To help
seek higher ground, I'm planning on using ssh.el to configure tramp and define
utility functions to lower my cost of exploring new workflows.

- Defines a function, `ssh/desktop-cd-home` that helps me quickly open a dired
  buffer for my work station's home directory.
- Documents some variables that I set weeks ago.
- Requires ssh.el in init.el.
2020-02-18 11:18:02 +00:00
William Carroll
993f7c9389 Further configure notmuch
Until now my notmuch is usable but not almost always pleasurably so. For
example, when I reply to messages, notmuch warns that "Insert failed:"; when I
check Gmail, the reply sent... strange. After consulting with a fellow notmuch
user and Emacs disciple, tazjin@, I borrowed some of his notmuch configuration.

- notmuch is no longer warning about replies
- Replies do not include noisy email signatures
- I have an Emacs User-Agent header in my outgoing mail
- All of this and more...
2020-02-18 11:09:03 +00:00
William Carroll
6f179afd49 Define KBD for find-file-at-point (i.e. ffap)
I'm attempting to incorporate the beloved find-file-at-point function into my
workflow.
2020-02-18 11:09:03 +00:00
William Carroll
159301da50 Further specify saved searches for tags
Add tag:unread to:
- direct
- broadcast
- systems

Additionally: I added "and not tag:sent" for direct because oftentimes I send
myself mail. Without that condition, my sent mail shows up in direct.
2020-02-18 11:09:03 +00:00
William Carroll
2e63a4e2e1 Require keybindings.el after wpc-keybindings.el
keybindings.el calls (require 'evil-ex), which I introduced in this commit...
0456a1c4b4
...calling (require 'evil-ex) loads evil. When evil is loaded before
evil-want-integration is set to nil, evil-collection writes to *Warnings* when
Emacs initializes, which I find noisy. This commit ensures the
evil-want-integration is set to nil before evil is loaded, which appeases
evil-collection and thus removes the warning message.

Bonus:
If you git checkout the previous commit, and attempt to run the KBDs...
- `SPC g s`: magit-status
- `s h`: evil-window-vsplit
...from a buffer whose major-mode is dired-mode, you should notice that the
above functions won't execute.

Strangely though, if you look at this commit...
37f8ca04f2
...I fixed these issues. Well I introduced a regression when I added 0456a1c.

My current guess is that when evil-collection complains about
evil-want-integration, it is breaking the evaluation sequence of my init.el
file. wpc-dired.el is downstream from wpc-keybindings.el, which requires
evil-collection. Perhaps no modules required after wpc-keybindings.el are
evaluated after evil-collection warns about evil-want-integration. Even if that
assumption is wrong, what I do know is that this commit fixes the
evil-collection warning and restores the KBDs for dired-mode-map.

Here's to feeding two birds with one scone!
2020-02-17 22:40:41 +00:00
William Carroll
e61965cafd Drop support for compton
I'm finding myself running `pkill compton` offer. In the spirit of slimming down
my configuration, I'm dropping support for compton.
2020-02-17 21:18:03 +00:00
William Carroll
62ea675d7a Alias systemctl
Support `systemctl` and `systemctl --user`.
2020-02-16 22:09:47 +00:00
William Carroll
6051654527 Support additional notmuch saved queries
Today I setup declarative gmail filters using some Google internal tooling. I'm
now adding labels to messages from Critique, Sphinx, Ganpati, "The Daily
Insider", messages sent directly to me, and more. These labels are applied
server-side.

On the notmuch, client-side, I'm support saved queries for these newly created
gmail labels.
2020-02-16 17:16:05 +00:00
William Carroll
08c3f6dd69 Support KBDs for labelling emails
I can already tag emails with `+` and `-`. Here I'm defining KBDs for moving
messages from my inbox into: action, review, and waiting. I'm also mutually
excluding messages in action, review, and waiting from inbox and vice versa.

I'm also supporting a "muted" tag for now; I'm still learning how to use notmuch
with email threads, but I'm hoping the "muted" tag will prevent future messages
in a thread from arriving in my inbox.
2020-02-16 17:13:21 +00:00
William Carroll
1ed7f2ed73 Prefer newest-to-oldest sorting
The default sorting order of results from notmuch.el are in
oldest-to-newest. This prefers the opposite.
2020-02-14 18:01:38 +00:00
William Carroll
a726bf737a Enable lieer-google.timer
After running `systemctl --user enable lieer-google.timer`, systemctl created a
symlink pointing from timers.target.wants -> ../lieer-google.timer. I'm not sure
if tracking symlinks in a git repository is such a useful idea.

This commit reminds me that I could and should be using Nix to better manage
symlink creation and destruction.
2020-02-14 15:43:37 +00:00
William Carroll
0456a1c4b4 Define notmuch KBDs
Until I have more opinions about my workflow with notmuch, I will redefine the
KBDs from Gmail that I'm comfortable with. While not many KBDs are defined here,
evil-collection defines dozens, many of which I find reasonable; those that I
disagree with, I've unbound in this commit.

Composing emails in notmuch feels similar to writing a commit message with
magit. I want to be able to type :x or :wq, but these commands don't DWIM. For
magit, I'd like that behavior to be the same as `C-c C-c`; not surprisingly, for
notmuch, I'd like the same.

I've bound :x to do this for notmuch. I'd like to define a macro that can easily
define buffer-local evil-ex commands for particular modes. This should lower the
cost of defining evil-ex commands and hopefully convince me to support some of
this desired behavior.
2020-02-14 15:38:28 +00:00
William Carroll
8105af7b8d Configure saved searches for notmuch
Mimmicking the "action", "review", and "waiting" labels that I had in Gmail
using the equivalent labels as tags in notmuch.
2020-02-14 15:38:05 +00:00
William Carroll
fa779ab7bf Support list/xs-distinct-by?
Supporting a predicate to check that all elements in a list are distinct after
applying a transformation function to them.
2020-02-14 15:34:56 +00:00
William Carroll
3677a7a39e Begin supporting notmuch in Emacs
I'm borrowing from @tazjin's dotfiles, which are stored in Git on Borg. When you
call `nix-build ~/briefcase/mail`, result will output a systemd units, which you
should move to ~/.config/systemd/user/.

The path to `gmi`, which is Lieer's executable, exists in /nix/store, and you
can read it from the systemd unit file (i.e. lieer-google.service). Lieer
synchronizes notmuch with Gmail and Gmail with notmuch.

Here's a general sequence of commands that I ran to set everything up. Special
thank you to @tazjin for helping me with all of this. These steps are not
certified as a tutorial; I'm recalling them from memory. When I set this up
things didn't work as expected immediately and I had to troubleshoot.

```shell
> mkdir -p ~/mail/account.google
> cd ~/mail/account.google
> nix-env -iA nixpkgs.notmuch
> notmuch setup
> nix-build ~/briefcase/mail
> cp ./result/lieer-google.{service,timer} ~/.config/systemd/user
> rm ./result
> systemctl --user cat lieer-google
...copy the /nix/store path to gmi...
> notmuch new
> /nix/store/gmi init
...follow the OAuth login flow...
>
```

Unknowns?
- Do I need to call `systemctl --user start lieer-google` at startup? Or should
  I move these units to user/default.target.wants?
- Can I send email from notmuch?
- How do I use notmuch to delete email? To respond to emails? To do anything?

Todo:
- Once this configuration stabilizes, I should package everything with Nix.
2020-02-13 18:32:26 +00:00
William Carroll
9fa97eab67 Solve merging-ranges
Write a function to merge meeting times. Added an in-place solution, which the
"Bonus" section suggested attempting to solve.

- Added some simple benchmarks to test the performance differences between the
  in-place and not-in-place variants. To my surprise, the in-place solution was
  consistently slower than the not-in-place solution.
2020-02-13 14:52:20 +00:00