Enjoying Another Advent of Code

On his blog, Karthik Balakrishnan wrote:

My interest in competitive programming dwindled pretty quickly and eventually I stopped doing it all together.

Until I discovered Advent of Code.

The whole article describes exactly how I feel, except I'd never even tried competitive programming before. The very thought of it fills me with dread — or at least it did until, like Karthik, I was turned on to AoC when I was at the Recurse Center. I enjoyed it so much I looked forward to it all this year, and I was delighted when December finally came around.

I liked this too:

As time goes by, I see this becoming more a battle of who can keep the cadence of doing this every day (instead of within minutes/hours).

So far this year I've been hustling to solve each problem as fast as I can. At some point (and to be honest I'm not there yet) I will settle into a "cadence" where I take the time each day to savor the feeling of methodically solving a problem and learning stuff along the way. This will happen naturally as the problems get harder, kind of the way New York Times crosswords get harder throughout the week. I get a different kind of pleasure from a Saturday puzzle than I do from a Monday puzzle.

I've been posting code and brief commentary each day on GitHub. Many others do the same, at their own links and on r/adventofcode.

Workarounds for Font Glitches in BBEdit 12.0.1

[UPDATE: Wow, Rich Siegel of Bare Bones replied to my email within a few hours — on Thanksgiving morning! See the updates below.]

Issues in BBEdit 12.0.1:

  • If I change the default font using BBEdit > Preferences… > Editor Defaults > Default font: > Select…, the display of currently open documents doesn't change. They keep using the old font, even if I resize the window to force the text layout to update. (This "nudging" used to be needed in older versions of BBEdit to get font changes to get applied to open documents.) Newly opened files do use the new font preference.

    • Workaround: either relaunch BBEdit or close documents and reopen them.
    • UPDATE: This is fixed in 12.0.2. I thought I had reproduced the bug in the beta of 12.0.2 but was mistaken.

  • If I open the Font Panel with ⌘T (View > Text Display > Show Fonts) instead of through Preferences, I can modify the font of the currently open document — but only that document. Same Font Panel, different effect. Furthermore, that particular document is stuck with that font across launches, because the association between font and file is remembered in ~/Library/BBEdit/Document State.plist. As far as I can tell there's no UI for telling that file to revert to the default font preference.

    • Workaround: quit BBEdit, delete Document State.plist, and relaunch.
    • UPDATE: Persistent per-document fonts are actually a feature. The UI I had missed was the Edit > Normalize Options… menu item, which changes the document back to using your Preferences settings.

I've reported these to Bare Bones. They've always been responsive to my issue reports. If I'm missing something they'll let me know, presumably after the Thanksgiving holiday.

Pairing in Judo and in Programming

These kids are practicing tomoe nage, one of the many judo techniques I never got the hang of:

[Facebook post by Miki Simoyama]

Watching this, I realized there's a relevance here to my life as a computer programmer: judo is inherently a "pairing" activity. You work with a partner for all the most important stuff. As my Sensei says: "Good for me, good for you."

It's important to learn how to be a good judo partner, which includes adjusting for the different types of people you partner with: different skill levels, different goals, different sizes, shapes, and so on. In a drill like the one these girls are doing, both parties should participate mindfully — not just the person practicing the technique (tori) but the person it's being practiced on (uke).

Anybody can be a good uke. If you are less advanced than tori, you can still do the basics correctly like not being too stiff or too limp, adjusting your movements per their requests, and knowing how to do a proper breakfall if needed. Meanwhile, you can pay attention to what tori is doing and learn what it is they are practicing to accomplish, how they are trying to disrupt your balance. It is valuable to learn this from uke's perspective, to engage mentally and not be a passive practice dummy. You shouldn't think too hard — "think" is probably the wrong word anyway — you just have to stay aware and open and you'll learn a lot by osmosis. At least that's my theory. Think of that quote about Ginger Rogers: she did everything Fred Astaire did, except backwards and in high heels. When you are a mindful uke you are sort of practicing judo backwards and in high heels.

If you are more advanced than tori, and understand what they are practicing well enough, you might provide verbal reminders and cues — "Pull the sleeve," "Don't bend over," "Hips need to be lower," and so on. Sometimes, though, silence is better and it's more important to let tori keep trying what they're trying. You can also adjust your own movements to help tori with the intricacies of the technique they're practicing. For example, if tori is working on the timing of a foot sweep it's uke's job to move naturally while knowingly being vulnerable. It takes practice to do this, because you must pretend, over and over, that you have zero anticipation that your balance is about to be disrupted. Any anticipation will come through as tension in your body that tori will be able to sense, and this will be counterproductive. To use another movie analogy, think of that blooper in North by Northwest when a kid covers his ears because he knows there's about to be a loud bang. Being able to relax that anticipation can be tricky; it's hard not to be that kid. The feeling of being tripped is quite unsettling, and here you are helping tori get better at doing that to you.

Back when I was playing judo I think I was pretty decent at "pairing" in terms of adjusting to the person, being aware of safety for both parties, and so on. As a programmer I think my "pairing" abilities could use improvement, which will only happen if I practice as diligently as these two little girls.

[Cross-posted from my judo blog.]

Quick Thoughts on the Apple Glucose Monitor Rumors

Last year when I switched to a low-carb diet I wished I had something like Instruments for my body, where I could observe changes in various parameters throughout the day. Later I learned that's basically what a continuous glucose monitor is. It's like an Instrument that measures one parameter — blood glucose — and lets you graph it over time. To use one, you need a prescription for it, you need have to have it embedded under your skin, and it has to be replaced every so often. Kind of a hassle, not something I feel like doing.

There are rumors that Apple has secretly been developing a non-invasive CGM. It would be amazing and an absolute game-changer if this is true and Apple has it working well enough to be useful, i.e., accurate enough to inform day-to-day decisions about diet and medication. This would mean they've solved technical challenges that other companies have been trying to solve for years — which is not impossible, but I'm not going to hold my breath or jump to any conclusions. I'm just going to wait and see.

If Apple plans to attack the world's diabetes problem, I wonder if a more likely scenario is that they'll announce a partnership with Virta. Purely fanciful speculation on my part, in the fine tradition of pre-WWDC baseless rumor-mongering. I make the connection in my mind because Virta takes a technology-based approach, because it is an ambitious startup that aspires to attack diabetes at scale, and because Peter Attia, an advisor to Virta, is an obsessive self-measurer and wears a CGM even though he is not diabetic.

Misnomers in the Docs on Swift Parameters

[I filed this as Radar #31462992. I might be overthinking things — this is a little like quibbling over whether something's a metaphor or a simile — but word choices matter to me. You should see how I overthink my variable names.]

In "The Swift Programming Language (Swift 3.1)" the terms "argument label" and "parameter name" are misnomers. I have suggestions for solutions.

Misnomers

Programmers often use the terms "parameter" and "argument" interchangeably, but they have distinct meanings.

  • A parameter is a specification of a value that a function expects to be passed to it. It is an inherent part of the function signature. A programmer who calls the function needs to understand this specification so they can call the function correctly.

  • An argument is an actual value that is passed to a function when the function is called. The programmer who implements the function needs the argument to have a name so their code can reference that value.

The way the Swift documentation uses these terms is the reverse of the above meanings. Consider this function:

func wave(toward person: Person) { print("Hello, \(person).") }

According to the docs, "toward" is the argument label and "person" is the parameter name. This is backwards, because the "toward" is the part that the caller of the function must get right, whereas "person" is a local name that's used in the implementation of the function, and that doesn't matter to the caller at all. The word "toward" is part of the function signature, whereas the word "person" isn't.

To drive this point home, imagine that wave(toward:) is a method of a class. Overrides of the method can replace "person" with whatever name they like, or leave out the separate name altogether:

// class GenericWaver
func wave(toward person: Person) { print("Hello, \(person).") }
 
// class FriendlyWaver
override func wave(toward guest: Person) { print("Welcome, \(guest)!") }
 
// class HostileWaver
override func wave(toward enemy: Person) { print("Get lost, \(enemy)!") }
 
// class LazyWaver
override func wave(toward: Person) { print("Whatever, \(toward).") }

If we use the conventional meaning of "parameter" and "argument", then in all four methods, "toward" is part of the parameter description, whereas "person", "guest", "enemy", and "toward" are different names for the same argument — contrary to the terminology used in the docs.

Possible solutions

Fixing this misnaming is not quite as simple as switching the terms "parameter name" and "argument label", because those terms actually make two distinctions:

  • parameter vs. argument
  • label vs. name

Consider again the first "wave" function above. Linguistically speaking, what's happening is that the prepositional phrase "toward person" is broken up so that the noun "person" can be referenced in the function implementation. The preposition "toward" is used as a cue to the programmer calling the function, as a signpost, a kind of fill-in-the-blank. The term "label" makes sense. It's analogous to a label in a form-based user interface:

Mail fields for To, From, etc.

By this reasoning, the most accurate correction would be to use the terms "parameter label" and "argument name".

If I only cared about formal precision, I'd leave it at that, but these names feel heavy to me, and still potentially confusing.

Another solution would be to use the wording Daniel Steinberg uses in A Swift Kickstart: every parameter has an "external name" and an "internal name". This approach gets rid of the label-vs.-name distinction, and this simplification buys increased clarity — the distinction between "external" and "internal" is immediately clear. As a bonus, the rest of the documentation would be a little more free to use "parameter" and "argument" interchangeably without risking confusion. That might or might not be a good thing, depending on your taste.

Yet another solution would be instead to get rid of the parameter-vs.-argument distinction, and call the things "argument label" and "argument name".

One more thing. If you choose to have different external and internal names, the docs describe the external name as something that you add to the left of the internal name. To my mind, it's the other way around: I'd suggest describing the internal name as something you insert after the external name. The difference is subtle, but to me it's meaningful, because the external name is primary and essential, whereas the separate internal name can be thought of as an optional implementation detail. (This is a bit of an oversimplification of the thought process behind having an internal name, but I think the general point still stands.)