This is Anti-pattern—thoughts on programming and whatnot by Brandon Weiss.

Knot Right

I learned to tie my shoelaces when I was about six years old. It wasn’t until 22 years later that I discovered I’d been tying them wrong.

When you tie your shoelaces, do the ends neatly lay flat across your shoes like you expect? Or does the knot sort of turn, causing the ends to awkwardly stick up and lay more parallel to your shoes? If it’s the latter, congratulations, you’ve been tying them wrong too.

The knot for your shoelaces is called… the shoelace knot. It’s made in two stages, each of which is another type of knot. The first stage is a half-hitch. The second stage is another half-hitch, but with the loops tucked into it, which is called a double-slip knot.

When you tie a half-hitch, you can choose for the left lace to go over the right lace, or for the right lace to go over the left lace—it doesn’t matter.

However, when you tie a second half-hitch over the first, which lace is on top does matter. It might seem like a small difference but it’s important enough that each way has its own distinct name.

If you put the same lace on top in both half-hitch knots you will tie a granny knot. The granny knot causes the ends of the laces to stick out at odd angles and tends to loosen and come untied on its own.

If in the second half-hitch knot you switch which lace is on top from the first half-hitch knot you will tie a reef knot. The reef knot lays flat, stays tight, and resists coming untied.

We should tie a reef knot but people tie whatever feels natural, which could be its inferior version, the granny knot.

It felt a little uncomfortable at first, but it only took a week or two of tying my laces with intention to make it feel natural, and now I tie a reef knot every time.

Migrating to a New Mac for Programmers

Apple creates great experiences, but migrating to a new computer tends to not be one of them. There are several different ways of migrating, it’s not clear what the relative differences are between them, and when it’s taking a lot longer than you expect it’s not clear why. The seemingly never-ending migration hits programmers especially hard.

After running into this problem yet again recently, I did some research and experimented until I figured out what was wrong and how to fix it. Here’s what I learned.

Target Disk Mode

You may have gotten used to booting your old computer into Target Disk Mode and then having the new computer migrate the contents of the old hard drive over during setup. Don’t do that! I don’t exactly understand why, but it seems that Target Disk Mode can’t transfer at Thunderbolt speeds; it just degrades to regular USB transfer speed.

Migration Assistant

Instead of Target Disk Mode use Migration Assistant. Migration Assistant is an application you run on your old computer. It will restart into a special mode that is complementary to the setup mode your new computer boots into and will allow your new computer to transfer files from your old computer at Thunderbolt speeds.

Thunderbolt cable

Make sure you have a Thunderbolt cable. The situation with USB-C and Thunderbolt is confusing. The ports look identical and the cables almost look identical. The charging cable that comes with your Mac is not a Thunderbolt cable. You’ll know if you have a Thunderbolt cable because it will have a Thunderbolt symbol on at least one end of the cable.

The transfer can also be done over WiFi for convenience if you don’t have much data to migrate, so Migration Assistant will ask you to connect to your WiFi network, but it’s not very clear why it’s asking. It’s extremely easy to misunderstand what is happening and connect to your WiFi network even though you have no intention of migrating your data that way. If you then also mistakenly use a USB-C cable instead of a Thunderbolt cable, you can wind up starting the transfer thinking it’s using Thunderbolt when it’s actually using WiFi.

Thunderbolt ports

Not all USB-C ports on all MacBooks are Thunderbolt ports. I believe the 2016 and 2017 13-inch MacBook Pros without Touch Bar only support full-speed data transfer on the left two ports. You can’t use the right two ports. The 2016 and 2017 13-inch MacBook Pros with Touch Bar and the 2016 and 2017 15-inch MacBook Pros all have full-speed data transfer on all four ports. It’s really confusing. Thankfully, all the 2018 MacBook Pros with Touch Bar now support full-speed data transfer on all four ports.

Zip your code folder

The final hurdle is the files themselves. I noticed that the transfer speed would fluctuate all over the place. Sometimes it would spike up to Thunderbolt speeds but often it would slow to a crawl, causing the transfer to take hours longer than would be expected.

Eventually I realized that even though I only have about 400 GB of data to transfer, the reason why it takes so much longer than expected is because I’m a programmer.

Migration Assistant does a file-level copy—it copies each file one at a time. There’s overhead in starting to copy a file and finishing copying a file. That means it’s much faster to copy one big file than a lot of little files, even if in aggregate they’re the same size as the big file.

The work programmers do doesn’t take up a lot of space so it deceptively seems like the data should transfer quickly, but the package managers we use to install dependencies generally create a lot of files. I just looked at one project and the dependencies totaled ~120,000 files. Multiply that across 20 or 30 projects and that is what makes the transfer take so long.

The fix is to zip up the folder where you keep your code, delete the original folder, do the transfer, then unzip it afterwards.


Before I got around 5 MB/s when migrating. Sometimes it would spike up to 20 MB/s but only briefly. I don’t even know how long the transfer would have ultimately taken because I cut it off after 20 hours with only about two-thirds done.

I made another attempt after figuring all this out. This time the transfer started at 5 MB/s but slowly ramped up to 105 MB/s and held steady there for the rest of the migration.

It took 1 hour and 45 minutes. 🚀

Explicit Privates

Years ago I wrote about the different styles of private declarations in Ruby and my personal preference. It was the best I could see at the time, but it was only marginally better than the rest and totally non-standard. Now I think I’ve finally arrived at a style that is superior to all of them.

To recap, the common style is this.

class Stuff

  def something_public
    # …
  end

  private

  def something_private
    # …
  end

end

Despite being ubiquitous, it’s actually awful. If your file is large, the only way to know if a method you’re looking at is private or not is to keep scrolling upwards until you either see a private or class declaration. All Rubyists have done this so many times now it’s become habitual. We’ve all internalized this as normal and we don’t ever think about how absurd it is. There’s a better way, though. If you’re a savvy Rubyist, you might be aware that the private declaration doesn’t affect class methods.

class Stuff

  private

  def self.something_private
    # Not actually private
  end

end

Never having tried to directly call a class method I’d declared as private, I didn’t discover this for years. To actually make a class method private you have to use private_class_method.

class Stuff

  def self.something_private
    # Now this is private
  end
  private_class_method :something_private

end

Which led me to realize you can do the same thing with instance methods and private.

class Stuff

  def something_private
    # This is private
  end
  private :something_private

end

And even better, the private declarations can be inlined.

class Stuff

  def something_public
    # …
  end

  private def something_private
    # …
  end

  private_class_method def self.classy_private
    # …
  end

end

This works because the return value of a method declaration is the method name as a symbol, which gets passed as an argument to private and private_class_method.

Whatever your initial gut reaction is to the repetition, it will quickly be replaced by the surprising relief of knowing immediately whether the method you’re working on is public or private and not having to jump around to find out. I’ve been using this for the last several months and it’s great. Try it—you’ll come to love it too.