rules to live by

I'm writing this in the wake of the Pulse club shootings in Orlando.

If you're reading this, I'm aware that you probably know or like me (because who else would care about my blog?). I realized that I know and love a lot of people who regularly attend religious services. And in the coming weeks, the sermons in their services are going to address this shooting.

Some sermons will approach the topic with love and compassion and say that no one should commit such an evil act. However, some will say that it was God's will, or that being gay is evil, or gays deserve to die. I'm mostly writing this to explain why I disagree with the latter. Within this explanation is my basic stance on life.


I try to do less harm than good. To remember to do that, I've created a few rules for myself, and I try to adhere to them while going about my life. Some of these rules are straightforward and practical, like "Don't wear high heels while drunk". But the majority of these rules all center around one main one.

The main rule is to not be terrible.

Over the years, I've had to define what "terrible" means. My definition of terrible involves impinging on living beings' happiness without their consent. There are different degrees of terrible acts, depending on:

  • How many living beings are affected
  • How long they have been/will be affected (a proxy for how deeply they've been hurt)
  • How much they can experience being affected
  • How terrible the affected beings are themselves
  • Whether the act is deliberate or consequential

Some of the factors that determine how terrible a person is include:

  • How aware they are of doing the terrible thing
  • How long they have been doing the terrible thing
  • What forces compel them to do the terrible thing
  • What forces prevent them from stopping doing the terrible thing
  • Whether that terrible thing is isolated/stoppable or systemic/hard to stop
  • Whether that terrible thing is to prevent something worse, or is in the service of something good

Thinking about this rule has made it easy to prioritize what to care about, because the things that matter most are the ones that actively prevent terrible things.

Helping people when they need it? Ok.
Keeping house? Nope.
Money? I guess having it can help someone.
Praying? Not really.
Writing a local representative? Maybe. Do they even read those?
Stopping an active shooter? Probably worth it if I don't get killed immediately.
Meeting deadlines? Is someone literally gonna be dead because I don't make a deadline? If not, then no.

Sometimes I care about some of this other stuff because other people care or are affected by it. But when all I really want to do is prevent the most terrible things-- suffering and death-- from happening in the known universe, the other stuff is small beans.

This rule has had some remarkable repercussions. I was raised Catholic and fairly conservatively. Because I care about life, I agree with the church's harsh stance on issues like guns and the death penalty, and I recognize that they're the largest non-governmental provider of health services in the world.

And because I care about life, I disagree with their stance on issues like abortion. I do agree that life begins at conception. But as someone who studied biology, I know that a clump of cells has less life in it than a mosquito, which is much less life than a full-grown woman whose life potential would be unduly taken away from her if she were forced to carry a child to term. In this case, I would rather be terrible to the clump of cells-- it doesn't have a fully developed nervous system, so it can't feel or remember pain and suffering to the extent that a woman can.

As someone who studied biology, I also take issue with the church's stance on sexuality, gender, and gender roles. Homosexuality does occur in nature. It may be unusual in mammals, but it's natural. (Flowers get really freaky with each other. And themselves.)

As someone whose own marriage would have been illegal less than a century ago, I'd like to point out that the things people claim are unnatural and that God finds disgusting have changed and will continue to do so. So if people want to do something to increase their happiness or ease their suffering and it won't harm anyone else, no matter how weird it might be to me, it's not my place to voice an opinion about it.

I generally disagree with having social norms, such as some forms of organized religion, normative whiteness, and heteronormativity, because they create a culture that not everyone fits into. That leads to the rejection of whatever and whoever doesn't fit those norms, which leads to the existence of outsiders to that culture. Being an outsider can result in discrimination-- in some cases, even death.

I still try not to be a terrible Catholic. But more importantly, I'm trying not to be a terrible person. I don't condone being terrible to someone because they don't fit in, or because they don't follow arbitrary rules about how to look or act. They must have participated in harming another living being for me to even consider being terrible to them.

Anyway, if you're trying not to be terrible, and are maybe even trying to help others, I personally believe that God is pretty accepting and doesn't have strong opinions on what you do otherwise. I just wish more humans could be like that. And, if nothing else, I wish we could agree on what being terrible means.

seeing the future

I moonlight as a fiction writer. I've been writing stories since kindergarten. As a middle schooler, I wrote a lot of science fiction. That whole imaginary worlds thing tapered off as I grew up and figured out how to deal with other people by writing about theoretical human drama. I'm glad I finally got back into science fiction; it's a lot more fun to imagine new concepts than it is to plot out the interactions between angsty teenagers.

Over the past several months, I've been working on a novel set almost a century into the future (at the very least). I call it my keitai novel because I've been writing it mostly on my phone during subway rides to and from the office. It's a little tricky to extrapolate current trends and research into what will actually happen a hundred years from now. But I remind myself that even Jules Verne and Gene Roddenberry didn't get everything right about the future, and they made up for it by illustrating the possibilities so enticingly that people decades and centuries later have taken it upon themselves to work toward substantiating the futures they described.

Some of the ideas I'm incorporating are a little more straightforward and technical, like bioencryption and the laws governing autonomous artificial intelligence. (Of course, the AIs don't call themselves that because they don't consider themselves "artificial".) But I've added other details that were extrapolated and analogized from current events, such as China descending into civil war, which means huge numbers of refugees with manufacturing and engineering expertise are fleeing China and turning stateless-- communities ripe for an alliance with rebel AIs that need people to repair them, and to help them enter the international political scene with some clout. Other details are largely visual and philosophical: this is a world where virtual/augmented reality glasses (VARGs) are widespread, and young people wear them all the time, adding a layer of psychedelic gamified nonsense on top of everything they experience.

It's fun thinking up what might be in store for humankind, but that's not really what this novel is about. To be an effective writer, I have to drop all of this history during the course of the story and not let it get in the way of the plot; I can't explain everything outright like I did above, because that would interrupt the novel's flow and believability. I think the best science fiction writers manage to convey a completely different world mostly in passing-- for example, William Gibson might drop a stray detail during a conversation that implies an entire war happened decades before the characters met. I want to create a future that can draw readers all the way in like that, but also compel them to dream about what's possible in the world we actually live in, and how to get from point A to point B.

asynchronicity

For the past month, I've been working on getting the latest version of my company's flagship website up and running. The part that personally caused me the most grief was the commerce-related scripts. I spent an entire weekend stumbling through them before it became clear that even though I'd worked with asynchronous functions in JavaScript before, I had no idea what I was doing.

Golden retriever wearing a necktie sitting at a computer: "I have no idea what I'm doing"

My boss realized what the trouble was, and the following Monday, she sat me down and gave me a twenty-minute rundown of SQL transactions, JavaScript promises and how they're related to ES7's new async/await function, and how to properly handle async errors using the try/catch/finally pattern. While she was at it, she showed me how the famed Express router's error handling works, and all the gotchas that come with it. I'm pretty sure she saved me months of my future life trying to figure this stuff out.

My main takeaways were (in ascending order of confusion):

  • Error handling
    • I seriously did not know how to throw an error within a try/catch. It's literally throw 'Error message'.
    • If you're going to pass any variables besides an error into a catch, declare it outside of the try/catch and then set it within the try. Otherwise catch doesn't know about anything that happens within try.
  • Promises
    • The function you're waiting for should have a try/catch in which you invoke resolve() upon a success and reject() upon catching an error. (Don't forget to pass those functions in from the Promise invocation.)
    • You can avoid true callback hell by using then/catches (like this one: promiseFunction().then().catch((error)=>{})) infinite times in what's called a "promise chain".
    • Promise chains are easier to work with than callback hell, but they're still only one step removed from callback hell.
  • Async/Await
    • async is basically a promise wrapper that prevents you from having to deal with all the .then().catch().then() of promise chain error handling, further shielding you from the horrors of callback hell.
    • Instead, you keep functions to await in a try/catch, and they are run chronologically, like normal functions.
    • You can technically await straight promises, but you shouldn't need to...
    • ...unless you're awaiting the end of a string of promises that are called asynchronously, in which case you should put them in an array in await Promise.all();, because the corresponding await* function didn't make it into the ES7 release.
  • Express.js with Async/Await + Promises
    • For every CRUD operation, you should only have one async function that returns a promise, and that's for the request that hits the server endpoint.
    • Every other client-side async function only awaits these request functions. There should be no other promises in your data-related code, with the exception of Promise.all() for the reason mentioned earlier.
  • SQL Transactions and Try/Catch/Finally
    • On the server side, instead of doing a series of straight SQL queries that change the database, you can open a database connection in a try statement and create the series of queries, then commit the whole transaction only at the very end, after everything else checks out.
    • If any part of the transaction fails, you can catch the error and rollback the entire transaction so that no part of it ever happens.
    • (And in the finally, if you still have a connection, you should release it.)
    • This allows you to make several related queries at once without being afraid that only some of them will go through, which could mess up your database.
    • Non-database functions that are harder to undo, like order or email sending, should be at the very end of the try statement, just before you commit the transaction. So if any other part of the try fails, those critical functions won't be run.
  • Some serious Express gotchas
    • The error handler is the first function passed into the router with four parameters (error, request, response, next) instead of three (request, response, next).
    • If you're passing anything into your next() function, it's read as an error and it'll go straight to the error handler.

One of the reasons I took this job was because during my interview, everyone I talked to taught me something new. I've been learning a lot from people here who are not only very knowledgeable, but willing to share their knowledge with others. Hopefully I'll get to a point where I can pay it forward more often.

trekking through the amazon

A few months ago, I learned about the t2.nano, a new Amazon EC2 instance that was cheaper than my old t2.micro ($5 a month versus $10), so I tried switching over to it and promptly bricked the whole thing, which was why this blog wasn't working for a while.

I started a new job that required me to learn a lot more about Amazon services, so this week I decided to take another crack at migrating my blog instance over. This time I even properly documented everything. It took several long evenings (and a panicked rewriting of my commit history after I pushed up some config files to GitHub that I really shouldn't have, which resulted in my emailer promptly getting hacked and turned into a spamming device), but it's now on the smaller nano instance and purring like a kitten.

While cussing at my laptop, I learned a lot about:

  • SSHing into stuff and making that process easier
  • How RSA keys are handled between hosts
  • Cloning Amazon EC2 instances and EBS volumes
  • Copying files to and from remote hosts (scp)
  • Obscure Git commands that you only need to know when you've seriously ****ed some **** up

    I really ****ed some **** up I really ****ed some **** up

This was all basic web deployment stuff I've been wanting to get deeper into, since my main goal as a web developer is to be able to create and run applications by myself. While the frontend has always been my jam (I like making things people can immediately use), I figure that if I can be a one-stop shop, I'll be of much more use to smaller places that really need a web presence, such as nonprofits and small businesses.

People have already suggested other improvements I can make to the blog, like adding encryption. I could also make my Ghost instance a static site using Buster (a.k.a. 'Ghost Buster'), since storing it in an Amazon S3 bucket would be even cheaper-- around $3 a month. I'll consider some of these options. But before that, I'd like to just enjoy having it back up and running.

It was only a couple of years ago that I became a web developer, but in that time, it feels like I went to college again and learned twice as much as I had the first time around. I started this blog in 2014; I'm kind of surprised that I managed to do it, since I was blindly copy-pasting terminal commands from Stack Overflow and hoping for the best. I know so much more about how this all works now.

Edit: I still blindly copy-paste terminal commands from Stack Overflow and hope for the best, but not as often as I used to.

another year, another bot

My 2015 has been filled with long and arduous international and domestic travel, plenty of family business, a cross-country move, and a deferred to-do list a mile high. I haven't been keeping regular hours since the beginning of the year, so I'm glad that the dust has settled and I have a little free time to learn and work on new things again.

I finally made a version of the bang bot that is police-oriented (and less pervy-sounding). The Washington Post's fatal police shootings database is reliably updated, and it's on GitHub so it was much easier for me to get raw data from (otherwise I would have to do some manual scraping-- not hard, just time-consuming).

The bot's checking mechanism was the simplest one I could come up with:

  1. Pull the latest .csv file on WaPo's GitHub
  2. Check if the number of lines is greater than that of the last stored version, and
  3. Tweet that number if it is.

The implementation's still got a few kinks (apparently you can't use Twitter's API to tweet the same thing twice, which may be a problem soon), but my previous experience with Node made building it fairly easy.

It was the deployment that gave me some trouble. I used Heroku to run my app this time, and it took me a while to realize that the reason my files weren't properly saving was because Heroku workers don't do data persistence (derp). So I had to pick a data storage addon. I would have liked to use MongoDB to make the app JS end-to-end, but it wasn't free. And I'm pretty familiar with Postgres after having used it for a class earlier this year, but I ultimately went with Redis, another NoSQL choice that's fast and has an easy-to-use Node.js client. I hear that relational databases are the way to go if you have a data structure that's even remotely complicated, but I only had to store two things.

A screenshot of callback hell. Can you tell I'm using Node?

Besides storage, I still haven't quite gotten the hang of JavaScript's asynchronous processes yet (please refer to the callback hell in the screenshot above). I tried to keep things readable, but I think I'm gonna just bite the bullet next time and use async.

The reason I started this project was to get an update on Twitter whenever WaPo confirms another death by police shooting, and I'm glad I reached that goal. But seeing the bot tweet for the first time on production was the first time I had ever felt sad about seeing something I built actually work.

Now that I'm getting into full-stack development, I'm exploring what else I can do with open data. My final project for the back-end class that I took this spring used data made available by San Francisco's Human Services Agency. Similar municipal open data initiatives are happening in New York City, which is where I'm based now. I hope to build bigger and more useful applications with some of this information in the future.