Open your eyes to the nonsense

Logic and culture have nothing to do with one another.

Jerry Weinberg, The Secrets of Consulting

A friend of mine works for a large government organization that runs a dam, extracting electricity from water and gravity.

They have internal software development, of course, and my friend described some impressive obstacles to change. Deploying a new lambda function is a challenge. My friend calls on contacts throughout the department, including friends from previous jobs that now also work there. They help each other through procedural barriers.

I said, wow. He said, yeah, we have a mantra: “We make power, not sense.”

Culture doesn’t make sense, to anyone from outside. Culture is common sense, to anyone embedded in it.

To understand and work with a large organization, let go of trying to make sense of it. Observe it and see what’s there. After that, logic might help in finding ways to work skillfully inside it, maybe even to change it.

Simon Wardley always says, map what is. Then think about moving it toward what you want.

A Christmas Adventure

Here’s our D&D campaign for the day, invented by Tyler. DMs only — Run this for your group:

All the adventurers are running around the city of Frostfang celebrating Candlenights. A person is a suit runs out of the Hot Bubbly Rum factory “Are you adventurers? I’m being haunted! I need protection!” He offers you coupons for cheaper Hot Bubbly Rum if you help him. (Or whatever the party is into.) Help involves protecting him from the 3 ghosts.

Ebenezer Smooge takes you into his office in the factory. As soon as you walk in, a ghostly figure in the corner, wrapped in chains, tells you that you will be visited by 3 ghosts: the ghost of Candlenights past, the ghost of Candlenights Present, the ghost of Candlenights future. The ghost responds to every query with the same statement. If you do some sort of detect-magic or true-sight kind of thing, it appears as a Sending, rather than a ghost.

Smooge rings a bell and someone bring in some Hot Bubbly Rum (but it is cold. “Hot” is part of the brand name). Smooge is an asshole to him. If you tip or charm this person you learn that his name is Magic Bob Crotchett. At various times you may get more of his story: he and some of the other employees chipped in on a Wish spell from a desperate warlock, and asked for Smooge to learn a lesson. But maybe they weren’t specific enough.

At each future point in the story, the original ghost makes an announcement, whatever seems spooky and appopriate. “The ghost of Candlenights Past!” Smooge passes out in fright when convenient.

When midnight rolls around, the first ghost arrives. A 30-ft door appears in the office (it’s a warehouse. high ceilings). A t-rex in a santa hat walks out. The door closes. The T-rex has been instructed to celebrate Candlenights. Its idea of celebrating Candlenights is eating people. For stats, pick some monster appropriate to your party’s level and copy those.

After the party defeats the T-rex, the original messenger announces the Ghost of Candlenights Present. A giant door opens. A present comes out. The door closes. The present is a 2x2x2 box with wrapping paper and a ribbon. When it is opened, two more presents pop out. While it is open, more presents pop out every few seconds. Each of these presents have the same effect.

How do we end the infinite presents? This is a question to be answered in each game.

If someone tries to smash a present and is too successful, they might get sucked inside. After that, and damage to any present is half-transferred to the trapped character.

Any sort of dispel-magic or magic-cutting-off spell can cease the infinite regression of presents. When the magic ends, all existing present boxes contain four commemorative Hot Bubbly Rum glasses. (They’re pretty cheap. No Hot Bubble Rum is included.)

When the infinite present regression is overcome, it’s time for the Ghost of Christmas Future. Another door opens, and a 7-foot-tall cyborg walks through. Its label says Tiny Tim 1000. Set its stats according to party strength. Our DM, Tyler, sets them dynamically at “one round of fighting and then the party kills it.”

What happens after the party defeats it? This is a place for creativity.

In our case, the rogue investigated a safe in the office, found it trapped for explosions. We moved the unconscious Smooge over close to it, then tried to disarm it. Meanwhile Magic Bob walked in and threw a brick to set off the explosion. It minorly damaged the party members who were able to dodge, and killed Smooge. Our party let Magic Bob distribute the money inside to the plant workers. (Our warlock checked his intentions, and he was only gonna skim 10% off the top, which seemed fair to all of us.)

Tyler (DM) admits that this entire adventure blossomed in his mind during the long drive toward our Christmas gathering based on the pun of Christmas Present.

Have fun with it!

Smarter dishwasher, smarter cook

Today before breakfast, we started the dishwasher. I think they might have been clean already, but when I saw Avdi loading all the dirty cups from the counters in, I didn’t complain.

Today making scrambled eggs, I didn’t have my favorite spatula. It was in the dishwasher. Dang it! This is a danger of running the dishwasher during the day: some dishes are unavailable.

Then after breakfast, I couldn’t put the dirties in the dishwasher, because it was running. I had to leave them in the sink or wash them by hand.

My brother-in-law, Tyler, has a system for this. Every night he starts the dishwasher, and every morning he empties it. Not full? Oh well, start it anyway.

He always knows whether they’re dirty or clean, based on the time of day. He has access to all his favorite spatulas all day. He can load the dishes into the dishwasher as soon as they’re dirty. For added bonus: the dishwasher makes its noise while no one is in the kitchen. He can predict his usage of dishwasher pellets: one per day.

Why doesn’t everyone do this? Waste, I guess. The dishwasher uses water and electricity to wash a partial load of dishes. To avoid this waste, I maintain state: is it full yet? Are the dishes clean or dirty? Am I going to need this spatula before it’s done? Why are these dirty dishes in the sink?

What if the dishwasher is smart enough to use less water and effort when there are fewer dishes? The washing machine totally does this. What if we can take care of the waste by add complexity to the dishwasher, leaving my life less complex so I can concentrate on the scrambled eggs?

Maybe tracking all this makes me feel more in-control of the kitchen. Maybe it feels like part of the core work of housekeeping. But it ain’t like anybody’s standing there admiring it. The value I provided this morning wasn’t dishwasher management; it was scrambled eggs.

When programming, keeping track of memory usage used to be part of the necessary complexity. Now that we have efficient garbage collection, we don’t have to use brainspace on that. We aren’t less powerful programmers because we leave memory recovery to the garbage collector; we are more powerful because we can use our brains on the germane complexity of the business.

The system as a whole, with a smarter dishwasher or garbage collector, is more complex. But that’s fine, because there’s a boundary; someone else understands dishwashing or memory management. A lot of complexity in that component relieves me of a little complexity in kitchen management, and that means I can handle more complexity in my chosen domain. Or in programming, I can think more at a higher level because someone else is thinking hard at a lower level.

Starting tonight, I’m gonna let the dishwasher do a little extra work. Then I will concentrate on the work people care about, and make better scrambled eggs.

How can we develop and operate increasingly useful software?

Most software gets harder to change as it ages. Making modern applications, it is not enough to write a system and put it out there. We need continual improvement and adaptation to the growing world.

How can we develop and operate increasingly useful software?

To answer this, I need a mental model of how software teams work.

My model is symmathesy: a learning system of learning parts. A great software team is made of people, software, and tools. The people are always learning, the software is changing, the tools are improving.

With this view, let’s look at the question.

How can we (the people, tools, & software in a symmathesy) develop & operate (for learning, these must be together) increasingly (the ongoing quest) useful (the purpose; to learn, we need connection to its use) software (output of our system to the wider world)? People are products of our interactions; the future matters, so we need healthy growth; and code is a product of our interactions with it — so the route we take, or the process, matters.

The external output of the team is: useful software, running in production. To make it increasingly useful, grow the symmathesy. Growth in a system is defined as an increase in flow. In a symmathesy, that means growth is an increase in learning.

The people learn about the software by operating it, mediated by tools. Then we teach the software and tools by developing. Unless development & operations are in the same team, learning is blocked.

To increase usefulness, the team needs to learn about use. We can get input from outside, and study events emitted by the running software, mediated by tools.

What we know about usefulness leads the team to design change, and move the system to the next version of itself. That next version may be more useful to the outside, or it may be better at learning and teaching, the better to increase knowledge inside the team.

Someone today told me, “All great things in life come from compounding interest” — from feedback loops. (Compound interest is the simplest familiar example of a feedback loop.)

In a great software team, that “compound interest” is our relevant knowledge. Of the software, of its environment, of the people and systems who use it.

Maximize learning to increase the usefulness of software, at an accelerating pace.

Do things right in VSCode

Here are some settings that I change when I install VS Code on a new computer.

Change these by searching for them in the settings UI (Ctrl-comma on Windows or ⌘-, on Mac). Or open the JSON and paste them in; access the JSON from the command palette (Ctrl-Shift-P) by searching for Preferences: Open Settings (JSON).

autosave

Please save my files.

"files.autoSave": "onFocusChange",

autoformat

Please format my files. This only works on files associated with an installed formatter extension.

"editor.formatOnSave": true,

goodbye minimap

My screen is too small to want this miniaturized representation of my file at the right.

"editor.minimap.enabled": false,

goodbye activity bar

Those buttons on the left, I can get to them from the menu. Give me real estate.

"workbench.activityBar.visible": false,

Another thing to know, especially when you have the activity bar off: the Explorer window (or Debug, or Extensions, or whichever you have open) toggles with Ctrl-B (or ⌘-B 0n Mac).

Explorer window opens with Ctrl-Shift-E (⌘-shift-e on a Mac).

window title

I like the title of my window to be only the filename. And I think this gives some indication of whether it needs saved.

"window.title": "${dirty}${rootName}",

open projects in their own window

At a command line (outside VSCode), when I type code . please open a new VSCode window. Do not add this folder to an existing, open project.

"window.openFoldersInNewWindow": "on",

Also, make it big.

"window.newWindowDimensions": "maximized",

stop it with popping stuff up all the time

Especially when live coding, I don’t want stuff popping up on my cursor all day. It bothers me.

 "editor.quickSuggestions": {
        "other": false,
        "comments": false,
        "strings": false,
    },

no carriage returns please

On Windows, when creating a new file, please don’t use carriage returns in the line endings. We don’t need those anymore.

"files.eol": "\n",

all together now

Here are all of them in one cut-and-paste-able block for my next settings.json.

 { 
    "files.autoSave": "onFocusChange",
    "editor.formatOnSave": true,
    "workbench.activityBar.visible": false,
    "editor.quickSuggestions": {
        "other": false,
        "comments": false,
        "strings": false,
    },
    "window.openFoldersInNewWindow": "on",
    "editor.minimap.enabled": false,
    "window.title": "${dirty}${rootName}",
    "window.newWindowDimensions": "maximized",
    "files.eol": "\n",
}

Basements and galleries

In a big new project, where do you start?

My dad bought this old building, and he’s turning it into an antique mall. It’s a huge project: two floors of shopping plus a gallery and museum at the top. Yesterday he showed me what he’s done so far.

In the basement, he added support beams and repaired the sprinkler system. They painted all the water pipes red, air blue, and electric gray. Paint is stored where it won’t freeze. The elevator machinery is oiled and accessible.

On the third floor, where art and artifacts will draw people through the store, he has crafted walls of sunrise, sunset, and nightfall from wood siding in dozens of different stains.

He started with infrastructure and with beauty. The underpinnings of the whole store, made observable with color coded pipes. And the unique features that will make this store different from any other.

In a big project, there’s not one place to start; usually we need to make little circles. Foundations, surface, various points in between.

Emphasize the parts that make the work smoother: a clean workspace, visibility into what’s happening, fire prevention. And the parts that make the work fulfilling: the beauty, so we remember why we’re doing this project at all.

Rebase on the World: personal shell choice

“Why use bash when you have PowerShell?” <– words I did not expect to hear from my own mouth.

Over the past few weeks I’ve begun learning PowerShell, and it’s an improvement over the UNIX (and family) shells, bash and ksh etc.

PowerShell is newer. It builds on what those shells did right, and then gets it more right.

The UNIX-y shell commands have this magical power of composition: you can pipe the output of one to the input of another, and chain these to build tiny programs right on your command line. One sends text to STDOUT, the next reads it on STDIN.

PowerShell does this piping, except with objects instead of lines of text. The data is structured and interrogable (I can ask it what fields it has). In bash, you output your data as text, and the next program parses that text.

Here’s an example from Chapter 1 of PowerShell in Action. In bash, the sort command can parse the piped text and sort on it. You can specify numeric sorting.

ls -l | sort -k 5 -r -n

In PowerShell, the sort command works on named properties of the piped object. And it knows the type of the property, so nobody has to tell it what’s a number.

ls | sort -Property length -Descending

More: PowerShell standardizes parsing of command-line arguments. This gives me consistency when I use the command, and saves painful work when I write a command.

More: PowerShell gives me multiple output paths, one for data (to the next program) and another to the user who typed the command. In bash, commands like git abuse STDERR to send info back to the user.

When PowerShell was only for Windows, by far the most powerful command-line shell for me was bash (or fish or zsh, pick your favorite). Bash worked in the worlds I lived in, and that matters most. Now that PowerShell runs on Mac and Linux, it is the most powerful command-line shell for me … except for one thing.

The biggest thing bash has on PowerShell is: I already know bash. I can type stuff there and it just works. With PowerShell I have to look things up all the time.

But every time I look something up, I increase my abilities. PowerShell raises the floor I build on, compared to bash.

It is always a tradeoff between sharpening the tools we have, vs trading them in for a better model. In this case, I’ll take some slowness in the beginning for a faster top speed.

By switching, I gain advantages that the software world has created since I started programming twenty years ago. I rebase myself on the latest version of the world.

Increase capacity, move slower

If the highways are crowded, and they build more lanes, the highways get more crowded.

If development is slow, and you add resources, development gets slower.

Adding people to a project increases the capacity for activity. Activity doesn’t translate to outcomes.

In these cases, you’re adding capacity to the system for cars, or for work, but those aren’t what makes the system run faster. Instead, adding capacity for traffic or for activity leads the system to change in ways that generate more traffic or activity. Which gets in the way of flow.

(lots more examples in this article)

What you want instead is to make flow easier. Add trains, intersperse commerce and residential. Add continuous delivery, add support structures to make progress easier. Don’t add more capacity for work! Doing work isn’t the point! Make the path shorter, instead.

Game science, programming science

In Pokémon Go last summer, a new feature popped up: bad guys. Some Pokéstops turned dark, and Team Rocket appears there, and they want to fight me. And they always win, dammit!

the Team Rocket Grunt gloats over his victory.

This much I can discover within the game. If I want to know more — like how to win the fights — I turn to the internet.

People on the internet have cataloged all the Pokémon. Each has a type, and each type is weak to attacks of certain other types. They’ve also noticed that when the Team Rocket Grunt boasts, they reveal something about the type of Pokémon they have. After they boast, I get to choose which of my Pokémon to fight their Pokémon with.

People observed these properties of the in-game world, and they reasoned about which Pokémon will be effective against which Team Rocket Grunts, and they’ve tested these guesses in-game, and they’ve posted the results online. I can use their analysis to increase my effectiveness in the world of Pokémon Go.

People take it even farther: they’ve deduced the hidden talent levels of individual Pokémon based on observable properties, and created calculators so that you can evaluate your Pokémon. There is systematic testing and measurement here, and logical deduction, and math.

This is science. People do science to describe a Nature that exists inside this game world. And then they publish their results.

It’s a different culture from the Science we learn in school, that institution/body of knowledge/discipline/people that studies Nature in the physical world. But it is science: it is people using observation, causal hypotheses, tests, and discussion to increase a shared body of knowledge about how a world works.

In software development, StackOverflow works this way too. Questions and answers on StackOverflow are scientific publications, sharing observations and knowledge and recommendations about a Nature that exists inside a particular programming language, tool, or library.

Every piece of software constructs its own little reality. Collaborating online, we study them together. We do science.

Work with the business, not for it

Scientists should be on tap but not on top.

Winston Churchill

In the Cold War, political and technical considerations were no longer separable. The President got a Science Advisory Committee, but “apparently… scientists must not concern themselves with devising and proposing policies; they ought to limit themselves to answering such technical questions as they may be asked.” (Leo Szilard, physicist)

Yikes! Sounds like old style software development, where the programmers receive the requirements from the business.

I think we’ve learned better than that. Many of the most successful companies are led by technical people. We need the business experts and software developers working together. The business doesn’t know all the questions developers can answer, and devs don’t know what questions to ask the business — until we start implementing. Then, necessary questions rise to the surface, and lead to discussions which include more useful questions.

If developers are “on tap” as a resource, we can’t create anything better than you can specify (and believe me, that list of requirements is no specification). Our collective imagination is better than either alone.

Asking useful questions is the hard part. Collaborate on it.