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  


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.

Three Nifty, Elegant Tips in JavaScript

Let’s start with the first one.

Imagine that you have a user object and you want to print its name. Such a method might look like this:

const getName = (user) => {
  return `${user.firstName} ${user.lastName}`;

We frequently don’t know if both fields contain data, however. In some backwards systems, the first name might be empty and the last name might be a company name.1 To get around this, you might see some verbose logic such as this:

 * Too much codez...
const getName = (user) => {
  let output = '';
  if (user.firstName) {
    output = user.firstName;
  if (user.lastName) {
    if (user.firstName) {
      output += ' ';
    output = user.lastName;

  return output;

A niftier way to handle this is to just assume that both fields do contain data and then trim any whitespace. The function below achieves the exact same thing as the one above, albeit more elegantly:

 * Hire this guy!
const getName = (user) => 
  `${user.firstName} ${user.lastName}`.trim();

Now for the second tip.

Let’s say you’re generating timestamps, such as:

  • 8:04 AM
  • 5:23 PM
  • etc

When you’re piecing this together from a JavaScript Date object, you use something like the Date.getMinutes() property. Often you’ll see code that looks something like this:

 * Whaaa
const getMinutes = (date) => {
  const minutes = date.getMinutes();
  let output = minutes;
  if (minutes < 10) {
      output = `0${output}`;
  return output;

The code is trying to make sure that there are always two digits for the seconds. There’s a groovier way to do this though:

 * Lit!
const getMinutes(date) => 

Lastly the third tip.

Often you see code that looks something like this:

 * We do this all the time, sigh
if (user.location === 'Chicago' || 
  user.location === 'New York' ||
  user.location === 'San Francisco') {

Here’s a cleaner way:

 * Array literals for the win
if (['Chicago', 'New York', 'San Francisco']
  .indexOf(user.location) >= 0) {

These tips have use cases outside these particular examples and they can easily transfer to other programming languages.

  1. This sort of blasphemy occurs when you have a lazy database designer who, in their infinite wisdom, chooses to use a single cell-starved table for both personal accounts and business accounts. Such design is pure evil and ought never to be imagined. ↩︎

WP Engine Acquires StudioPress  

Brian Gardner:

It is my pleasure to announce WP Engine has acquired StudioPress.

Our future has never been brighter than it is today, and the road ahead of us is so much longer than the road behind. It’s a new journey that I cannot wait to continue with you.

Over the last eleven years, we have changed the WordPress landscape—from creating a commercial market to building the most popular theme framework. While we were able to do that as a bootstrapped company, the vision I have for StudioPress requires more.

If you’re using WordPress, you need a reason to not be using StudioPress and WP Engine. They’re the emergent winners. This acquisition wasn’t expected but I’m excited to see them come together. I’ve used both of these technologies for years and wish all parties involved the very best going forward.

Taking Risks  

Casey Liss, earlier this month:

This past Tuesday, I woke up as I would any other Tuesday. I got ready for work like any other Tuesday. I went to work, met with my boss, and spoke two words that will dramatically change my life.

“I’m resigning.”


In my life, I’ve never been one to take risks. However, when I do, I’ve always been rewarded, regardless of the eventual outcome. The well-traveled road brings less surprise, but is paved with the regret of poorly trodden forks not taken.

The well-traveled road is safe and pays well, but every entrepreneur eventually comes to regret it. I wish Casey the very best in his new chapter.

Say the Hard Thing  

Michael Lopp:

The majority of people-related disasters I’ve created originate with my choice to not say the hard thing. On my short list of critical leadership skills, the ability to “say the hard thing” is right after “delegate until it hurts.”

If you’ve ever worked on a team or ever plan to work on a team, this whole piece is mandatory reading. Michael’s experience and insight here are invaluable.

React Still More Popular Than Vue  

Great analysis by Kevin Ball, who shows that just because a repo has more stars than another doesn’t mean it’s actually more popular. See also the comments, where the validity of NPM installs as a metric is itself challenged. It definitely makes sense that React is still more popular than Vue. It is older and has had a longer chance to become mainstream. Five years from now though, we may be seeing a very different story. Time will tell who the real winner is.

Track Your Average Interval Pace With This Groovy UI  

For a while now I’ve been calculating my average interval running paces by hand. It’s been tedious, and today I needed an excuse to spend some quality time writing Vue. So I updated the little app that’s currently running at Distance.MartynChamberlin.com to include this feature. No more having to compute it all by hand. Here’s a screenshot of what it looks like for one of my recent runs on Strava.1 The UI needs some more refinement but it gets the job done for a 1.0 version.

  1. Admittedly this is a somewhat bizarre example because my lap distance turned out to be 2.00 miles rounded to the hundredth and the pace turned out to be 6:00/mi rounded to the second. What are the chances of deriving such perfect numbers if you tried? ↩︎

Vue Passes React in Popularity  

Dan Abramov, author of Redux, the de facto state manager for React:

Congratulations to @vuejs for surpassing React’s star count on GitHub! Seems like I almost captured a historical moment by accident.

The typical developer on the street thinks that the two winners for frontend web libraries are Angular and React. I’ve been stressing over and over again that there are actually three winners: Angular, React, and Vue. And that Vue, which is the newest of the three, took the best ideas from React and Angular and that it’s actually the best of the three. I’ve spent hundreds of hours in all of these frameworks — in the case of Angular and Vue, thousands of hours. I can say unequivocally that Vue has the lowest learning curve and simplest API, has significantly fewest gotchas, and enables the fastest development cycle, all the while sacrificing nothing in performance. And now I can finally say that in a mathematical, quantitative metric, Vue has surpassed React in popularity. React is officially in the rear view mirror. If you’re wanting to start a new project or migrate a legacy project to one of these new frameworks, choose Vue. By all means, play with the others so you’ll know what you’re saying no to, but come back to Vue. There’s a reason it’s the most starred of the three projects on GitHub.1

  1. Also, if you’re not on the JavaScript Weekly newsletter, you really need to be. It’s the moral equivalent of Drudge Report for JavaScript. ↩︎

Called It  

Ewan Spence, writing at Forbes:

Apple continues to use the proprietary lightning connector on its iOS-powered devices, but that could be set to change. According to a number of suppliers, Cupertino is looking to move the iPhone and iPad lines over to USB-C, just as it has with the MacBook family of laptops.

If this is true, then I was a year premature in what I still consider to be a valid argument. This contemplation makes me unlawfully gleeful because it means I’m going to be right and someone else is going to be very wrong.

Strava Brings Kudos to Other Networks  


Our thumbs give kudos for effort and activity, not political rants or latte art. Kudos are how millions of Strava athletes share support for each other and spread positivity in our community, and now we’re spreading it even further.

I’m delighted to see Strava mock political rants and latte art for their uselessness. Strava is a social network for people who are too fit, too busy exercising, to whine and doodle. Strava people ship.

Apple Brings Apple Maps to the Web  

Yuge. Some of the stuff in the opening keynote was of less weight than this; it should’ve gotten a mention. Memoji, for instance. Nobody’s going to use that. Lots of people are going to use this.

The Verge: “Microsoft Has Reportedly Acquired GitHub”  

If true, then this is mind-blowing.1 If you’re a developer working on web technologies, it’s difficult to imagine what Apple could announce tomorrow at WWDC that in the long run would be bigger news than this.

Update: the acquisition is confirmed.

  1. It also makes the top-rated answer on Quora for this question look really silly. Anyone who actually thinks that Microsoft’s Visual Studio Team Services is better than GitHub is laughably insane. I’ve used them both extensively and there’s no comparison. The question at this point is this — will TFS and GitHub continue to exist alongside each other? I’d love to see TFS get cannibalized by GitHub. ↩︎

Back to the Mac  

This afternoon I built a mini web page that I can turn to throughout the workday in solace.

Here’s the thing: I get it. Windows has better enterprise software, and it makes sense that corporate America prefers — nay, mandates — the use of Windows software over Apple software.

But it burdens my heart that WWDC is this upcoming Monday and the only way I’ll be able to stream it from my skyscraper desk is via my iPhone, since Apple understandably restricts playback to its own devices. My Dell Latitude 7480 won’t be able to stream it. [Update: turns out this isn’t true. I was able to stream it from Edge on my Windows machine just fine. Apple’s restriction isn’t an arbitrary choice but rather having to do with whether your browser can support its video streaming requirements. Makes sense.] There are a finite number of months that one can go on in this condition. Using Windows for frontend web development is a losing strategy if you’re used to the finesse and vast superiority of macOS. Again, I quote Steve Jobs:

The problem with Microsoft is they just have no taste. They have absolutely no taste, and what that means is, and I don’t mean that in a small way, I mean that in a big way.

Visual Studio Live Share  

Visual Studio Live Share, announced as public beta three weeks and one day ago, is a game changer that is hard to overestimate. This is much bigger news than when GitHub announced Teletype for Atom in November 2017. Both tools allow one host and multiple guests to view and collaborate on files at the same time, but Visual Studio Live Share goes beyond that by allowing you to also share your computer’s local servers and port numbers — any of your choosing. For example, if you have a NodeJS server running on localhost:9000, or a Ruby on Rails server running on localhost:8080, or a Hugo server running on localhost:1313, you can share any of those with another developer on another network and another operating system. All they have to do is click a link that you provide, fire up a browser to the right port on localhost, and they’ll see exactly what you see on your own computer. Zero setup or configuration on their part required. It’s kind of like turning your computer into a server, except there’s zero hassle and full security. All the host and guest(s) need is VSCode installed, and that’s a fast free download. It’s been a while since I’ve been this excited about something in tech. I wish I’d had this in college. It would’ve been immensely useful.

The Definition of Insanity Is Misleading in Computer Science

The definition of insanity is doing the same thing over and over again and expecting difference results.”

Often this is quoted to mock someone who is trying to achieve something on a computer and duplicating the exact steps multiple times with the same unsuccessful output. But take this example:

  let i = 0;
  const buttonWasClicked = () => {
    if (i === 3) {
      console.log('third time lucky');

  Button of Insanity

Here we see that the console only gets activity after the third click. While this example is overtly contrived, the principle behind it (i.e. a UI that responds differently depending on a state that itself may or may not be transparent to the end user) is extremely common in software. To develop this out a bit more, there are three kinds of user interfaces in computers:

  1. UIs that have zero bugs or flaws in them. This is Unicorn territory. They almost don’t exist, and when they do, they’re extremely basic UIs that are of little value.
  2. UIs that have bugs that are manifest 100% of the time. This is also pretty rare in software that’s regularly used because the bugs are incredibly obvious and tend to get fixed. Which leads us to the most common type of UIs:
  3. UIs that have bugs that only occur some of the time. One way to think of this is that component B has a bug that in and of itself is never manifest, but becomes manifest if component A gets into a certain state. This category can be sub-divided into two smaller sections.
    1. Sometimes it is the case that component A is by default in a state that causes the bug in component B to be manifest. This results in the bug usually being present, unless you first fix the state of component A. In terms of the above example, think of the <script> as component A and the <button> as component B. The latter has no bugs in it - it correctly wires to a function on the click event. Rather, the bug resides in component A: it only performs an action on the third click (i.e. it has to be in a certain state to work), whereas the user expects the button to perform the action on every click. The button is unreliable, but not completely broken. This is the scenario in which the user gets mocked for being insane. It’s ambiguous to the user if the fix to component A is circumstantial or requires a specific change in their user behavior, but either way, they’re innately aware that component B really will work eventually, they just need to figure out how. This isn’t insanity; it’s working with a UI that was built by a fallible software developer. This is the normal life of a computer user. We’ve all done it many times, and we’ll continue to do it as long as there are computers.
    2. Other times it is the case that component A is by default in a good state, which means component B works most of the time. When your job is to perform Quality Assurance and you get the occasional ticket from a user complaining that something isn’t working, and you test it and it’s working fine, that is caused by this situation. In this case, your job is to test the same thing over and over again with the hope of figuring out what the secret is to reliably breaking it.

In the code example above, you didn’t have to change hardware devices to tease out the working state. You didn’t have to change networks, or get past a blip in the current network. You didn’t have to wait through an outage in a outbound web service. You didn’t have to log out of user A and log in as user B. You didn’t have to switch from one browser to another. Often, you have to do one or more of these things to tease an issue out and get to the bottom of it, but here you didn’t, and often in real life you don’t. You just have to do the exact same thing (from your perspective, though since we know the code, it’s not the exact same thing) more than once.

In computer science there is no such thing as truly trying the exact same thing over and over again, even when, from the perspective of someone looking over your shoulder, you seemingly are. Hardware and software are never in the same state. They are constantly in flux. When a bug is only sometimes present, you may be assured that there is some variance somewhere, and it is your job to find it. It’s time to quit mocking this as insanity; it is what computer scientists do for a living.

The Gangsta Guide to Fixing the Position & Spacing of Footnote Backlinks in Hugo

Currently Hugo has two problems with its backlinks. First, take this multi-paragraph footnote in Markdown:

[^1-2018-05-26]: Some text

    > A blockquote

    Some more text

That renders with the backlink (↩︎) in a dedicated paragraph. It should instead be on the same line as “Some more text.” This is a burden in the land that affects more footnote systems than just Hugo’s, for the record.

The second problem is one that I universally fixed in Jekyll but that persists in Hugo, which is this: the backlink is not connected to the previous element via &nbsp; — there’s rather a pure whitespace. This results in the backlink sometimes appearing on a dedicated line in isolation, due to text-wrapping. Instead, if the backlink must text-wrap to the next line, it should should always take its previous word along with it for improved continuity.

Rather than monkey with Hugo core - I don’t have time for that right now, unfortunately - the solution to both of these issues can be derived with this pure ES6 JavaScript.

const fixFootnotes = () => {
  const footnotes = [...document.getElementsByClassName('footnote-return')];
  footnotes.forEach(footnote => {
    const previousContent = footnote.previousSibling.textContent;
    if (previousContent === '\n ') {
      // Hugo has needlessly created a dedicated DOM node for the backlink, due 
      // likely to a multi-paragraph footnote. The solution is to move the backlink 
      // inline with the last node that actually contains footnote content.
      const whitespace = document.createTextNode("\u00A0");
      [whitespace, footnote].forEach(element =>
    } else {
      const lastTwoChars = previousContent.substr(previousContent.length - 2, previousContent.length);
      if (lastTwoChars === '\n ') {
        // Replace the whitespace prior to backlink with &nbsp; so the backlink is
        // never a widow.
        footnote.previousSibling.textContent = `${previousContent.substr(0, previousContent.length - 2)}\u00A0`;

Sure, it’s coding pretty close to the metal, but it works fantastically. I’m now using this code on Drinking Caffeine, and I invite you to be the judge on its superiority over the default behavior of backlinks in Hugo.1

  1. Once you have a grasp of how to do this level of DOM manipulation with JavaScript, an entire world of control opens up for you. It’s a good feeling. ↩︎

Many Reputable Companies Are No Longer Serving the EU Because of GDPR  

SJW dylanbeattie, on Twitter:

Company says: “Due to the GDPR, we are no longer able to offer our service to customers in the European Union.”

I hear: “You are not a customer. You never were. You are PRODUCT. Now that your privacy is protected by law, you are no longer worth anything to us. Go away.”

What dylanbeattie doesn’t seem to be aware of is that it’s not just the small minority of truly shady businesses that are forced to make changes to get complaint. It’s anyone collecting user data from EU citizens. By its very nature, the World Wide Web is accessible everywhere, including in the EU, which means any website collecting data is by default subject to GDPR’s overreaching jurisdiction. In the case of some very reputable businesses, the hassle of getting compliant with this burdensome mandate is simply not worth the effort. Many web-based businesses are pulling out of serving the EU because it’s not cost effective any more. From the Drip blog:

For some businesses, the cost of becoming GDPR-compliant is higher than not doing business with EU citizens to begin with, especially if you’re not purposefully courting them in the first place.

The soyboys in Clown World haven’t figured it out yet, but GDPR was a mistake.

Chrome Will Flag All Non-HTTPS Sites Starting in July  

From the Chrome Security blog, back on February 8:

For the past several years, we’ve moved toward a more secure web by strongly advocating that sites adopt HTTPS encryption. And within the last year, we’ve also helped users understand that HTTP sites are not secure by gradually marking a larger subset of HTTP pages as “not secure”. Beginning in July 2018 with the release of Chrome 68, Chrome will mark all HTTP sites as “not secure”.

A few thoughts on this.

  • First, a gentle reminder that calling these certificates SSL certificates is no longer using accurate nomenclature, despite some people still clinging onto the term.1 The correct term is TLS. Here’s a good article that explains, if you’re unfamiliar.
  • It’s amusing to me that Google is still using Blogger as its platform for content.
  • I’d love to see a future version of Chrome treat non-mobile-friendly sites with a similar harsh treatment.2
  • Lastly, if you have a site that doesn’t yet adhere to HTTPS, you can get with the program for free with Cloudflare. It’s what Drinking Caffeine has been using for a while now, and it rocks.

  1. GoDaddy, for instance:

    Get a little green lock for your site with a trusted SSL certificate. It shows your visitors that their data is safe, makes Google happy and speeds up load time on HTTP/2. It’s a win-win-win.


  2. When I run a Google Mobile-Friendly Test on a certain obnoxiously curmudgeon site I get this:

    Page is not mobile friendly
    This page can be difficult to use on a mobile device

    Not groovy, JG.


Connecting a Dell Latitude 7480 Laptop to an Apple Thunderbolt Display  

In case you’re ever needing to connect a Dell Latitude 7480 laptop to a discontinued Apple Thunderbolt Display, rest assured it’s possible. The Dell has a Thunderbolt 3 port, whilst the Apple Thunderbolt Display has a Thunderbolt 2 cable. The solution is to buy a $49 adapter. I picked one up today at Best Buy and my Thunderbolt Display works as expected, just as if you were connecting it to a MacBook Pro. Good times.

JavaScript Trampolines  

This is a brilliant way to write recursive functions that are immune to the concerns of stack overflows. If you write JavaScript at all, I highly recommend pouring over this until you understand exactly what’s going on.