How I Clean My Computer Screen

I’m incessantly dismayed at how dirty are most people’s computer screens. This is avoidable. It makes no sense to spend thousands of dollars on a computer that you don’t keep clean.1

If you don’t keep your computer screen clean, it’s ugly in the short-term, and it’s downright damaging in the long-term. When it’s there for months on end, that grime has a way of eating the screen; you’ll never be able to fully get the scar tissue healed. A case can be made for meticulously cleaning your screen every week.2

After years of trial and error, I’ve come upon the perfect method for keeping my computer screen as spotless as it was the day I removed the protective paper. First I set the screen brightness to zero and turn the screen so it reflects the light. Then I use a Falcon Touch Screen Wipe to get the major stuff off. After that’s dried, I use a microfiber cleaning cloth to remove the dried water streaks. You can use one that came with your sunglasses. Or these on Amazon look promising. The key is to make small circular strokes and to stay gentle. I spend a few minutes with the microfiber cloth. It takes patience to get the screen completely spotless and lint free. It’s worth it.

If you don’t start with a wet wipe, you run the danger of scratching your display. If you don’t finish with a dry cloth, you can’t fully get rid of the water streaks. It takes both, in that order.

I do this every week, and my screen looks amazing. That’s all there is to it. You’re welcome.


  1. How many muddy Lamborghinis do you see cruising down the road? ↩︎
  2. Your mileage will vary depending on how much you travel with your computer, and how much you eat and talk near it. A weekly cleaning might be excessive if you’re a few levels of careful above me. In my case, spit, dust, and food are summoned to my screen on an almost daily basis. ↩︎

The iPhone Franchise  

Ben Thomas, two days ago:

Apple released a new flagship iPhone yesterday, the iPhone XS.

This is the time of year where your social circle rolls its eyes at the “lack of innovation” that Apple demonstrated with its new iPhones. It makes you smile wanly though, because you know they have last year’s iPhones, and somehow, by this time next year, they’ll own this year’s. That’s because the iPhone is a franchise. Ben Thompson does a fantastic job laying this out, and I recommend reading his piece in its entirety. It’s calm, objective, and adroit, as usual.

GitHub Removes jQuery From Its Frontend  

The GitHub engineering team:

We have recently completed a milestone where we were able to drop jQuery as a dependency of the frontend code for GitHub.com. This marks the end of a gradual, years-long transition of increasingly decoupling from jQuery until we were able to completely remove the library.

jQuery played an important role back when the ecosystem of native JavaScript DOM APIs wasn’t as robust as it is today. At this point, I don’t think anybody really needs jQuery. I removed it from Drinking Caffeine last November. Rest in peace, once-useful thing.

GitHub’s iterative approach is perhaps the most important takeaway in this piece. The company has proven that big refactors are achievable if you’re willing to play a slow steady game.

Chrome Celebrates Ten Years With a New Look  

Ellie Powers and Chris Beckmann:

Today we celebrate Chrome’s 10th birthday, and just like a kid on the cusp of double digits, we’re constantly growing and changing. In the case of Chrome, those changes happen every six weeks to bring you new features and security updates, but our 10th birthday update is bigger than normal.

The new Chrome is awesome. It’s a fantastic update to the world’s greatest browser. Some Mac pundits have decried its look as being un-macOSy, but seriously, I think Chrome has a better UI and UX than does Safari for Mac. Specifically:

  • Safari’s address bar animation that occurs when you focus on it is distracting and time-consuming. It makes me feel inefficient. I know you can start typing in Safari’s address bar before the animation has completed, but still. Perception is reality.
  • Safari’s address bar is narrower and shorter than Chrome’s, which means it’s harder to click it. Small targets make for bad UI/UX.
  • Safari’s developer console feels 5 years behind Chrome’s. It has fewer options and it’s harder to do stuff in it. That might just be because I spend a lot more time in Chrome’s, but I don’t think so.

Apple should learn from Google how to build a good browser.

On Apple’s Discontinuation of the iPhone SE

Yesterday Thomas Brand wrote a piece that decried the removal of the iPhone SE on the grounds that it was the company’s only affordable iPhone for some customers. The underlying assumptions rubbed me the wrong way. I’m compelled to counter them here. He wrote:

If you are looking for a phone with a smaller screen, a phone with a headphone jack, or or a phone that costs under $400, Apple no longer makes an iPhone for you.

That’s fair, but the universe of people for whom any of this is true is small. Most people are happy with the screen sizes, port options, and pricing of the new lineup. Apple doesn’t like a product line with a long tail, and the time to remove the SE has come. Simplify, simplify, simplify.

Then:

In short, Apple has discontinued their entry-level iPhone SE in favor of larger phones that require additional adapters and cost upwards of $750.

I’d be curious how many people actually use adapters with their iPhones on a regular basis. I’m sure they’re out there, but my gut is that it’s a very small (albeit irksomely whiny) community. The puck has moved on.

Next:

The iPhone SE kept me invested in the iOS ecosystem, and enabled me to purchase a Apple Watch without approaching the ~$700 iPhone ASP I normally attribute to laptop computers. Now that an updated iPhone SE is no longer an option, I am evaluating alternative cell phone platforms. I am sure I am not alone.

I don’t know anybody who uses a $700 laptop. With tax included, I paid $3,037.39 for the MacBook Pro on which I’m writing this. A friend of mine paid around that amount for the Windows laptop he uses. If you use a laptop for work, you’re paying many multiples of Thomas’ figure. $700 will buy you a fairly decent Chromebook or a really horrific Windows machine. Both options are very pedestrian.

Apple made something very clear this week. If you don’t have $750 for an iPhone, you aren’t in its target market. Apple’s always been this way, directionally: to own an Apple product, you pay big money, often more than the competition, and in return you get a great product that has culture and taste. That’s the value proposition, the rule of engagement. If you find this appealing, you participate in Apple’s store. Otherwise you don’t. Apple isn’t that interested in people for whom money is the primary consideration. Apple was founded by a self-identifying hippie, and it wants customers who care about more than money. If everything in your life lives and dies by the almighty dollar, then you’re never going to understand or appreciate Apple. The company has sometimes managed to ensnare such persons by offering a low-cost product; but whenever it pulls it, their true colors show. Apple did everyone a favor this week by removing an iPhone priced as the SE was.

(Hat tip to Pixel Envy.)

Assign to New Variable Names in an Object Destructuring  

I had no idea until today that this was possible. But take this:

const user = {
  device: 'android',
  statement: 'iPhone X has the exact same OLED screen that Samsung phones have, albeit overpriced.',
};

Let’s say we want the statement piece of this object, but we don’t like the property name. We can do like so:

const { statement: claimChowder } = user;

Now, the claimChowder variable has the value:

iPhone X has the exact same OLED screen that Samsung phones have, albeit overpriced.

Groovy, right?

New iPhones to Be Announced September 12  

Juli Clover, writing at MacRumors:

Apple today sent out media invites for its annual iPhone-centric event that will be held on Wednesday, September 12 at 10:00 a.m. at the Steve Jobs Theater on the Apple Park Campus in Cupertino, California.

That’s the same date it was held last year. I’m stoked! Also, I wonder what they’ll call these new iPhones.

The Downsides of a Static Site Generator

Lately I’ve been concerned about static site generators. After using Jekyll and then Hugo extensively for a combined 2.5 years, I’m seeing things in new light.

First though, going from WordPress to Jekyll and Hugo is really popular. Here are the upsides of a static content generator:

  • It’s cheaper. You can host on GitHub pages, which is free.
  • It’s safer. A site that is nothing but .html files can’t be hacked, unless permissions are wonky.
  • It’s geekier. There’s a higher barrier to entry because it takes more knowledge than running a WordPress site. The exclusivity appeals to nerds with an ego. If we’re honest with ourselves, few of us who write software for a living are immune to this appeal.
  • It’s faster. There’s nothing faster than running a static HTML site.
  • It gives you version control via git. If you have a deploy process set up, pushing to your master branch is how you deploy a new blog post, which means git is a core part of your workflow.

But! But. There are downsides too. They’re a bit less tangible but they wear on you after a while. Let’s look at them.

  • Architecturally, database-driven design is superior to file-driven design. Marco Arment argued this point on the ATP show a while back. I disagreed with him at the time, but as I’ve gotten more experience and understand the nuances of the two systems, I’ve come to realize he’s right. Chris Pearson recently confirmed this during a Periscope episode. He argued for the superiority of a WordPress theme system being database-driven instead of file-driven. Thesis was built atop the database paradigm. It requires a different way of thinking, but it’s better for a few reasons.
    • Database-driven design gives you better flexibility. If you want to change the date structure or permalink structure of a static site’s posts, or if you want to introduce a new property to a post type, it’s a huge headache. You either have to be a regex ninja or make a lot of manual per-post changes or introduce confusing conditional logic in the render template. All of this is easier in a database-driven design. Same goes for complex things like search and per-month archive pages. Those things are a pain in static site generators compared to WordPress, and sometimes simply impossible given the constraints.
    • Similarly, database-driven design ensures maximum repeatability, whereas file-driven systems contain an innate amount of redundancy. If you’re having to repeat yourself a lot in a database-driven architecture, you’re doing something wrong; whereas in a file-driven architecture, you often don’t have much choice. For example, you often have to loop through a global list of posts and manually cherry-pick the ones you’re after for a given view, rather than just start out with the correct data like you could with a MySQL query.
  • Every time you do a new deploy in a file-driven system, you have to rebuild the entire website. That gets incrementally slower as you introduce more and more posts. Hugo is about 10x faster than Jekyll since it’s built in a compiled language (Go) rather than a scripting language (Ruby). Still, there’s a cognitive overhead in knowing that you’re slowing down the system with every new post you create. Database-driven designs are immune to this. Yes, there’s a slight performance cost to increasing the number of rows in the wp_posts table, but it’s infinitesimal compared to increasing the file count in a file-driven system.
  • Related, every time you write a new post in Hugo, you’re creating a new file in a flat directory. Pretty soon you have hundreds or thousands of files. This just feels wrong compared to having them elegantly tucked away in a paginated database table. Feelings matter.
  • WordPress has 28% of the global market. How much does Jekyll have? How much does Hugo have? A lot less than that. I’m not worried that Jekyll and Hugo will go away tomorrow. But they’re always going to be a fringe technology in the grand scheme of things. Building an empire on a fringe technology is a bad idea. I’ve seen it go awry too many times. And if I had to guess, WordPress will outlast these static content generators, ultimately, from a sheer numbers and sustainability standpoint. I want to use a platform that’s going to be around in 40 years.
  • In a similar vein, setup and configuration with a static file generator has a lot more pitfalls and obscure dependencies. It’s harder to get Go compiled and running than PHP and MySQL, simply because PHP and MySQL are more popular. You also have to support a deployment pipeline with a static site. I’ve personally found that the ongoing maintenance of a regularly-deployed static site is higher than the ongoing maintenance of a WordPress site. That is something I would not have expected. Live and learn.
  • Getting your content from WordPress is a lot easier than from Jekyll or Hugo. That’s because it’s easier to get importable data out of a database than it is from a collection of markdown files. I like systems that are easily exportable. Because of this, switching to a file-driven system seems like a step backwards in time, not forwards.
  • Bonus round: using a file-driven system means you don’t get to use Mars Edit to write your stuff. You’re stuck in Terminal and VSCode, which wouldn’t be a problem except that you’re in there 8+ hours per day already. Never underestimate the appeal of using a different set of equally elegant tools. It provides a mental break. That’s incredibly important. The most enjoyable tools are those dedicated to the job at hand.

On the whole, the cons of a static file generator seem less tangible than the pros. But I’ve been giving a lot of hard thought to this over the past few months. Intangibles matter. As a result, I’m seriously thinking about switching from Hugo to WordPress. Googling around, I’m not sure anyone’s done this yet. If I pull the trigger on the switch, I’ll be pioneering new ground and documenting the process as I go. Stay tuned. 😎

Thoughts on WordPress’ Gutenberg

First, watch this engaging Periscope by Chris Pearson, where he argues that Gutenberg is forcing a fork in the road for everyone. It’s well reasoned. But here are some counter-thoughts, from the perspective of an outsider.

  • Something is missing from Pearson’s narrative, the true meaning of which we often forget: simplicity is the ultimate sophistication. That doesn’t mean that things that appear simple are in fact truly simple. It means that things that appear simple require a lot of what Pearson would call “bloat” under the hood. While Gutenberg’s underlying architecture introduces greater code complexity, the resulting UI looks simpler. Gutenberg’s value proposition is to make things easier for the writer, in the same way that the original Gutenberg printing press introduced greater complexity but made book production easier. Making things easier (simpler) often requires added layers of underlying complexity (sophistication).
  • We’ve come to expect this sort of increased complexity in operating systems. macOS is infinitely more complex than it was when it debuted in 2001. So is iOS today compared to 2007. Does anyone really think that the original versions of these operating systems were superior compared to today’s? The “tell” in knowing where people stand on this is whether they upgrade. You can virtue signal all you want about the good old days, but when it’s all said and done, if you upgrade, you’re admitting that the latest is better overall. Are the rules of engagement that we set for operating systems different than what we expect from WordPress? If so then why?
  • I don’t agree that Gutenberg is more complex than what it’s replacing from a UX standpoint. That’s only the case if you have heretofore been creating simple blog posts and you’re now wanting to create more complex ones, and that isn’t a fair comparison. If you’re always doing simple, Gutenberg provides a simpler UI. If you’re always doing complex, Gutenberg provides an abstraction from the HTML. In either case, it’s better for people who don’t want to get into the HTML.
  • It’s not a winning strategy to avoid change simply because of the mere potentiality of it causing problems tomorrow. First you have to quantify the likelihood of those problems. What’s the probability that embracing Gutenberg today is going to cause debt tomorrow? In order to answer this, we have to look at Pearson’s concerns:
    • Using Gutenberg locks you into a complex, opinionated system. That’s fair. But we buy into new things all the time. I don’t have an elegant exit strategy if I ever want to move away from Apple’s walled garden. I’m ok with that. I don’t view that as debt. It’s a lifestyle choice. Sometimes the best things in life are strongly opinionated and locked down.
    • Pearson has high confidence that projects that rely on Gutenberg are going to break in a few years. But WordPress is here to stay, and Gutenberg is here to stay. Do I think individual implementations will get top-heavy? Sure they will. But that’s true of any technology. Your mileage with Gutenberg will be defined by what you make of it. You can ruin an ice cream cone by insisting on having 5 scoops of ice cream. Does that mean that the ice cream cone concept is fundamentally flawed?
    • “But Gutenberg makes your site load slower.” If that’s really true, I have confidence that the community will address it. In reality, I have a feeling that Pearson’s threshold of “unacceptably slow” is simply lower than the community average, and that Gutenberg is “good enough” in speed for most people and situations.1 And regardless, the way most people use WordPress is already slow. The low hanging fruit to making a WordPress site load faster is by reducing your JS and CSS footprint, and changing how those resources are loaded.
  • Clearly, Chris knows a lot of people who are not reaching their goals with WordPress, and Gutenberg is providing confirmation bias that the technology is the problem. I’m skeptical here. It makes a nice scapegoat, but technology is only one piece of the puzzle. Human factors are the primary make-or-break. You can have the greatest site in the world, but if you don’t have eyeballs, it means nothing. You can have the greatest technology in the world and have eyeballs, but if you don’t understand human psychology and marketing and you don’t have a stellar value proposition, it means nothing. The meta involved in how your website is served up is important, but it’s a detail in the big picture. It’s the process, not the product.
  • WordPress is moving where the puck is headed. Medium has made WordPress’ pre-Gutenberg editor interface look arcane and cumbersome. It’s time to move forward. This is what that looks like. Welcome to the future.

This saga reminds me a bit of the recent fallout some people had with Twitter. There was a small vocal minority that deleted all their tweets, and went to their blogs to whine about it. And there will be a similar minority of site owners that fork WordPress or switch to Ghost / Jekyll / Hugo / whatever. The terrier barks, but the semi keeps moving. Whether you view this as “the herd running off the cliff” or “that terrier is getting on my nerves, I wish I could run over it,” depends on whether you’re in the semi or not. Both viewpoints have merit, and only time will tell who is directionally more accurate. Either Pearson’s Periscope won’t age well, or it’ll be an uncanny prediction, a “told you so” moment. We’ll see.


  1. And after all, we wouldn’t want websites to get so fast that Google AMP is no longer useful, would we? 😜 ↩︎

Inspecting Elements in Chrome that Only Appear Via JavaScript Event Listeners  

Some DOM elements appear on hover because in CSS they’re targeted with a :hover entry. In those cases, you can use the attribute modifier in Chrome to synthesize :hover, which lets you inspect the element in its hovered state without having to physically modify the document.

In many other cases though, DOM elements appear on hover via a JS onmouseover event or similar, which hoverIntent (or a similar in-house solution) picks up and programmatically applies a CSS class or series of classes. In this scenario, freezing the DOM to a state where you can access the modal / popup / tooltip / whatever is harder. That’s where this Stack Overflow solution comes in. I wish I’d known about this years ago.

Slack’s Design Flaw

For as long as I can remember, I’ve hit the “+” next to “Channels” in Slack’s sidebar when I’m wanting to view a preexisting channel. This doesn’t result in what I’m expecting though. Instead, I’m taken to a screen where I can create a new channel. To get to what I’m after, I have to click the “Channels” text. This happens to me every single time and it’s frustrating. It’s also inconsistent with the “Direct Messages” and its corresponding “+” button, because both of those take you to the same screen, where you can chat with preexisting users.1

At a company meet-up last year, I noticed that my coworkers were making this same mistake. We’d been using Slack as our primary communication tool for more than a year at the time, and we were still making this mistake. It wasn’t just me. The UI was genuinely confusing and needed improvement. We kept going to the screen for creating a new Slack room when all we wanted to do was join a preexisting room.

I sent Slack a support ticket about this 10 months ago and got a “We’ll pass along this feedback!” kind of response. Nothing material has been done about it. Today I’m still making this mistake. For the most part, Slack is a very well designed application for an HTML product.2 But this one thing desperately needs improvement. Since you rarely want to create a channel, I’d recommend burying its button somewhere in the dropdown that appears in the top left corner of the screen. The “+” icon next to “Channels” is prime real estate and should let you choose a preexisting channel.

If Slack doubts I’m right, I recommend it Amplitude-log how many times people hit the “+” button and create a channel, versus how many people hit the “+” button, hit Esc, and click on “Channels.” I’m willing to wager that 98% of the time, people click the “+” and don’t mean to, because it doesn’t do what they think it does.


  1. Obviously these two sections — “Channels” and “Direct Messages” — aren’t quite the same thing. You can’t create a new user in the way that you can create a new channel. But having the same UI element perform different things when clicked based on where it’s at in a related section is a design flaw. ↩︎
  2. The “for an HTML product” here is key. More on that later. ↩︎

Working Remote, Away from Home

When “working remote” means “working from home,” we deprive ourselves of life’s rich texture. Most people weren’t made to do the bulk of their computer-based jobs in the same building that they sleep. A daily commute is a mandatory ritual for most of us to retain our sanity and to experience the harmony and fullness of life. I’m not a fan of celebrating the number of miles saved by working in our houses. Just because we don’t have to travel somewhere to do our work doesn’t mean we shouldn’t.

It’s great that more jobs are going from in-office to remote. It’s not great when we decide that this means we will work from our houses 5 days per week. I’m saying this as someone who did exactly that for years. I’m now working out of a coworking space, and I’m never going back.

Having spent the better part of this year with a 25-minute drive separating my pillow and my desk, here’s a list of things I’ve learned in retrospect:

  • Before, I was experiencing a common melancholy in my home office that resulted from working in isolation. I was starting to ask myself questions like, “Is any of this real?” People who work around others are immune to this. As someone told me a couple months ago, software developers are usually introverts; introverts need to be forced out of their hermit comfort zone, and working from home does the opposite. It compounds the problem.1
  • The boundaries of work and domestic life were blurred and under-regulated. There was never an official, consistent time I started and ended my work each day.
  • Similarly, it was difficult to keep my sleep schedule consistent year-round. Ritual and routine are very important. Almost all high-functioning people have lots of this in their lives.
  • I had convinced myself that because I had fewer human-factor distractions, I was able to get more focused work done. I’ve since learned that this was offset by my freedom to go down useless rabbit trails. It resulted in a zero-sum game. Getting held up in the break room for 5-10 minutes will save you 45 minutes of programming when you get back to your desk. It’s worth having healthy doses of human distractions. Especially if a big part of your job is problem-solving and creative thinking.
  • I’d formed my outlook on working from home by influential thought leaders such as Mullenweg and DHH. But there’s a difference in experience between leaders who work from home and their helpers. Leaders travel a lot, and they talk a lot. They have positive feelings about working from home, because they experience it from a leadership’s lifestyle. Just because Mullenweg and DHH think working from home is great for them doesn’t mean it’s great for you or me.
  • I thought I had more free time since I didn’t have a commute. But I was also upset that I still couldn’t find discretionary reading time. The commute solved this frustration, thanks to a monthly Audible subscription. I’m now using the commute to learn about new things. I’ve listened to more high-quality books this year than I’ve read in any other post-college year. I’ve learned to embrace the commute. It’s helping me implement better habits. And it’s allowing me to let go of my day’s work before coming home to my family. There’s nothing wasted about that drive. I need it.

Granted, I could force myself to begin my workday around 8 or 9 if I worked from home. I could force myself to minimize distraction and be done (really, actually done) by 5 or 6. I could force myself to spend an hour per day reading a good book. But who does that?

You want a system in place that brings the lifestyle you’re after with the least amount of effort (not because you’re lazy, but because you want to save your effort for other things). You achieve a healthier, fuller lifestyle with less effort by introducing a commute.

If you have a remote job, be thankful for it. Remote is great! Now convert your home office into a guest bedroom, and find a coworking space.


  1. The gentleman who told me this commutes voluntarily from Atlanta, Georgia to work in physical proximity to his constituents. He could work from home if he wished, but he puts a high dollar value on not doing so. ↩︎

Steven Hackett’s 2018 Macbook Pro Keyboard Is Already Having Problems  

I bought my 2018 MacBook Pro the first day it was available in retail stores — July 13. My keyboard is working great five weeks later.1 But not Steven’s. In just 23 days he’s having issues. As his URL states, “not great, Tim.”


  1. Including a lot of lunches that have been in uncomfortably close proximity. ↩︎

Too Bigly

In many activities of life, we try to make things too bigly. Here are some examples.

  • Beginner runners have strides that are too wide. Shorter strides enable better breathing and less muscle strain.
  • Beginner cyclists have cadences that are too slow. It’s easier to climb a hill with lots of smaller pedal strokes.
  • Beginner house painters make brush strokes go too far. Dipping a brush more often makes the brush last longer and yields better coats.
  • Beginner dieticians eat two large meals per day instead of continuous smaller meals. Smaller meals do a better job with metabolism.
  • Beginner investors invest too much in a few stocks, instead of investing a little bit in a lot of stocks. Aggregate investing is safer and smarter.
  • Beginner software developers put too much code in functions. Smaller functions make code easier to understand.
  • Beginner writers put too many words and ideas in sentences. Shorter sentences are easier to read.

You can probably add several more examples from your experience.

Jack Dorsey on the Sean Hannity Show  

I don’t know normally listen to Talk Radio but this is worth a listen. Taking a purist stance on the First Amendment is something I can connect with, and both Hannity and Dorsey lean in this direction.

Steve Jobs on the Importance of Strong Leadership  

I’m listening to the linked Audible recording of Walter Isaacson’s Steve Jobs. The book is more polished and better-rounded than Becoming Steve Jobs, which was little more than a thinly-surfaced composite recap of news articles. I highly recommend re-visiting Isaacson’s canonical biography. This part struck me though, towards the end:

When our discussion turned to the sorry state of the economy and politics, he offered a few sharp opinions about the lack of strong leadership around the world. “I’m disappointed in Obama,” he said. “He’s having trouble leading because he’s reluctant to offend people or piss them off.” He caught what I was thinking and assented with a little smile, “Yes, that’s not a problem I ever had.”

How to Create a Bulk Filter in Gmail for a List of Email Addresses

Let’s say you’re on an email thread that you no longer want to be on, but you’re too nice to communicate that. You just don’t want to get any emails from that group any more. Thanks to Gmail filters, there’s a way you can programmatically achieve this without a bunch of repetitious elbow grease.1 First, create a JavaScript file and open VSCode:

cd ~/Desktop
touch file.js
code file.js

Next, get your list of email addresses from which you no longer wish to receive, and format them in a way that JavaScript can understand. Using some simple search and replace in your text editor, it shouldn’t be too hard. The goal is for you to get it in an array format:

const addresses = ["Example User 1 <[email protected]>", "Example User 1 <[email protected]>"];

Next, put this into your newly created file.js, with that formatted version at the top:

const addresses = ["Example User 1 <[email protected]>", "Example User 1 <[email protected]>"];

let startTime = new Date().getTime();
const filters = addresses.map(address => {
  const start = address.indexOf('<') + 1;

  return {
    time: startTime++,
    email: address.substr(start, address.length - start - 1)
  }
});

const template = `<?xml version='1.0' encoding='UTF-8'?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:apps='http://schemas.google.com/apps/2006'>
<title>Mail Filters</title>
<id>tag:mail.google.com,2008:filters:${ filters.map( el => el.time ).join(',') }</id>
<updated>2018-08-04T14:41:59Z</updated>
<author>
  <name>[Your name]</name>
  <email>[Your email]</email>
</author>
${ filters.reduce((acc, el) => `${acc}
<entry>
<category term='filter'></category>
<title>Mail Filter</title>
<id>tag:mail.google.com,2008:filter:${el.time}</id>
<updated>2018-08-04T14:41:59Z</updated>
<content></content>
<apps:property name='from' value='${el.email}'/>
<apps:property name='shouldTrash' value='true'/>
<apps:property name='sizeOperator' value='s_sl'/>
<apps:property name='sizeUnit' value='s_smb'/>
</entry>`, '') }
</feed>`;

template;

Replace the [Your name] and the [Your email] with your name and email address.

Now copy the contents of this file to your clipboard:

pbcopy < file.js

Then head over to Chrome, pop open the JavaScript console, and paste your clipboard. Copy the string output stored in the template variable, and paste it into a new file:

pbpaste > import.xml 

Now go into Gmail > Settings > Filters and Blocked Addresses, scroll to the bottom, and select “Import filters.” Choose import.xml. Complete the steps, and you’re done.

I just did this successfully with a list of 75 email addresses and it felt amazing.


  1. Gmail’s interface allows you to create filters directly, but there’s a severe character limit when you’re assembling the filter. If you have a list of more than a few email addresses that you’re wishing to filter, you’re out of luck. That’s where this tutorial comes in. ↩︎

Google’s Blatantly Misleading Chromebook Ad  

Since macOS Yosemite debuted in fall 2014, buttons on dialogs haven’t been as skeumorphic as the overwhelming majority of them are in this ad. Google had to stitch together an antequiated collection of imagery in order to depict a false narrative. It’s a farce to pretend that a regular part of using macOS includes these dialogs. They’re infrequent, and when they appear, they’re important. Moreover, for those who don’t need a full-blown desktop operating system — which I unequivocally do need — there’s nothing you can do on a Chromebook that you can’t do on an iPad, with a vastly superior user experience. This ad is garbage.

Will Apple Let You Swap Your Recently-Bought 2017 MacBook Pro for a 2018 One?  

Ben Lovejoy, writing for 9to5Mac:

Apple Store staff tell us that they have fairly broad discretion to do what they believe to be the right thing for the customer. When they want to swap out a machine that is just a little way outside the 14-day window, we’re told that managers tend to ok it.

This past week, I took advantage of the 14-day “no questions asked” policy, but I have two anecdotal stories to show how much discretion Apple Store staff has in addition to that.

On September 4, 2015, I bought a baseline 13” retina MacBook Pro, to replace a 3-year-old machine. Then the following month I started a new job that required a more powerful machine. I took my MBP to the Apple Store on October 8 — more than 30 days after my purchase — and received a full store credit to go towards a retina 15” model. “We just want you to have the computer you need to do your job,” the staff told me.

Then on February 4, 2018, I went to the Apple Store with a Magic Keyboard whose space bar had quit working reliably. I’d purchased it on December 1, 2015. The genius looked at it, went to the shelf, found a matching keyboard, took the plastic off the box, removed the keyboard, and handed it to me at no charge. Again, the explanation was the same — “I just want you to be able to get back to work.” There was no receipt involved. I simply walked in with a broken keyboard and walked out with a new working one.

Apple charges a premium for its products but the service you get with those products is remarkable.

True Tone on External Displays  

Apple:

The True Tone technology in MacBook Pro (2018) uses advanced multichannel sensors to adjust the color and intensity of your display and Touch Bar to match the ambient light so that images appear more natural.

Then the good part:

True Tone can also adjust these external displays when they’re connected to your MacBook Pro:

I can confirm that this is working as advertised on the new 2018 MacBook Pro and the discontinued Apple Thunderbolt Display. Toggling “True Tone” in System Preferences makes a noticeable difference on both the laptop screen and the external display. Heretofore I had been under the impression that the screen itself had to have additional properties in it to support True Tone. Turns out this isn’t the case. The days of needing to use Night Mode are officially gone.

If you’re using an external display and you’re using something other than one of these three, it’s time to get one of these three. They’re the only three external monitors worth having.1


  1. Along with a black keyboard with no numeric pad, I’m waiting for Apple to come out with its own external 5K monitor. Who wants to have to look at that “LG” logo all day, anyway? Gross. I did that with Dell for 4 months and I’m never doing it again. ↩︎

Joël Perras on Boolean Expressions  

I have a lot of respect for Joël, and wholeheartedly agree that flipping inequalities to remove a negation is a win and that boolean expressions that can be simplified should be simplified (the latter two points of his piece). With that said, I quibble with how helpful it is to reduce the number of negated expressions. Joël offers this example, whilst recommending the version on the left side:

not (a and b) == (not a or not b)

When we talk about the readability of the code, one gut check is to see how easy it is to audibly explain the algorithm to someone else. In everyday speak, if we’re trying to communicate the algorithm above, we’re going to use the version on the right. People are very comfortable communicating that way, even non-programmers talking about everyday decision making. It takes substantially more words to communicate the algorithm in terms of the left version, because first you have to create a mental variable of the result of the parentheses. Even as a developer, the left version is a mild brainteaser for me — it requires more cognitive overhead — whilst the right version is easier to grok.1


  1. My verdict notwithstanding, one caveat comes to mind. I’ve heard of situations, particularly in database queries, where ANDing something has proven substantially less expensive than ORing something. There’s definitely a time and place to flip these things around, but I wouldn’t do it for readability’s sake. In my mind it hurts readability. ↩︎

Apple Updates Its MacBook Pro Lineup, to the Chagrin of Those Who Already Bought a MacBook Pro Earlier This Week  

I’m typing this on a 15” 2017 MacBook Pro that I purchased this Monday. Tomorrow I’m taking it to the Apple Store for a full refund in exchange for the model that was introduced today. Life is stranger than fiction. It’s a black box trying to predict when Apple is going to upgrade its MacBook Pro lineup. I’d given up on seeing anything new coming out this year when WWDC came and went with no news on this front. And then, wham.

This lineup refresh took Apple employees as much by surprise. The specialist I spoke with on the phone today walked into work this morning and heard the news for the first time. The new laptops are available for order online today and they’re available for purchase at retail stores tomorrow.