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", "employee", "company", 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.)

Cantilever Laptop Stand

I'm really liking this laptop stand. It's a bamboo cutting board clamped to a bamboo file sorter. Looks nice, very sturdy, and I can either sit or stand.

When I'm sitting, this arrangement allows me to bring the screen closer to me than, say, if I rested the laptop on a stack of books. This helps me avoid the habit I have of leaning forward to peer at the screen, which has caused me lots of neck and shoulder pain over the years.

The screen is at just the right height for me but might have to be higher for someone taller.

Assembly involved no measuring, no cutting, no drilling, and no skills. Also no cost, since it's made from things I already had.

I should make this into a kit and sell it at 100% markup. I'd call it "The Diveboard", and I'd make up a bogus story about months of research into design, ergonomics, and sustainable materials.

laptop stand

Intro Notes on the Smalltalk Environment

This is a follow-up to my post about Smalltalk language basics. Here I’ll talk very generally about the Smalltalk environment — at least what I remember about it. Like my previous post, this is meant to be a lightweight conceptual orientation.

The main thing to get is that the Smalltalk environment is a complete, self-contained universe of objects. The Smalltalk language defines an abstract syntax for creating objects and sending. The Smalltalk environment contains actual objects — things in memory being managed by a running process on your computer — that can interact with each other and that you can interact with.

Here's what happens when you do Smalltalk development:

  • You launch the VM (virtual machine), which is a runtime engine that will interpret and execute all your Smalltalk code.
  • You load a file called a Smalltalk image, which contains a snapshot of the aforementioned universe of objects.
  • Once the image has loaded, you're presented with a UI for writing and executing code.
  • Everything you do in that UI, even something as simple as moving a window, has some effect on that "universe of objects": you're either creating, modifying, or destroying one or more objects in that universe.
  • Before you quit Smalltalk, those changes are saved to the image file to be reloaded next time. (You need to know that there's actually a separate file called the changes file, but that's an implementation detail for purposes of this discussion.)

A rough analogy would be that the VM is like a game engine and the image is like a massive file containing the state of game play exactly as it was when you left off.

The image contains descriptions of all the objects that existed in the "universe" when the snapshot was taken. When the image is loaded, all those objects are re-instantiated. Since everything in Smalltalk is an object, including windows, this means all the windows that were open when you left off will re-appear right where you left them. If you had a debugger window that had stopped at a breakpoint in some code that was running, that debugger will re-appear in exactly the state it was in previously, and you will be able to resume executing that code as if you'd never quit Smalltalk, since the execution context was yet another object that was saved in the image.

Here are some kinds of windows you can open in the Smalltalk environment:

  • Browser. A browser window lets you browse the source code for all the classes that exist in the environment, including not only classes you wrote but also Smalltalk's built-in classes, which are themselves written in Smalltalk. (Classes are objects, so they are reconstituted and added to the environment when the image is loaded, just like all other objects.) Browsers are where you create your own classes.
  • Workspace. A workspace window is basically a scratch pad where you can type Smalltalk code and run it.
  • Transcript. A transcript is a special kind of workspace. You can write text to the global object named Transcript, and that text will be written to all transcript windows. You can use this anywhere in your code to print output. For example:

    Transcript show: 'About to add two numbers.'; cr.
    x := 3 + 4.
    Transcript show: x; cr.
  • Inspector. An inspector window displays the internal state of an object — its instance variables. You can open an inspector on any object by sending it an #inspect message (e.g. try this: 3 inspect) or, in some contexts, by right-clicking on it and selecting "inspect it" from the contextual menu.
  • Debugger. A debugger window lets you step through running Smalltalk code, examine code being executed, and inspect the objects involved. A handy feature of Smalltalk is that in general you can modify code in the middle of debugging, and the new code will be used without your having to restart the program you were running.

You can open as many of each type of window as you want. You generally open them by right-clicking and selecting from a contextual menu, or by hitting a keyboard shortcut.

Speaking of contextual menus, the last thing I'll mention is some operations that are available anywhere you can select Smalltalk source code. If you right-click one or more statements, the contextual menu will contain a whole bunch of options, of which these are the handiest to start with:

  • do it — Executes the selected code.
  • print it — Executes the selected code and prints the resulting value immediately after the selected text.
  • inspect it — Executes the selected code and opens an inspector on the resulting value.

There are typically keyboard shortcuts for these actions.