Jun 04

Rules for rioters

I had business outside today. I needed to go in towards Philly, closer to the riots, to get a new PSU put into the Great Beast. I went armed; I’ve been carrying at all times awake since Philadelphia started to burn and there were occasional reports of looters heading into the suburbs in other cities.

I knew I might be heading into civil unrest today. It didn’t happen. But it still could.

Therefore I’m announcing my rules of engagement should any of the riots connected with the atrocious murder of George Floyd reach the vicinity of my person.

  1. I will shoot any person engaging in arson or other life-threatening behavior, issuing a warning to cease first if safety permits.
  2. Blacks and other minorities are otherwise safe from my gun; they have a legitimate grievance in the matter of this murder, and what they’re doing to their own neighborhoods and lives will be punishment enough for the utter folly of their means of expression once the dust settles.
  3. White rioters, on the other hand, will be presumed to be Antifa Communists attempting to manipulate this tragedy for Communist political ends; them I consider “enemies-general of all mankind, to be dealt with as wolves are” and will shoot immediately, without mercy or warning.

UPDATE: I didn’t mention white nationalists because I judge my chances of encountering any member of that tiny, ineffectual movement to be effectively zero, and I refuse to cooperate with the mass-media fiction that they are a significant factor in this crisis.

We don’t have a problem with white nationalists attempting to burn down our country using black people as tools and proxies. We have a problem with Communists doing that. I insist on naming – and if necessary, shooting – the real enemy.

May 28

Looking for C-to-anything transpilers

I’m looking for languages that have three properties:

(1) Must have weak memory safety. The language is permitted to crash on an out -of-bounds array reference or null pointer, but may not corrupt or overwrite memory as a result.

(2) Must have a transpiler from C that produces human-readable, maintainable code that preserves (non-perverse) comments. The transpiler is allowed to not do a 100% job, but it must be the case that (a) the parts it does translate are correct, and (b) the amount of hand-fixup required to get to complete translation is small.

(3) Must not be Go, Rust, Ada, or Nim. I already know about these languages and their transpilers.

May 17

Designing tasteful CLIs: a case study

Yesterday evening my apprentice, Ian Bruene, tossed a design question at me.

Ian is working on a utility he calls “igor” intended to script interactions with GitLab, a major public forge site. Like many such sites, it has a sort of remote-procedure-call interface that allows you, as an alternative to clicky-dancing on the visible Web interface, to pass it JSON datagrams and get back responses that do useful things like – for example – publishing a release tarball of a project where GitLab users can easily find it.

Igor is going to have (actually, already has) one mode that looks like a command interpreter for a little minilanguage, with each command being an action verb like “upload” or “release”. The idea is not so much for users to drive this manually as for them to be able to write scripts in the minilanguage which become part of a project’s canned release procedure. (This is why GUIs are irrelevant to this whole discussion; you can’t script a GUI.)

Ian, quite reasonably, also wants users to be able to run simple igor commands in a fire-and-forget mode by typing “igor” followed by command-line arguments. Now, classically, under Unix, you would expect a single-line “release” command to be designed to look something like this:

$ igor -r -n fooproject -t 1.2.3 foo-1.2.3.tgz

(To be clear, the dollar sign on the left is a shell prompt, put in to emphasize that this is something you type direct to a shell.)

In this invocation, the “-r” option says “I want to do a release”, the -n option says “This is the GitLab name of the project I’m shipping a release of”, the -t option specifies a release tag, and the following filename argument is the name of the tarball you want to publish.

It might not look exactly like this. Maybe there’d be yet another switch that lets you attach a release notes file. Maybe you’d have the utility deduce the project name from the directory it’s running in. But the basic style of this CLI (= Command Line Interface), with option flags like -r that act as command verbs and other flags that exist to attach their arguments to the request, is very familiar to any Unix user. This what most Unix system commands look like.

One of the design rules of the old-school style is that the first token on the line that is not a switch argument terminates recognition of switches. It, and all tokens after it, are treated as arguments to be passed to the program and are normally expected to be filenames (or, in the 21st century, filename-like things like URLs).

Another characteristic of this style is that the order of the switch clauses is not fixed. You could write

$ igor -t 1.2.3 -n fooproject -r foo-1.2.3.tgz

and it would mean the same thing. (Order of the following arguments, on the other hand, will usually be significant if there is more than one.)

For purposes of this post I’m going to call this style old-school UNIX CLI, because Ian’s puzzlement comes from a collision he’s having with a newer style of doing things. And, actually, with a third interface style, also ancient but still vigorous.

When those of us in Unix-land only had the old-school CLI style as a model it was difficult to realize that all of those switches, though compact and easy to type, imposed a relatively high cognitive load. They were, and still are, difficult to remember. But we couldn’t really notice this until we had something to contrast it with that met similar functional requirements with lower cognitive effort.

Though there may have been earlier precedents, the first well-known program to use something recognizably like what I will call new-school CLI was the CVS version control system. The distinguishing trope was this: Each CVS command begins with a subcommand verb, like “cvs update” or “cvs checkout”. If there are switches, they normally follow the subcommand rather than preceding it. And there are fewer switches.

Later version-control systems like Subversion and Mercurial picked up on the subcommand idea and used it to further reduce the number of arbitrary-looking switches users had to remember. In Subversion, especially, your normal workflow could consist of a sequence of svn add, svn update, svn status, and svn commit commands during which you’d never type anything that looked like an old-school Unixy switch at all. This was easy to remember, easy to document, and users liked it.

Users liked it because humans are used to remembering associations between actions and natural-language verbs; “release” is less of a memory load than “-r” even if it takes longer to type. Which illuminates one of the drivers of the old-school style; it was shaped back in the 1970s by 110-baud Teletypes on which terseness and only having to type few characters was a powerful virtue.

After Subversion and Mercurial Git came along, with its CLI written in a style that, though it uses leading subcommand verbs, is rather more switch-heavy. From the point of view of being comfortable for users (especially new users), this was a pretty serious regression from Subversion. But then the CLI of git wasn’t really a design at all, it was an accretion of features that there was little attempt to simplify or systematize. It’s fair to say that git has succeeded despite its rather spiky UI rather than because of it.

Git is, however a digression here; I’ve mainly described it to make clear that you can lose the comfort benefits of the new-school CLI if a lot of old-school-style switches crowd in around the action verbs.

Next we need to look at a third UI style, which I’m going to call “GDB style” because the best-known program that uses it today is the GNU symbolic debugger. It’s almost as ancient as old-school CLIs, going back to the early 1980s at least.

A program like GDB is almost never invoked as a one-liner at all; a command is something you type to its internal command prompt, not the shell. As with new-school CLIs like Subversuon’s, all commands begin with an action verb, but there are no switches. Each space-separated token after the verb on the command line is passed to the command handler as a positional argument.

Part of Igor’s interface is intended to be a GDB-style interpreter. In that, the release command should logically look something like this, with igor’s command prompt at the left margin.

igor> release fooproject 1.2.3 foo-1.2.3.tgz

Note that this is the same arguments in the same order as our old-school “igor -r” command, but now -r has been replaced by a command verb and the order of what follows it is fixed. If we were designing Igor to be Subversion-like, with a fire-and-forget interface and no internal command interpreter at all, it would correspond to a shell command line like this:

$ igor release fooproject 1.2.3 foo-1.2.3.tgz

This is where we get to the collision of design styles I referred to earlier. What was really confusing Ian, I think, is that part of his experience was pulling for old-school fire-and-forget with switches, part of his experience was pulling for new-school as filtered through git’s rather botched version of it, and then there is this internal GDB-like interpreter to reconcile with how the command line works.

My apprentice’s confusion was completely reasonable. There’s a real question here which the tradition he’s immersed in has no canned, best-practices answer for. Git and GDB evade it in equal and opposite ways – Git by not having any internal interpreter like GDB, GDB by not being designed to do anything in a fire-and-forget mode without going through its internal interpreter.

The question is: how do you design a tool that (a) has a GDB like internal interpreter for a command minilanguage, (b) also allows you to write useful fire-and-forget one-liners in the shell without diving into that interpreter, (c) has syntax for those one liners that looks like an old-school CLI, and (d) has only one syntax for each command?

And the answer is: you can’t actually satisfy all four of those constraints at once. One of them has to give. It’s trivially true that if you abandon (a) or (b) you evade the problem, the way Git and GDB do. The real problem is that an old-school CLI wants to have terse switch clauses with flexible order, a GDB-style minilanguage wants to have more verbose commands with positional arguments, and never these twain shall meet.

The only one-syntax-for-each-command choice you can make is to have the same command interpreter parse your command line and what the user types to the internal prompt.

I bit this bullet when I designed reposurgeon, which is why a fire-and-forget command to read a stream dump of a Subversion repository and build a live repository from it looks like this:

$ reposurgeon "read <project .svn" "prefer git" "rebuild ../overthere"

Each of those string arguments is just fed to reposurgeon’s internal interpreter; any attempt to look like an old-school CLI has been abandoned. This way, I can fire and forget multiple reposurgeon commands; for Igor, it might be more appropriate to pass all the tokens on the command line as a single command.

The other possible way Igor could go is to have a command language for the internal interpreter in which each line looks like a new-school shell command with a command verb followed by switch clusters:

igor> release -t 1.2.3 -n fooproject foo-1.2.3.tgz

Which is fine except that now we’ve violated some of the implicit rules of the GDB style. Those aren’t simple positional arguments, and we’re back to the higher cognitive load of having to remember cryptic switches.

But maybe that’s what your prospective users would be comfortable with, because it fits their established habits! This seems to me unlikely but possible.

Design questions like these generally come down to having some sense of who your audience is. Who are they? What do they want? What will surprise them the least? What will fit into their existing workflows and tools best?

I could launch into a panegyric on the agile-programming practice of design-by-user-story at this point; I think this is one of the things agile most clearly gets right. Instead, I’ll leave the reader with a recommendation to read up on that idea and learn how to do it right. Your users will be grateful.

May 13

Two graceful finishes

I’m having a rather odd feeling.

Reposurgeon. It’s…done; it’s a finished tool, fully fit for its intended purposes. After nine years of work and thinking, there’s nothing serious left on the to-do list. Nothing to do until someone files a bug or something in its environment changes, like someone writing an exporter/importer pair it doesn’t know about and should.

When you wrestle with a problem that is difficult and worthy for long enough, the problem becomes part of you. Having that go away is actually a bit disconcerting, like putting your foot on a step that’s not there. But it’s OK; there are lots of other interesting problems out there and I’m sure one will find me to replace reposurgeon’s place in my life.

I might try to write a synoptic look back on the project at some point.

Looking over some back blog posts on reposurgeon, I became aware that I never told my blog audience the last bit of the saga following my ankle surgery. That’s because there was no drama. The ankle is now fully healed and as solidly functional as though I never injured it at all – I’ve even stopped having residual aches in damp weather.

Evidently the internal cartilage healed up completely, which is far from a given with this sort of injury. My thanks to everyone who was supportive when I literally couldn’t walk.

May 08

Term of the day: builder gloves

Another in my continuing series of attempts to coin, or popularize, terms that software engineers don’t know they need yet. This one comes from my apprentice, Ian Bruene.

“Builder gloves” is the special knowledge possessed by the builder of a tool which allows the builder to use it without getting fingers burned.

Software that requires builder gloves to use is almost always faulty. There are rare exceptions to this rule, when the application area of the software is so arcane that the builder’s specialist knowledge is essential to driving it. But usually the way to bet is that if your code requires builder gloves it is half-baked, buggy, has a poorly designed UI or is poorly documented.

When you ship software that you know requires builder gloves, or someone else tells you that it seems to require builder gloves, it could ruin someone else’s day and reflect badly on you. But if you believe in releasing early and often, sometimes half-baked is going to happen. Here’s how to mitigate the problem.

1. Warn the users what’s buggy and unstable in your release notes and the rest of your documentation.

2. Document your assumptions where the user can see them,

3. Work harder at not being a terrible UI designer.

4. Watch the issues list/user’s forum/mailing list, and actually respond.

5. When someone tells you it requires builder gloves, believe them. And fix it so it doesn’t.

Becoming really good at software engineering requires that you care about the experience the user sees, not just the code you can see.

Apr 27

The feel for weapons

I read Scientists Have Recreated Ancient Battles to Solve Debate Over Ancient Bronze Swords and was annoyed.

Not because the study wasn’t worth doing for its own sake – I applaud archeologists with the good sense to use historical reenactors to learn more about how combat in bygone times must have worked. But it seems to have been done to refute a theory that shouldn’t have been entertained seriously for three seconds – namely that Bronze Age swords were mainly ceremonial items with little use in actual combat.

I am, as Charles Babbage might have said, not able rightly to apprehend the kind of confusion of ideas that could provoke such a theory.

Continue reading

Apr 26

Lassie errors

I didn’t invent this term, but boosting the signal gives me a good excuse for a rant against its referent.

Lassie was a fictional dog. In all her literary, film, and TV adaptations the most recurring plot device was some character getting in trouble (in the print original, two brothers lost in a snowstorm; in popular memory “Little Timmy fell in a well”, though this never actually happened in the movies or TV series) and Lassie running home to bark at other humans to get them to follow her to the rescue.

In software, “Lassie error” is a diagnostic message that barks “error” while being comprehensively unhelpful about what is actually going on. The term seems to have first surfaced on Twitter in early 2020; there is evidence in the thread of at least two independent inventions, and I would be unsurprised to learn of others.

In the Unix world, a particularly notorious Lassie error is what the ancient line-oriented Unix editor “ed” does on a command error. It says “?” and waits for another command – which is especially confusing since ed doesn’t have a command prompt. Ken Thompson had an almost unique excuse for extreme terseness, as ed was written in 1973 to run on a computer orders of magnitude less capable than the embedded processor in your keyboard.

Herewith the burden of my rant: You are not Ken Thompson, 1973 is a long time gone, and all the cost gradients around error reporting have changed. If you ever hear this term used about one of your error messages, you have screwed up. You should immediately apologize to the person who used it and correct your mistake.

Part of your responsibility as a software engineer, if you take your craft seriously, is to minimize the costs that your own mistakes or failures to anticipate exceptional conditions inflict on others. Users have enough friction costs when software works perfectly; when it fails, you are piling insult on that injury if your Lassie error leaves them without a clue about how to recover.

Really this term is unfair to Lassie, who as a dog didn’t have much of a vocabulary with which to convey nuances. You, as a human, have no such excuse. Every error message you write should contain a description of what went wrong in plain language, and – when error recovery is possible – contain actionable advice about how to recover.

This remains true when you are dealing with user errors. How you deal with (say) a user mistake in configuration-file syntax is part of the user interface of your program just as surely as the normally visible controls are. It is no less important to get that communication right; in fact, it may be more important – because a user encountering an error is a user in trouble that he needs help to get out of. When Little Timmy falls down a well you constructed and put in his path, your responsibility to say something helpful doesn’t lessen just because Timmy made the immediate mistake.

A design pattern I’ve seen used successfully is for immediate error messages to include both a one-line summary of the error and a cookie (like “E2317”) which can be used to look up a longer description including known causes of the problem and remedies. In a hypothetical example, the pair might look like this:

Out of memory during stream parsing (E1723)

E1723: Program ran out of memory while building the deserialized internal representation of a stream dump. Try lowering the value of GOGC to cause more frequent garbage collections, increasing the size of your swap partition, or moving to hardware with more RAM.

The key point here is that the user is not left in the lurch. The messages are not a meaningless bark-bark, but the beginning of a diagnosis and repair sequence.

If the thought of improving user experience in general leaves you unmoved, consider that the pain you prevent with an informative error message is rather likely to be your own, as you use your software months or years down the road or are required to answer pesky questions about it.

As with good comments in your code, it is perhaps most motivating to think of informative error messages as a form of anticipatory mercy towards your future self.

Apr 19

Payload, singleton, and stride lengths

Once again I’m inventing terms for useful distinctions that programmers need to make and sometimes get confused about because they lack precise language.

The motivation today is some issues that came up while I was trying to refactor some data representations to reduce reposurgeon’s working set. I realized that there are no fewer than three different things we can mean by the “length” of a structure in a language like C, Go, or Rust – and no terms to distinguish these senses.

Before reading these definitions, you might to do a quick read through The Lost Art of Structure Packing.

The first definition is payload length. That is the sum of the lengths of all the data fields in the structure. No padding is included in this length.

The second is stride length. This is the length of the structure with any interior padding and with the trailing padding or dead space required when you have an array of them. This padding is forced by the fact that on most hardware, an instance of a structure normally needs to have the alignment of its widest member for fastest access. If you’re working in C, sizeof gives you back a stride length in bytes.

I derived the term “stride length” for individual structures from a well-established traditional use of “stride” for array programming in PL/1 and FORTRAN that is decades old.

Stride length and payload length coincide if the structure has no interior or trailing padding. This can sometimes happen when you get an arrangement of fields exactly right, or your compiler might have a pragma to force tight packing even though fields may have to be accessed by slower multi-instruction sequences.

“Singleton length” is the term you’re least likely to need. It’s the length of a structure with interior padding but without trailing padding. The reason I’m dubbing it “singleton” length is that it might be relevant in situations where you’re declaring or passing a single instance of a struct not in an array.

Consider the following declarations in C on a 64-bit machine:

struct {int64_t a; int32_t b} x;
char y

That structure has a payload length of 12 bytes. Instances of it in an array would normally have a stride length of 16 bytes, with the last four bytes being padding. But your compiler might generate a 12-byte copy when you ask it to assign the value of x.

This struct has a singleton length of 12, same as its payload length. But these are not necessarily identical, Consider this:

struct {int64_t a; char b[6]; int32_t c} x;

The way this is normally laid out in memory it will have two bytes of interior padding after b, then 4 bytes of trailing padding after c. Its payload length is 8 + 6 + 4 = 18; its stride length is 8 + 8 + 8 = 24; and its singleton length is 8 + 6 + 2 + 4 = 20.

To avoid confusion, you should develop a habit: any time someone speaks or writes about the “length” of a structure, stop and ask: is this payload length, stride length, or singleton length?

Most usually the answer will be stride length. But someday, most likely when you’re working close to the metal on some low-power embedded system, it might be payload or singleton length – and the difference might actually matter.

Even when it doesn’t matter, having a more exact mental model is good for reducing the frequency of times you have to stop and check yourself because a detail is vague. The map is not the territory, but with a better map you’ll get lost less often.

Apr 14

Insights need you to keep your nerve

This is a story I’ve occasionally told various friends when one of the subjects it touches comes up. I told it again last night, and it occurred to me that I ought to put in the blog. It’s about how, if you want to have productive insights, you need a certain kind of nerve or self-belief.

Many years ago – possibly as far back as the late 80s – I happened across a film of a roomful of Sufi dervishes performing a mystical/devotional exercise called “dhikr”. The film was very old, grainy B&W footage from the early 20th century. It showed a roomful of bearded, turbaned, be-robed men swaying, spinning, and chanting. Some were gazing at bright objects that might have been lamps, or polished metal or jewelry reflecting other lamps – it wasn’t easy to tell from the footage.

I can’t find the footage I saw, but the flavor was a bit like this. No unison movement in what I saw, though – individuals doing different things and ignoring each other, more inward-focused.

The text accompanying the film explained that the intention of “dhikr” is to shut out the imperfect sensory world so the dervish can focus on the pure and holy name of Allah. “Right,” I thought, already having had quite a bit of experience as an experimental mystic myself, “I get this. In Zen language, they’re shutting down the drunken monkeys. Autohypnosis inducing a serene mind, nothing surprising here.”

But there was something else. Something about the induction methods they were using. It all seemed oddly familiar, more than it ought to. I had seen behaviors like this before somewhere, from people who weren’t wearing pre-Kemalist Turkish garb. I watched the film…and it hit me. This was exactly like watching a roomful of people with serious autism!

The rocking. The droning. The fixated behavior, or in the Sufi case the behavior designed to induce fixation. Which immediately led to the next question: why? I think the least hypothesis in cases where you observe parallel behaviors is that they have parallel causation. We know what the Sufis tell us about what they’re doing; might it tell us what the autists are doing what they’re doing?

The Sufis are trying to shut out sense data. What if the autists are too? That would imply that the autists live in a state of what is, for them, perpetual sensory overload. Their dhikr-like behaviors are a coping mechanism, an attempt to turn down the gain on their sensors so they can have some peace inside their own skulls.

The first applications of nerve I want to talk about here are (a) the nerve to believe that autistic behaviors have an explanation more interesting than “uhhh…those people are randomly broken”, and (b) the nerve to believe that you can apply a heuristic like “parallel behavior, parallel causes” to humans when you picked it up from animal ethology.

Insights need creativity and mental flexibility, but they also need you to keep your nerve. I think there are some very common forms of failing to keep your nerve that people who would like to have good and novel ideas self-sabotage with. One is “If that were true, somebody would have noticed it years ago”. Another is “Only certified specialists in X are likely to have good novel ideas about X, and I’m not a specialist in X, so it’s a bad risk to try following through.”

You, dear reader, are almost certainly browsing this blog because I’m pretty good at not falling victim to those, and duly became famous by having a few good ideas that I didn’t drop on the floor. However, in this case, I failed to keep my nerve in another bog-standard way: I believed an expert who said my idea was silly.

That was decades ago. Nowadays, the idea that autists have a sensory-overload problem is not even controversial – in fact it’s well integrated into therapeutic recommendations. I don’t know when that changed, because I haven’t followed autism research closely enough. Might even be the case that somewhere in the research literature, someone other than me has noticed the similarity between semi-compulsive autistic behaviors and Sufi dhikr, or other similar autohypnotic practices associated with mystical schools.

But I got there before the experts did. And dropped the idea because my nerve failed.

Now, it can be argued that there were good reasons for me not to have pursued it. Getting a real hearing for a heterodox idea is difficult in fields where the experts all have their own theories they’re heavily invested in, and success is unlikely enough that perhaps it wasn’t an efficient use of my time to try. That’s a sad reason, but in principle a sound one.

But losing my nerve because an expert laughed at me, that was not sound. I think I wouldn’t make that mistake today; I’m tougher and more confident than I used to be, in part because I’ve had “crazy” ideas that I’ve lived to see become everyone’s conventional wisdom.

You can read this as a variation on a theme I developed in Eric and the Quantum Experts: A Cautionary Tale. But it bears repeating. If you want to be successfully creative, your insights need you to keep your nerve.

Apr 03

On the implausibility of a war with China

In the wake of the PRC’s actions around the COVID-19 pandemic, there has been increasing speculation in some circles that the PRC might be preparing to wage war against the United States, or at least some sort of regional war (such as an invasion of Taiwan) in which treaty obligations would involve the U.S.

I’ve actually been considering this possibility, from my perspective as a wargamer and military-history buff, for over a decade – ever since China began seriously flexing its muscles in the South China Sea. And the risk of war has undoubtedly been rising recently.

The PRC has given U.S. and other trade partners ample reason to conclude that they need to decouple their economies from Chinese supply chains. Threats by China to use its control of most of rare-earth production for economic blackmail have been followed by much more serious threats to use its dominance of the manufacturing of basic pharmaceuticals as a weapon.

Post-COVID-19, it’s now strategically vital for other nations to develop supply chains for critical goods that are domestic, or at least better guarded against the political and epidemiological risk of relying on Chinese manufacturing. While necessary, this shift does mean the PRC has less to lose in the event of going to war.

Nevertheless, I continue to judge that the odds of China launching a war are very low. Nobody can entirely rule out enraged, irrational behavior by the PRC, but in the remainder of this post I will attempt to demonstrate why the war options available to the PRC hold out little or no prospect of a satisfying victory and entail severe terminal risks.

Continue reading

Mar 24

Choosing your weapons wisely

In the comments to my last post advising people not to panic-buy guns because of COVID-19, I got a request from a regular wondering how to choose a first firearm wisely, and about safe storage practices.

He said: “I’m thinking in the next year of getting a gun for home defense, and I’d like myself and my spouse to train with it. […] I have young kids, and want to make sure the gun is accessible enough to be reachable in the event of a break-in but hard enough to access that my daughter doesn’t get into it.”

Credentials for anybody new here: I have several decades of experience as a self-defense and firearms instructor. I’m grateful that I haven’t had to shoot a human being yet. I’m not a professional in this stuff, but people who are treat me as a peer. As you keep reading, I think you will recognize the common sense in my advice.

Content warning: if you are easily offended by cold-blooded consideration of violent outcomes or Damned Facts about statistical patterns in criminality, this post will offend you.

I’m going to address the second sentence first. For basic physical security, you may want to consider getting a pistol-sized gun safe with a biometric lock. However…and I cannot emphasize this enough…do not rely on this to protect your children. Children are curious and ingenious and if they consider your security a challenge to be defeated you could have a tragedy.

The only safety lock that reliably protects your child is the one you install in your child’s head by teaching him or her that a gun is a dangerous tool that should only be used with adult supervision. Explain the danger. Do not make your weapons taboo forbidden fruit or surround them with mystery; if your child is curious, take him or her to the range with you.

If your child becomes very interested, this is good. Shooting sports are an effective way to develop discipline and concentration. And very safe (safer than golf, for example) except in the extremely unlikely case that you’ve raised a sociopath or some other kind of minimal-brain-damage victim, in which case you have larger problems than I’m going to try to address here.

Now I’ll talk about intelligent choice of weapons. This depends on your threat model and where you live.

I’m going to go into different threat models more later in this post, but I’ll start with advice that is common to all of them. The single most universally useful firearm you can have – and the least dangerous in case of accident or misuse – is a reliable carry pistol which you do, in fact, carry daily.

Do not get hung up on caliber or type. Gunfolks love to argue about stopping power and bullet ballistics but it turns out that once you get out of the mouse-gun range (.22, .25 and .32) all pistol calibers have essentially indistinguishable statistics on two-shot stops.

Therefore, keep it simple. Rent several different pistols at a range. To use your time efficiently, exclude monster hand cannons like .44 Magnum; that is certainly not a good beginner’s choice. You should be looking at calibers from 9mm up to .45ACP (11mm). Shoot them all, and pay attention to which one fits your hand the best and feels most comfortable for you to shoot. That is almost certainly the one you should buy.

I myself prefer medium-caliber semiautomatics like a .40 or .45 because I don’t enjoy the snappy recoil of a 9mm. But other people can be best suited for lighter-caliber pistols or revolvers; there are a lot of relevant variables including the shape and size of your hands and what kind of upper-body strength you have.

For home defense, it’s probably a good idea to fit a laser sight on your pistol; I got an aftermarket one recently for my .45. Then you can train in point shooting using the laser – makes you faster responding because you don’t have to pause to get a sight picture.

Because this post is about choice of weapons, I’m not going to talk a lot about training methods except to say “do one”. Train, train, train. Get comfortable with firing your weapon, learn how to be accurate at normal pistol engagement ranges of 7-10 feet.

That’s feet, not yards. It’s pretty close. Accuracy at that range is easy. More important than crisply perfect technique is the ability to handle the psychological stress of clutch situations so your accuracy doesn’t go to shit when you’re tired, rattled, and in low-light conditions. Read up on “stress inoculation” and try to get some.

Don’t be daunted by the thought that it takes years to master shooting. As with all skills, the more you put into it, the more you can get out. But any competent instructor can teach you how to handle firearms safely in 20 minutes, and you can develop the competence for basic self-defense shooting in a few hours.

You should lock that in with at least semi-regular practice, though. The newer you are, the more regular it should be; eventually (after years) you may get to the point where your muscle memory is solid enough to weather long periods without practice.

You’ll need a holster so you can carry. A gunbelt – which is just an extra-stiff leather belt that helps distribute the weight of you weapon – is a good investment. Alas, choosing good gunleather is an entire topic in itself. Expect that the first holster you buy will not be optimal and that you’ll probably need to experiment a few times before finding one that suits you for long-term use.

One area in which I think the gun culture can be unhelpful is in helping you judge how much ammunition to keep around. The problem is that a lot of us gunfolks end to treat the size of our ammo stockpiles as a sort of tongue-in-cheek competitive studliness display. The truth is that for almost everyone a 250-round reserve per weapon (exclusive of what you buy and shoot at the range) is just fine – generous, in fact.

Beyond that first pistol, what else you should buy starts to diverge based on where you live and what your threat model is. I’m going to start by assuming the most common and simplest one, which I’ll call the Standard Threat Model: you want to defend yourself and your family against low-level criminal violence, with a side order of hedging against a temporary (on the order of a few days) condition of civil disorder due to, e.g., natural disaster.

In that case a lot depends on whether you live in Switzerland or Swaziland. Most of the U.S. has violent-crime statistics like Switzerland – very low base rate of crime, law-abiding neighbors, high levels of legal gun ownership. In Switzerland, even temporary disaster conditions don’t induce looting, arson, and crime spikes. Therefore they do not raise your threat level much.

Unfortunately, parts of the U.S. – some major urban cores, and some drug-corridor rural areas near the Mexican border – are Swaziland. In Swaziland base violent-crime rates are high. Rates of legal gun ownership are low. Your neighbors are unhelpful, and a high-deviant cohort of them is actively dangerous.

If you live in Switzerland (easily 95% of the U.S. by land area), rational assessment of the Standard Threat Model does not require you to be heavily armed. I’d start with a carry pistol for each adult household member, and one shotgun for fixed-point defense. Whether you should also get a rifle depends on where you live. If you’re urban or suburban there’s not a lot of physical point to it because you won’t have long enough sightlines for distance shooting to matter much.

If you’re rural, on the other hand, you want a rifle. How serious a rifle depends on whether you have dangerous critters like bears or mountain lions in your area. Most people can get away with what gunfolks call a “varmint rifle” – a light-caliber rifle that shoots cheap ammo like .22LR. This is fine if your typical animal threat is something like a rabid skunk. It will take care of threatening humans too, in the extremely unlikely event you assess enough threat to have to shoot them at distance.

If, on the other hand, you have heavy threats like cougars or bears, you need a heavier rifle and a bigger bullet. Detailed discussion of these is out of scope for this post. Besides, I don’t know much about heavy rifles and wouldn’t want to give bad advice.

If you live near enough to a Swaziland, your threat profile is entirely different. Here’s how to tell if you do: (1) you live in a rural area with the Mexican border or concentrations of illegal immigrants within a two-hour drive. (2) you live in an urban area and within 20 minutes’ walk of you are places where groups of black or Hispanic males aged 15-35 carrying intoxicants routinely gather.

Yes, I can hear you lefties screaming already. All I have to say is: study the crime statistics. We can tell all kinds of stories about why those numbers look the way they do. Some of the stories we could tell are racist and irrational (but I repeat myself). The fact that shitty people tell toxic stories about the numbers doesn’t change the numbers, and it doesn’t change what the rational response to the numbers should be.

In American Swaziland, unlike African Swaziland, there’s no dangerous-animal threat at all, so you don’t need a heavy rifle. However, you have a banditry problem – not just individual muggers and home invaders but gangs of feral predators who routinely commit crimes ranging from mass shoplifting raids upwards to savage monkey-dance beatings that cripple or kill their victims. Civil disorder in Swaziland is quite dangerous, not only because of direct threat from mobs of ferals but due to indirect threats like arson.

In Swaziland you also need to assume that any assailant will be high off his ass on something like PCP or bath salts – a disassociative anesthetic. Pistol rounds do not reliably stop such a person before they can get close enough to kill you unless you luck out with a heart or brain shot.

If you’re living in Swaziland, the best thing you can do for yourself and society is arm up to the level where you pose a credible threat not just to individual criminals but to a mob of drunk or drugged ferals with a low average IQ and poor impulse control. Because riots or natural disaster could require you to step up like a roof Korean.

That means we’re in scary-black-rifle territory. You want an AR-15 or something like one. Understand that functionally an AR-15 is not very different in how accurately can shoot and what it can stop from your granddad’s hunting rifle. However, what it does to a mob’s threat assessment is very different.

Granddad’s hunting rifle says to a mob “Stupid ofay probably hasn’t fired that thing in years.” Black rifle says “Uh oh, gun nut. Prepared. Would probably rather shoot than not.” Ironically, this means that if what you’re showing is granddad’s hunting rifle, you’re more likely to have to actually shoot it. I’d consider actually having to shoot a human a less than optimal outcome; if you don’t, I probably don’t want to know you.

And that pretty much wraps up the Standard Threat Model. Now I’ll briefly cover a couple of other possibilities you might want to arm against which group together because they push your weapons mix in a similar direction.

One is longer-term civil disorder, ranging upwards to what gunfolks and preppers call “SHTF” (Shit Hits The Fan) scenarios. Worrying about these changes your optimal weapons mix – basically, you have to assume mob-feral violence as a prompt threat even in Switzerland. You’ll want scary black rifles, at least one per military-age household member.

However…I urge you not to worry about the weapons themselves so much that you neglect other needs. One is ammunition. Anywhere near SHTF conditions ammunition is going to become scarce and valuable; you want at least a thousand rounds per weapon and 10K would not be excessive.

More importantly, however, you need to lay in serious amounts of food and medical supplies before going on any gun-buying sprees. You can’t eat bullets, and raiding your neighbors for food would get terminally risky pretty fast.

I myself do not prep for SHTF very seriously, for reasons which I could explain but which are beyond the scope of this post. However, there is a different reason for me to have a SHTF-like weapons mix: the Second Amendment. I take my Constitutional duty to be part of the nation in arms seriously, and I insist on having the weapons that would-be tyrants foreign and domestic fear and want to take away from me precisely because they want to take them.

Generalizing, a sufficient reason to keep weapons beyond what the Standard Threat Model requires is as a move in the political power game, with the goal of ensuring that they are never actually needed.

Mar 23

PSA: COVID-19 is a bad reason to get a firearm

I’m a long-time advocate of more ordinary citizens getting themselves firearms and learning to use them safely and competently. But this is a public-service announcement: if you’re thinking of running out to buy a gun because of COVID-19, please don’t.

There are disaster scenarios in which getting armed up in a hurry makes sense; the precondition for all of them is a collapse of civil order. That’s not going to happen with COVID-19 – the mortality rate is too low.

Be aware that the gun culture doesn’t like and doesn’t trust panic buyers; they tend to be annoying flake cases who are more of liability than an asset. We prefer a higher-quality intake than we can get in the middle of a plague panic. Slow down. Think. And if you’ve somehow formed the idea that you’re in a zombie movie or a Road Warrior sequel, chill. That’s not a useful reaction; it can lead to panic shootings and those are never good.

I don’t mean to discourage anyone from buying guns in the general case – more armed citizens are a good thing on multiple levels. After we’re through the worst of this would be a good time for it. But do it calmly, learn the Four Rules of Firearms Safety first, and train, train, train. Get good with your weapons, and confident enough not to shoot unless you have to, before the next episode of shit-hits-the-fan.

Mar 09

shellcheck: boosting the signal

I like code-validation tools, because I hate defects in my software and I know that there are lots of kinds of defects that are difficult for an unaided human brain to notice.

On my projects, I throw every code validater I can find at my code. Standbys are cppcheck for C code, pylint for Python, and go lint for Go code. I run these frequently – usually they’re either part of the “make check” I use to run regression tests, or part of the hook script run when I push changes to the public repository.

A few days ago I found another validator that I now really like: shellcheck Yes, it’s a lint/validator for shell scripts – and in retrospect shell, as spiky and irregular and suffused with multilevel quoting as it is, has needed something like this for a long time.

I haven’t done a lot of shell scripting in the last couple of decades. It’s not a good language for programming at larger orders of magnitude than 10 lines or so – too many tool dependencies, too difficult to track what’s going on. These problems are why Perl and later scripting language became important; if shell had scaled up better the space they occupy would have remained shell code as far as the eye can see.

But sometimes you write a small script, and then it starts to grow, and you can end up in an awkward size range where it isn’t quite unmanageable enough to drive you to port it to (say) Python yet. I have some cases like this in the reposurgeon suite.

For this sort of thing a shell validater/linter can be a real boon, enabling you to have much more confidence that you’ll catch silly errors when you modify the script, and actually increasing the upper limit of source-line count at which shell remains a viable programming language.

So it is an excellent thing that shellcheck is a solid and carefully-thought-out piece of work. It does catch lot of nits and potential errors, hardening your script against cases you probably haven’t tested yet. For example. it’s especially good at flagging constructs that will break if a shell variable like $1 gets set to a value with embedded whitspace.

It has other features you want in a code validator, too. You can do line-by-line suppression of specific spellcheck warnings with magic comments, telling the tool “Yes, I really meant to do that” so it will shut up. This means when you get new warnings they are really obvious.

Also, it’s fast. Fast enough that you can run it on all your shellscripts up front of all your regular regression tests and probably barely ever notice the time cost.

It’s standard practice for me to have a “make check” that runs code validators and then the regression tests. I’m going back and adding shellcheck validation to those check productions on all my projects that ship shell scripts. I recommend this as a good habit to everybody.

Feb 27

The right to be rude

The historian Robert Conquest once wrote: “The behavior of any bureaucratic organization can best be understood by assuming that it is controlled by a secret cabal of its enemies.”

Today I learned that the Open Source Initiative has reached that point of bureaucratization. I – OSI’s co-founder and its president for its first six years – was kicked off their lists for being too rhetorically forceful in opposing certain recent attempts to subvert OSD clauses 5 and 6. This despite the fact that I had vocal support from multiple list members who thanked me for being willing to speak out.

It shouldn’t be news to anyone that there is an effort afoot to change – I would say corrupt – the fundamental premises of the open-source culture. Instead of meritocracy and “show me the code”, we are now urged to behave so that no-one will ever feel uncomfortable.

The effect – the intended effect – is to diminish the prestige and autonomy of people who do the work – write the code – in favor of self-appointed tone-policers. In the process, the freedom to speak necessary truths even when the manner in which they are expressed is unpleasant is being gradually strangled.

And that is bad for us. Very bad. Both directly – it damages our self-correction process – and in its second-order effects. The habit of institutional tone policing, even when well-intentioned, too easily slides into the active censorship of disfavored views.

The cost of a culture in which avoiding offense trumps the liberty to speak is that crybullies control the discourse. To our great shame, people who should know better – such as the OSI list moderators and BOD – have internalized anticipatory surrender to crybullying. They no longer even wait for the soi-disant victims to complain before wielding the ban-hammer.

We are being social-hacked from being a culture in which freedom is the highest value to one in which it is trumped by the suppression of wrongthink and wrongspeak. Our enemies – people like Coraline Ada-Ehmke – do not even really bother to hide this objective.

Our culture is not fatally damaged yet, but the trend is not good. OSI has been suborned and is betraying its founding commitment to freedom. “Codes of Conduct” that purport to regulate even off-project speech have become all too common.

Wake up and speak out. Embrace the right to be rude – not because “rude” in itself is a good thing, but because the degenerative slide into suppression of disfavored opinions has to be stopped right where it starts, at the tone policing.

The OSI membership page is here.

Feb 21

Reposurgeon defeats all monsters!

On January 12th 2020, reposurgeon performed a successful conversion of its biggest repository ever – the entire history of the GNU Compiler Collection, 280K commits with a history stretching back through 1987. Not only were some parts CVS, the earliest portions predated CVS and had been stored in RCS.

I waited this long to talk about it to give the dust time to settle on the conversion. But it’s been 5 weeks now and I’ve heard nary a peep from the GCC developers about any problems, so I think we can score this as reposurgeon’s biggest victory yet.

Continue reading

Feb 15

The reality of the lizard people

One of the loonier and more wonderful conspiracy theories floating around the Internet is it many of the world’s elite are shapeshifting lizardoid extraterrestrials. This explainer seems to sum it up pretty well.

When I first encountered this idea I was gobsmacked. How could anyone actually believe such a thing? And yet, apparently, many people do – millions of them, if polls on the topic are to be believed.

How humans form and maintain insane beliefs when there are plenty of objective reasons to know better is, I fear, a topic of continuing fascination to me. If only because when contagious and totalizing forms of insanity like Marxism or supernaturalist religions motivate the behavior of mobs they pose a significant threat to my survival.

The lizard-people theory isn’t in that class of danger, but I think cases like it and (for example) flat-Earthism are worth analysis precisely because they’re so implausible and still manage to attract adherents. Extremes like this can be revealing about mechanisms that are harder to see closer to the ordinary.

And indeed when I was mulling over lizard-people theory a few years ago I think I really did get a significant insight about the psychology of belief and what lizard-people conspiracy theory actually means.

Continue reading

Feb 07

Chinese bioweapon II: Electric Boogaloo

Yikes. Despite the withdrawal of the Indian paper arguing that the Wuhan virus showed signs of engineering, the hypothesis that that it’s an escaped bioweapon looks stronger than ever.

Why do I say this? Because it looks like my previous inclination to believe the rough correctness of the official statistics – as conveyed by the Johns Hopkins tracker – was wrong. I now think the Chinese are in way deeper shit than they’re admitting.

Continue reading