Composition over Inheritance, emotionally:
I have feelings, not I _am_ my feelings.
I can notice them, decide how to use them.

Discoholic đȘ©

â
wallacepolsom
$LAYYYTER
i don't do bad sauce passes

ç„æ„ / Permanent Vacation
Aqua Utopiaïœæ”·ăźćșă§èšæ¶ă玥ă
we're not kids anymore.
Sade Olutola
Show & Tell

tannertan36
KIROKAZE

PR's Tumblrdome
h
Cosmic Funnies
No title available
Three Goblin Art
Alisa U Zemlji Chuda

izzy's playlists!
YOU ARE THE REASON
seen from United States

seen from Serbia

seen from Malaysia

seen from Russia
seen from France

seen from Malaysia
seen from Sweden
seen from United States
seen from Philippines
seen from Philippines
seen from United States
seen from United States
seen from United States

seen from Malaysia

seen from United States

seen from United States

seen from United States
seen from China

seen from United States

seen from Spain
@tistil
Composition over Inheritance, emotionally:
I have feelings, not I _am_ my feelings.
I can notice them, decide how to use them.
Kubernetes is like a dishwasher
Iâm capable of washing dishes by hand. But I donât enjoy doing that every time I eat. And I donât appreciate when people get sloppy and thereâs still food on the plates.
The dishwasher is a standard place to put the dirty dishes. Washing happens. I have to load it and unload it, but the washing is reliable, consistently thorough, with hotter water than I could use by hand and no dirty washcloths.
Kubernetes is like a dishwasher. Yes, I could run all my apps by hand, but I wouldnât do as good a job, I canât prescribe to other people how to do it with the same precision, and I might re-use infrastructure (dirty washcloths).
Kubernetes, once loaded, keeps the apps running until I unload them. It watches over them, so I donât have to think about them every day.
It does suck when the dishwasher breaks down and I donât know how to fix it. Glad there are companies who will do that for me.
Kubernetes is better than a dishwasher because it has an API; I can program computers to load and unload it, triggered on events like a successful build. Iâm still working to program my kids to put their dishes in the dishwasher upon successful meal completion.
learning to learn
Francesco Cesarini remarked the other day that most of learning programming is learning how to learn.
As an adult, I do this consciously now. Iâm learning piano, and when a teacher tells me: practice only that part that I struggle with. Practice it slowly. One hand at a time. When you get it right, keep going: practice it correctly five times before moving on.
I do this, and it helps. I learn the song, and I learn something about learning.
The other day, practicing a 10-minute talk, I stopped after the part I struggled with it. I practiced that one part, repeatedly, not until I got it right but until I got it right three times in a row. It helped.
So now you have a trick for learning something. The larger point is: look for you own learning tricks, and apply them more broadly, and get better at learning everything. This is the next level of humanity, this is the modern age, this is software.
shared intentions: leveling up at helping
Today a friend installed a sink in my basement. I know nothing about plumbing, so I hung around to watch. When it was clear I could help him with some action, I did: holding a pipe steady while he cut, sanding the second end after watching him do the first. It was tempting to pick up the installation instructions and try to contribute ideas, but I knew better.
This works with pairing on code, too: when someone else has all the context, Iâm not gonna make them explain to me top-down what weâre doing, not at a level detailed enough that I could contribute. If I can participate in the action theyâre currently taking, then I can help. As I gain context, I can contribute at a higher level: suggesting a different path when one gets hard, recognizing potential problems as we embed them. If I try to contribute at too high a level, then I force my partner to justify decisions theyâve made. Even if Iâm right (unlikely), they donât experience that as help.
Next time I join a new team, Iâm going to remember this. I donât have to have all the context to help with actions in progress. As I gain context, I can help at a higher level.
The ability to shared intentions is what makes us human. (from The Righteous Mind, by Haidt) This applies at many levels, from a mission statement down to a task. (seamaps illustrate this.) I can help at the levels that I understand, and gain understanding in the process.
a thousand small problems
Thereâs an anecdote in which Gorbachev (or Yeltsin) visits New York (or London, or Austin) in the waning years of the USSR. He is astonished by a grocery store, with its fully stocked shelves and no lines. He asks, âWho is in charge of the supply of bread to New York?â
because it is ingrained in him that serious work is best done by a single planning mind. Yet the evidence said otherwise: New York has plenty of bread, and Moscow did not.
No one is in charge of the supply of bread to New York. A thousand people are in charge of the supply of bread to one store. A thousand small problems, each solved in their own way, are tractable; one big problem, solved âefficiently,â is not.
In an enterprise, it sometimes feels efficient to put a person in charge of the supply of servers, or testing, or purchasing. Yet by lumping these small problems together by category, youâve created a big problem that can never be solved well for everyone.
Teams need different servers, at different paces, so gathering guesses and then planning and then allocating is always going to be too slow and never accurate. Letting each team get their own is a small pain for each team, but a big pain for no one. Even better: offer a general solution to solve 80% of the problem (fill out this web form to get a company-standard cloud VM within five minutes), and then let teams handle their special needs themselves.
The stores in New York mostly buy bread from a few distributors, but they can bake their own bread if they choose.
When developing infrastructure and tooling for an enterprise, I donât want to be the central planner, very efficient at slowing everyone down. I want to be a distributor. The internal market is large enough and specific enough to target. When I do my job well, many teams will use my products. A few will still bake their own, and Iâm not in their way.
Why does it work?
"Whyâ is too vague a question. Read my post on medium for the true-in-life half of this post.
John Allspaw and the SNAFU catchers are studying incident retrospectives. People ask, âWhy did this fail?â and you can learn a lot from that. In this talk my favorite bit is: ask âWhat made this not be worse?â Focus on the relative successes so that you can sustain those controls/tools/people in the future.
The useful question in a system âwhyâ is âHow does it stay true?â
We can look at a system in that perspective, we can ask, âitâs working. how does it stay working?â and the answer is, people. The people above the line are monitoring and adjusting as the external environment fluctuates and changes.
We can look at each part of the system and learn something.
âThe database is up. how does it stay up?â and one answer is, âthereâs a controller that starts new replicas when needed, and shuts down ones that arenât responding.â In another case, a controller is watching and switches to failover when necessary, and another piece keeps the failover database in sync with the live one. Software below the line automates controls that people used to spend energy on.
Ask this question about various parts of your system, and youâll learn about it. which will be useful in your next incident.
P.S.
Mike Nygard made a post along these lines a few days before I did. When the world is ready for an idea, it doesnât come to just one person ;-)
smaller steps are the best steps
Opening a bag of lozenges: I want to rip the bag, it doesnât tear. Maybe with my teeth? I want to open it in one step.
Slow down, Jess, humans are tool users. Get the scissors. Cut the bag open. Return the scissors.
Itâs more steps, what fun is that? but each step is easier than the hardest step in the original plan. Itâs the hardest step that is limiting, not the quantity.
I think about this in code, too: three pieces of complexity 2 are, in aggregate, less complex than one piece of complexity 4. It isnât the sum, itâs the maximum, that limits what we can understand.
In this post, Kent Beck applies this to refactoring. âThere is a tradeoff between the cost of adding steps to a workflow and the expected cost of mistakes.â
Adding steps feels more expensive than it is. Slow is smooth, smooth is fast, even for household tasks.
nope, canât do everything
The other day in the kitchen, I was disgusted by the knife left in the sink. Knives are dangerous. Wash them, dry them, put them directly back into the knife block.
Itâs just one thing in the kitchen. Itâs one that Iâve picked to be important. Meanwhile I left bits of food on the floor, kicked them under the edge of the counter. Someone else would find that disgusting.
i can let go of my fury about the knives now. And laundry baskets on the couch (those things sit on the basement floor, ew). And ripped-open envelopes, those are so hideous I must throw them away immediately.
These are only my pet peeves. The other adults in my household are not deficient people for prioritizing something else instead. There are infinitely many useful things to do or clean. If they do choose to put the knives away or trash the envelopes for my sake, it is a gift.
Itâs the same in code. I have my pet peeves. How important is it that the tests hit live services instead of faked ones? Yes it will be faster and better when we put in the work to change that, but there are tons of other things to work on too. Itâs a balance. Sometimes we do a thing because it makes the other people on our team more relaxed. Christian doesnât like abbreviations so Iâve started writing out ârepositoryâ more. These are gifts we can give each other to smooth our teamwork.
canât spend all day on self care
My dentist tells me that taking great care of my teeth is essential for health. My chiropractor thinks my spine is the #1 thing I should keep in order. (Well, my former chiropractor; I didn't revisit that one after the guilt trip.) A personal trainer will say exercise is a top determiner, and a dietician that food is first.
They're all right; all these are important. But I can't do everything! I have work to do and a life to live!
It's a balance. At each moment one of these things matters most; if my back is wonked then chiropractic care will help. If my energy is super low, am I low on iron or need more exercise? Life isn't about doing everything right; it's about getting the right things a little more right. And "the right things" are extremely contextual.
In software, people exhort developers to be responsible. Write tests first. Make good abstractions. Create a universal language. Experiment and validate. Retrospect and follow up. Refactor. Read everything in Slack, and all the commits, and emails. Get the user docs beautiful. Add null checks and error messages. Unit test and property test and integration test and simulation test. Learn the business and the code and the tech. Alphabetize your imports.
If I wrote code Correctly, it'd be useless by the time I shipped it. (qualifier: I'm talking about business software that's unproven, not serious libraries.) Oh yeah, and ship constantly.
It's contradictory! So you know for sure it's contextual, that some of these rules don't matter in your situation.
There's several ways that my team is doing it "wrong." There are several dirty things in the pull request I'm about to submit. The question is, is it good enough? and which improvement will make a difference in this context?
We tend to improve the things that stand out to us, which may or may not matter. Code smells, we know how to spot those. But what's the leverage point, what's the constraint in the system? Maybe it is a few missing tests. More likely it isn't software at all, but communication among team members. Or my understanding of the business.
The magic solution for one team is a waste of time for the next. Consider your context carefully, and don't let people guilt you about the tasks you consciously chose not to do right now.
donât make me think about style
âA good style guide is one of the keys to writing more and faster. Avoiding style decisions alone offers the same sort of speed boost as word processing.â - the Responsible Communication Guide
Programming is fractal decisionmaking. Thereâs a little bit of typing to express the results of our decisionmaking, and yet thereâs a ton of decisionmaking even in that typing. what file do we put it in? what do we call the function? If we are also thinking about how to format the code, thatâs yet more decisionmaking that we could have spent on important business decisions like which errors to handle and how.
Style guides are important. Even better is when theyâre automated, so that I hit save and poof my code conforms to the style. Then I donât have to memorize the style guide. This is particularly important when switching between languages or teams that have different style guides.
Automated stylers like elm-format and go-fmt remove obstacles from adding this language to your repertoire.
Clutter
This comic describes life in a typical heterosexual household:Â https://english.emmaclit.com/2017/05/20/you-shouldve-asked/
Consider the part about clearing the table. The protagonist goes to put something away, sees laundry needs moved, moves it; sees food to put away, puts it; sees mustard is missing, notes it. As she moves about the home, sheâs doing stuff that needs doing, moving what needs moving, noting what needs done later. Itâs 2 hours before sheâs cleaned the table, but the house is in an overall better state.
Her partner clears the table in 10 minutes, but does nothing else to improve the house. He probably stacked shit somewhere else.
Which of them looks more productive?
If we evaluate our performance based on the time it takes us to do the named task at hand, we look slow unless we skip everything else we see.
If weâre evaluated at how smoothly the household operates -- or how smoothly our development teamâs work goes long-term -- this looks very different. My team has mustard, and clean laundry, and the food is in the fridge. We arenât gonna be in the âoh crap I have no clean shirts and no sandwichesâ panic when a deadline approaches.
Individual productivity is a destructive thing to measure.
Think about generativity instead: the difference between your teamâs work without you, vs your teamâs work with you.
Who on your team would the work slowly go to crap without? (on mine itâs @ddgenome.) Say thanks to that person today, and tell their manager.Â
time-dependent rate phenomenon
Here is a fascinating article about biology:Â https://www.quantamagazine.org/20170314-time-dependent-rate-phenomenon-evolution-viruses/
It says that when you look at organisms over a few generations, you see lots of mutations. Yet when you look at those organisms over thousands of years, the rate looks much slower.
This means that we have lots of variation, and it circles back to where it started after a while.
If we consider this with our teams: say a team has a retro every 2 weeks, and they choose to try something different in their process for the next 2 weeks. They can keep doing this over and over, and at the end of the year, theyâre likely to be quite close to where they started. A year-over-year retro (carefully recording norms each time, because weâll forget by next year) would show that not much has changed. And _this is success_.
Consider this with our teams: if velocity is constant from sprint to sprint, weâre doing it wrong. Weâre not changing, weâre not implementing anything new. Average velocity over 6 months should be pretty constant, but if week-to-week itâs the same, either weâre cheating somehow, or weâre not evolving at all.
If frequent changes stress you out, take a broader perspective. Weâll circle back, and be mostly the same but hopefully a little better. If the lack of change over time bores you, focus smaller, and try temporary changes to keep yourself learning, and very gradually the organization will learn too.
changing systems
Is there a word for acceptance without approval? intimacy without attachment? embracing without preserving?
To change a software system I need to become part of it, I need to understand how the bits fit together. For example: When we spin up a new AWS instance, we use code in one repository, which activates a system controlled by another repository, which includes a script that shells into another machine where it makes an HTTP call to localhost to a service in a third repository, which digs around in its history and links to artifacts created by code in a fourth repository to package up a fifth repository. Â Do I approve of this flow? It doesn't matter. I need to accept its existence, without accepting its inevitability. I need to love it enough to understand it, and only then can I confidently change it.
In social systems too, I am part of the system already. I need to understand its workings; I am part of them. It is from here I can exert force for changing them. Resentment, denial, judgement: these hurt me, and they change nothing. I will face my fear, and my pain, and let it pass through me. I will be not surprised, I will be not approving, I will not expect that because it is this way now, that it must always be. I am part of the system but I do not help it self-preserve, in ways that I am able to see because I no longer punish myself with resentment and terror for being able to see them.
Participation is not endorsement.
To understand a complex system, whether society of software, means immersing myself in it, while retaining perspective. It means observing each interaction without surprise, it means intimacy without losing my self. To understand deeply is to love -- to love without needing it to stay the same. There's a concept our culture doesn't have: love, intimacy, familiarity while encouraging change. Even with children we are like "I wish they didn't grow up so fast!" No. Let them grow, it is the changing that holds their greatest beauty.
When I can hold in my head both the way the system works now and the way I wish it to work soon, then I can find the stepping stones and the pressure points to move it from here to there.
Stepping Stones
(from a progressive political position) My husband and I shouted at each other over Obamacare this morning. âItâs progress!â I said. âIt is not!â he felt. Later he calmed down and admitted that Obamacare has helped some people some. But what we need is single payer.
Even if everyone in the government agreed that single payer healthcare is better, the way to get there is not BAM! Change the rules. Healthcare companies, out of business. Doctor offices, change operations. We donât get from here to there in one decree.
We need stepping stones. Where we are today matters. How the system works today determines where we can go in the near future. Obamacare is a small step. Change the system, let it adjust. Change a bit more, let people move. Provide transitional support at each step. Sometimes it takes generations for opinions and skillsets to shift.
Even in tech, when we talk about âdisruption,â we donât mean BAM! change everyone right now. We mean: add a new option to the system, which alters peopleâs preferences, and then the system changes itself.
In software systems, where we are today matters. Once software is in production, change is hard. Itâs incremental, or itâs dangerous. Each step needs transitional support. Customers need time to adjust, APIs need backwards compatibility.
In developer tooling, where an organization is today matters. The latest new open-source deployment system looks cool, and could be less work than maintaining the one we have now, but getting from here to there is far more work than either. It means making the new tool support everything we currently do. It means keeping todayâs UI working, running both systems for a while, as we train teams in the new way. It means migrating production services gradually.
Aysylyu Greenberg gave a great talk about implementing a new distributed build architecture at. The majority of the work went into transition.Â
Standing up the new system is easier than moving from the old to the new.
There is no âjust rewrite it.â
Improving systems (software and people) can be orders of magnitude harder than building them from scratch. Yet when weâre not starting from zero, our work has guaranteed impact: everyone now participating in the system will benefit. I like this kind of work, but it takes a lot of patience. At least in software, we can work faster than government. Releases are faster than generations.
Haydn or Beethoven
Joseph Haydn wrote over a hundred symphonies. He pretty much defined and perfected the form of the symphony, as within it he wrote so many, so well loved. Beethoven, a generation later, wrote only nine symphonies. Few - and yet each one is different and unique, each one redefined the structure in a new way.Â
As a developer, are you a Haydn or a Beethoven? Excellent software, a process defined and followed to great productivity? Or excellent software, a process altered with great originality? Both are masters. Â Haydn was prolific in his output, while Beethoven was prolific in his innovation.
Which does your company need more of now? And how would we hire for each?
Source: How to listen to and understand great music, a course by Prof Greenberg. Lecture 29 or 30.
distributed systems in a band
Watching the symphony last night: the conductor provides common ground for the joint activity of playing the music. She is a single point of coordination, that canonical clock that everyone can see at the same time. There is no information delay from the conductor to any member of the orchestra. They are playing from the same script, they have situational awareness of each other, plus they have a common source of timing.
Maybe a jazz band, playing improvisationally, is more like a distributed system without a central coordination point. All listening to each other, all sharing enough knowledge of the music and each other to respond and build the song. They have common snippets of scripts, and lots of awareness of each other.
For distributed systems in computing, imagine a jazz band with information delay. Theyâre trying to improvise but they can only hear what the other musicians played a few measures ago. Worse: usually itâs one measure ago but sometimes itâs several measures ago and no one knows which. They have to decide what to play in realtime based on out-of-date information. Everything they play will affect their peers, but they donât know when.
Yeesh.
Add a central point of coordination, and a strict script, and weâre back to being in an orchestra - except with information delay, they canât play in sync. If it takes the conductorâs movements a different amount of time to reach each musician, they arenât playing together anymore.
We want our software systems to sing. But we canât expect them to play a perfect song, not with central coordination, not with peer-to-peer. I donât know what the solution is, but more and more I appreciate that this is hard.Â
Good news, bad news
The big news stories are almost always about disasters and terrible things. The good news in life is not nearly so dramatic. The good parts are people helping each other, one-on-one. One building going up, one life improved by science. Each child who grows and learns for another day.
This is a property of complex systems. Improvement happens in âlots of tiny, measured steps in the same direction performed by many people over a long time.â (@jackdanger) Catastrophic failures are sudden.
It is the same with software. Once critical systems are in production, and reach a level of scale and complexity that makes them useful and hard to change, improvements come in small incremental steps. Disaster comes suddenly. Success is in keeping them alive to grow and learn another day.