The Secret Life of Cows
https://deterministic.space/secret-life-of-cows.html
TIL that you can use Rust’s Cow
for representing a type that can either be borrowed or owned. This can be useful when you want to, for example, return either a static string (&'static str
) or a dynamically generated owned string (String
) from a function.
Week of 20 April, 2020
- Anxiety was bad this week. I was up until 3AM on Tuesday night because I couldn’t turn off my brain, no matter how much I tried. I don’t know what triggered it, but getting off social media and news websites seems to have fixed it.
- I’ve started spending a bit of time each morning reading short stories in Punjabi. I no longer struggle with the grammar or the script—I’ve already been reading the news in Punjabi for a few months—but a lot of the words are new to me. Having to constantly look up words slows me down, but I’m building a lot of vocabulary very fast.
- I’ve given in and ordered a Roomba for the house.
- Our girl kitten turned out to be a boy kitten, which explains the constant fights. The older cat doesn’t like this new roommate at all.
- Not much progress with Crafting Interpreters this week, but I did add a way to convert an AST into a Graphviz diagram. Very proud of this one.
GoAccess
CloudFlare recently informed me that this website was getting thousands of hits every day, which is an unusual occurrence. I pulled up Google Analytics to figure out where all that traffic was coming from, only to be informed that I was getting three to four hundred daily visitors at most.
This felt a bit suspicious, so I dug into my Nginx logs to see if something was up. I pulled up the logs in Vim, but it was too hard to make sense of any of the raw data by reading it line-by-line. I needed something that could help me visualize my logs. I asked around and found a little tool called GoAccess.
GoAccess is an open-source log analyzer that can help you visualize your server logs in the terminal or use them to produce an HTML report. I installed it from the Ubuntu repositories and ran it:
$ goaccess /var/log/nginx/access.log
I was greeted with a dialog listing a bunch of popular log formats, asking me which one my file conformed to. After searching the Web for a bit, I figured out that Nginx uses something called the NCSA Combined Log Format for its messages. I picked that in the dialog and was on my way.
After a few minutes of looking at the aggregated data, I felt that analyzing just one file wasn’t telling me the entire story. I wondered if I could analyze all the logs produced by Nginx in the last month at once. After searching the Web a bit more, I found that I could use zcat
to unzip the older logs and print them to stdout
, and then pipe that into GoAccess. So I did this:
$ zcat -f /var/log/nginx/access.log* | goaccess --log-format=COMBINED
Turns out someone was trying to exploit my website by by sending malicious inputs to WordPress’s xmlrpc.php
. From the access patterns, it looked more like a drive-by automated attack than a human trying to break in. Since I didn’t need any of the features enabled by the WordPress API, I blocked access to xmlrpc.php
entirely:
location = /xmlrpc.php {
deny all;
access_log off;
log_not_found off;
}
The downside to this is that I can’t post to my website from the WordPress app on my iPhone. But that’s not something I do often, so losing that feature is not a big deal.
After this incident, I also removed Google Analytics from my website. I’m fundamentally opposed to business models that are based on surveillance-based advertising, which is why I try to stay away from Google products as much as possible. My server logs give me enough data to judge how well my posts are doing, and with GoAccess I now have a reasonable way of querying and visualizing that data. That’s pretty much all I need.
Perpendicular
Years ago, when going outside was legal and I still believed in Pitchfork scores, I started a music blog with a couple of friends. We eventually shut it down because reasons, but thankfully The Wayback Machine managed to capture a few snapshots.
Here it is in all its glory, minus the CSS and media.
Week of 13 April, 2020
- The cats have stopped fighting! Minor squabbles still break out once or twice a day, but for the most part they’ve settled into an uneasy truce.
- Found a contract for the next six weeks. It’s not a Rust gig as I had hoped, but it involves some heavyweight data visualization in the browser that will call for a lot of cleverness. I expect to enjoy this thoroughly.
- Eating a lot of cheese this week. No regrets.
- Working through Crafting Interpreters at a decent pace, though I could probably be going faster. Instead of just translating the Java code in the book, I’m trying to write idiomatic Rust as far as possible. This takes longer and makes my design totally different from what’s in the book, but I’m learning far more this way. I’ve also added a few additional features to my implementation, like proper line editing in the REPL using rustyline.
- My fitness trainer now has an online lesson plan, so I’m back to working out. Feels good to be doing something with this bag of meat.
- Still irritated at how much pointless detail that Gandhi book has. But I’m going to get through this thing one way or another.
- Still playing Radiant Historia and Into the Breach, still loving the hell out of both games.
- Album highlight of the week is Cha Cha Palace by Angelica Garcia.
The Expression Problem
While reading Crafting Interpreters, I learned about something called the expression problem. It’s a problem I’ve run into countless times, especially in larger projects, but I never knew it had an actual name. As usual, Eli Bendersky has an in-depth article about the problem and its solution in C++ and Clojure.
After reading Eli’s article, I wondered how the problem would manifest in Rust and what the solution would be. Turns out it’s not too complicated. Want to add a new type? Just add it and implement all the traits you care about. Want to add a new operation? Define a new trait and implement it on all the types you care about. This article goes into more detail on what that looks like.
Week of April 6, 2020
- Spent a lot of time on calls with potential clients. Happy to report that I can sound very professional even when I’m not wearing pants.
- Started reading Crafting Interpreters. With a lot more Rust under my belt than the last time I tried this, things are going better than I expected. I even managed to add reasonable (by my standards) error handling to my baby interpreter!
- Started posting things on this blog again, trying to keep it fun and low-stakes. I want to have fun writing, and turns out Growing an Audience™ and Using Fully-Formed Sentences™ is the exact opposite of fun.
- Played a lot of Radiant Historia on the 3DS. I’m loving the gameplay and story so far, but the combat needs to get more interesting soon.
- Played a few hours of Into the Breach on the Switch. Holy. Fucking. Shit. This is easily one of the best designed video games I’ve ever played. I see myself pouring many many hours into this gem!
- We got a new kitten just before pandemic, hoping that she’d become friends with our older cat. Did not go according to plan. It’s impossible to leave them in the same room together without one of them trying to murder the other every five minutes. We’re keeping them separate for now, hoping for at least an uncomfortable truce.
- The first half of Gandhi: The Years that Changed the World was incredible, but now the book is getting repetitive. It has a lot of detail that I consider unnecessary. I’m somehow powering through the last 200 pages so I can pick up Ursula K. Le Guin’s Earthsea series.
- Some albums I enjoyed this week were: Saint Cloud by Waxahatchee, 2017-2019 by Against All Logic, and Aarupa by Quinton Barnes.
People Sure Have Opinions About Programming Languages
- From Lobsters: Say something nice about a programming language you dislike
- From Lobsters: Say something you dislike about a programming language you love
- From Lobsters: What are some niche features you’d like to see in more languages?
- From /r/ProgrammingLanguages: What are some niche features you’d like to see in more languages?
- From /r/programming: What are some niche programming features you’d like to see in more languages?
tl;dr: everyone loves pattern matching.
Arundhati Roy on the Morally Appropriate Language in Which to Think and Write
What is the Morally Appropriate Language in Which to Think and Write? is one of my favorite pieces of writing on the Internet. At its core, the essay is about using translation as a primary form of literary creation in a country as linguistically diverse as India. Put another way, it’s about Arundhati Roy’s quest to bend English in such a way that it captures some of the flavor of India’s many tongues.
While I haven’t read any of Roy’s novels, I recently read a different book that pulls off this feat admirably: Midnight’s Children by Salman Rushdie. One of my favorite scenes from Midnight’s Children is where a mother yells at her child: “Fool from somewhere!”
Roy’s essay covers a lot of ground. If I start quoting from it then I’ll end up reproducing the entire piece here, so I’ll just mention two of my favorite parts. The first one is how English is perceived in the Dalit community:
[English] is also the language of emancipation, the language in which privilege has been eloquently denounced. Annihilation of Caste by Dr. B. R. Ambedkar, the most widely read, widely translated, and devastating denunciation of the Hindu caste system, was written in English. It revolutionized the debate on perhaps the most brutal system of institutionalized injustice that any society has ever dreamed up. How different things would have been had the privileged castes managed to contain Ambedkar’s writing in a language that only his own caste and community could read. Inspired by him, many Dalit activists today see the denial of a quality English education to the underprivileged (in the name of nationalism or anticolonialism) as a continuation of the Brahmin tradition of denying education and literacy—or, for that matter, simply the right to pursue knowledge and accumulate wealth—to people they consider “shudras” and “outcastes.” To make this point, in 2011 the Dalit scholar Chandra Bhan Prasad built a village temple to the Dalit Goddess of English. “She is the symbol of Dalit Renaissance,” he said. “We will use English to rise up the ladder and become free forever.”
The second one is about how Devanagari—associated at the time and perhaps even now with Brahamanical oppression—came to be the primary script in which modern Hindi is written, erasing the once-popular Kaithi script from public memory:
In order to clearly define itself and mark itself off from other competing constituencies, the newly emerging Hindu constituency [in British India] needed cultural symbols—something to fire the imagination of its evangelists and its potential recruits. The holy cow and the holy script became the chosen vehicles for mobilization. Gau Rakshak (cow protection) societies proliferated, and simultaneously the demand was raised that Devanagari (Deva as in Dio/God—the script of the Gods) be officially accepted as a second script for Urdu. Devanagari, originally known as Babhni, was the script of Brahmins and had, like Sanskrit, been jealously guarded, its purity protected from the “polluting influence” of lower castes, who had, for centuries, been denied the right to learn Sanskrit. But the changing times now required that it be promoted as the indigenous script of “the people.” In fact, the more widely used script at the time was a script called Kaithi. But Kaithi was used by non-Brahmin castes like the Kayasthas, who were seen to be partial to Muslims. Extraordinarily, in a matter of a few decades, Kaithi was not just discarded, but erased from public memory.
I’d never heard of Kaithi before reading this essay. Digging around a bit, I found a wonderful piece about the script on Satyagraha: कभी हिंदी और उर्दू से ज़्यादा इस्तेमाल होने वाली कैथी खत्म कैसे हो गई?
Fairy Tales
Fairy tales are more than true: not because they tell us that dragons exist, but because they tell us that dragons can be beaten.
— Neil Gaiman, from Coraline