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.
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.
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!
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`.
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.
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.
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.
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.
"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.
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.
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.
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...
- 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.
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.
- 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.
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.
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...
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
InterviewCake asks "How would you handle punctuation?". Without precise specs
about what that entails, I'm supporting sentences ending with punctuation.
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.
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.
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...
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.
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!
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.
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.
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.
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.
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.
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.
After working with fish for a few weeks, I've decided that I prefer aliases to
abbreviations.
Why? When I reverse search through my command history, I search for the
what I typed and not what it expanded to. Some of my aliases wrap existing
tools encoding my preference for tool A if tool B isn't available. For example I
alias vim to neovim. When nvim isn't available on $PATH, typing vim will
expand to nvim, which will in turn fail.
I previously had an alias defined as `simple_vim`, which would start an instance
of Vim with a bare bones config. I had a to-do to Nixify it. That is
now (mostly) to-done.
When I try and install it with `nix-env -f ~/briefcase -iA tools.simple_vim`,
Nix fails and says that pkgs.stdenv is undefined. I will need to fix this one
day, but it is neither important nor urgent...