The idea behind Facebook’s Relay is to write declarative queries, put them next to the user interaction code that uses them, and compose those queries. It’s a solid idea. But this snippet about Relay Modern made me chuckle:
The teams realized that if the GraphQL queries instead were statically known — that is, they were not altered by runtime conditions — then they could be constructed once during development time and saved on the Facebook servers, and replaced in the mobile app with a tiny identifier. With this approach, the app sends the identifier along with some GraphQL variables, and the Facebook server knows which query to run. No more overhead, massively reduced network traffic, and much faster mobile apps.
Relay Modern adopts a similar approach. The Relay compiler extracts colocated GraphQL snippets from across an app, constructs the necessary queries, saves them on the server ahead of time, and outputs artifacts that the Relay runtime uses to fetch those queries and process their results at runtime.
How many meetings did they need before they renamed this from “GraphQL stored procedures” to “Relay Modern”?
(FWIW, I worked on a system that exposed stored procedures through a web service for client-side interaction code. It wasn’t too bad, setting aside the need to hand write SQL and XSLT.)
I don’t like using services like Uber, Twitch, or Favor. I want to like them, because the underlying ideas are pretty futuristic. But the reality of these services is that the new boss wants to squeeze their not-even-employess-anymore just as badly the old boss did. It feels manipulative, like buying a car. Except I’m abetting the manipulation too. :(
The contrast between the gig economy’s rhetoric (everyone is always connecting, having fun, and killing it!) and the conditions that allow it to exist (a lack of dependable employment that pays a living wage) makes this kink in our thinking especially clear.
What happens when the gig economy tries to turn a profit? The race downwards will squeeze out all of their contractors until they can replace them all with automated drivers, commoditized personalities, and punitively-low ad revenue sharing rates. This sounds horribly dystopian but I’m pretty sure it’s already happening. See also: when Google kneecapped bloggers as a side-effect of end-of-lifing Reader and changing Pagerank.
Platforms are, in a sense, capitalism distilled to its essence. They are proudly experimental and maximally consequential, prone to creating externalities and especially disinclined to address or even acknowledge what happens beyond their rising walls. And accordingly, platforms are the underlying trend that ties together popular narratives about technology and the economy in general. Platforms provide the substructure for the “gig economy” and the “sharing economy”; they’re the economic engine of social media; they’re the architecture of the “attention economy” and the inspiration for claims about the “end of ownership.”
After reading this, I started substituting “platform company” for “company building its own monopoly”. And then it all makes sense. Businesspeople say they love free markets, but give any rational-thinking business the chance and they will create so many “moats” and “barriers to entry” that they resemble tiny state enterprises more than a private business. See also: telecoms and airlines.
This has been the status quo for most of the last decade. But the next rising wave of tech innovators twist the definition of “market” even further, to a point where they aren’t actually markets at all.
Yes, my confirmation bias is burning. Yes, technologists are doomed to recreate the robber-baron past they didn’t study. Yes, we still have time to change this. Yes, our field needs an ethics refresher. Yes, we should get back to inventing jetpacks!
…watches are one of the key pieces of jewelry I can sport, and while many have no clue what’s on my wrist, those that do… well do. And they are investments. Usually good purchases will not only last forever (with a little love and care), but go up or retain most of their value over time.
When pal Marcos started talking to me about watches, I realized they checked all the boxes cars do, but at a fraction of the price. If cars check your boxes, look into watches. Jeremy’s intro will get you started without breaking the bank.
With feedback, like jokes, timing is everything. Good feedback at a bad time won’t do the trick.
I’ve mostly experienced programming feedback through pull requests. This is way better than no feedback. However, since most pull requests occur at the end of work, and not somewhere in the middle, some kinds of feedback are not conducive to pull requests.
Suppose all feedback falls somewhere on two axes: “timeliness” and “depth”. The narrow sweet spot of code review is apparent:
The sweet spot in the top-right corner is when code review works best: unhurried and in-depth feedback. I’d hesitate to call the lower-right corner of hurried, minimal feedback a code review at all; it’s more like rubber stamping.
I’ve often referred to code review, flippantly, as the worst form of pairing yet invented. I’ve given a lot of code review feedback in the past that was better suited to the synchronous nature of pairing than the very asynchronous nature of code reviews. That said, I feel like pairing is an excellent way to give all manners of feedback in the moment the code is being conceived or written. You can immediately point out possible incorrectness or better designs and talk it out, with the code at hand, with your collaborator.
However, we can’t all pair all the time. Let me show you how I’m trying to better time my feedback when I can’t share it immediately.
A tale of four pull requests
Consider four PR subject lines. Which ones are appropriate for architectural ideas? What about optimization ideas? When is deep refactoring feedback appropriate? Can I look at one of these in an hour when I’m done with my current task?
“Hotfix Facebook Auth scope”
“Prevent sending email for failed payment jobs”
“Add tagging to admin storylines listing”
“WIP introduce Redis/Lua-based story indexing”
Lately, when I do pull request reviews, I use these guidelines:
Figure out if this PR seems like it’s a hot patch to production, a quick fix on existing work, a PR landing new functionality, or a work-in-progress checkpoint seeking feedback.
Bear in mind that hot patches and quick fixes are more time sensitive and need yes/no feedback on correctness more than detailed feedback.
For hot patches (e.g. “Hotfix FB auth”), I’m only looking for “is this correct” and “will it fix the problem?”; thumbs up or thumbs down and commentary as to what I think is missing to solve the problem. No refactoring ideas. I only touch on performance if I spot a regression.
For quick fixes (e.g. “Prevent sending email…”), I’m again looking for correctness and timeliness. I might leave ideas for how to improve the performance or cleanliness of the code later. Those kinds of notes are entirely up to the gumption of the other developer, though. I know the low-gumption feeling of wanting only to fix something and get on to the next thing.
Landing new functionality (e.g. “Add tagging…”) receives a full review cycle. Beyond baseline correctness, I’m trying to view this code through my crystal ball. When some value of N is grows, will this code slow down noticeably? Is the code structured so that future changes are easy and obvious?
Work-in-progress checkpoints (“WIP introduce Redis/Lua…”) are open to the full spectrum of feedback. Ideas for how to differently structure data, which APIs to export, how to structure objects, how to name the domain model, etc. are all in play. Pretty much the only thing out of play is anything that feels too close to bike shedding.
Bear in mind that everyone exists on a spectrum of coding specificity. More seasoned developers are likely open to ideas for restructuring code or considering novel approaches. Less seasoned developers (including seasoned developers new to the team) likely want specific guidance about which changes to make or factors they need to consider.
Where I may try to respond to hot patches and quick fixes in less than fifteen minutes, I may wait a couple hours before I look at new functionality or WIP reviews.
The most difficult part with these guidelines is how to handle ideas about refactoring on time-sensitive reviews. I want to hold the line against letting lots of little fixes accrete into a medium-sized mess. I don’t want to discourage ideas for refactorings either; I want them separately so I can act on them when I have the energy to really do them.
Use different tactics when sharing feedback for code review; it’s not pairing. Identify patches, reviews, and full feedback pull requests. Sanity check patches, look for correctness in review, look for design in review. Use GitHub’s review process to indicate your feedback is “FYI” vs. “fix this before merging”. Time-to-response is most important for patches and fixes.
Above all: giving feedback is a skill you acquire with practice, empathy, and maintaining a constructive attitude.
In Fred Brooks’ terms, this was essential complexity, not accidental complexity. Features interact — intentionally — and that makes the cost of implementing the N+1 feature closer to N than 1.
In other words, the ability to change a product is directly proportional to the size of N (features, requirements, spec points, etc.) for the system that express that product. You may find practices that multiply N by 0.9 so you go a little faster. You may back yourself into a corner that multiply N by 1.1 so you go a little slower. But, to borrow again from Fred Brooks, there is no silver bullet. Essential domain complexity is immutable unless you reduce the size of the domain, i.e. cut existing features.
Not even fancy new technologies are correlated with reducing your multiplier, in the long run:
This perspective does cause one to turn a somewhat jaundiced eye towards claims of amazing breakthroughs with new technologies…What I found is that advocates for these new technologies tended to confuse the productivity benefits of working on a small code base (small N essential complexity due to fewer feature interactions and small N cost for features that scale with size of codebase) with the benefits of the new technology itself — efforts using a new technology inherently start small so the benefits get conflated.
Lastly, this is a gem about getting functionality “for free”:
So “free code” tends to be “free as in puppy” rather than “free as in beer”.
All free functionality eventually poops on your rug and chews up your shoes.
However, dividing health expenditures into these categories misses an important economic reality: health-care spending has a substantial impact on every other sort of economic activity.
Healthcare isn’t consumption, like buying a TV or going to a movie. It is a Keynesian multiplier. Every dollar the government spends on it means an individual or business can spend more than a dollar on something productive in GDP terms.
UPS and FedEx can’t exist without public roads. Southwest and United Airlines can’t exist without the FAA. Lockheed and Northrop can’t exist without the Air Force. Walmart and McDonald’s can’t exist without food stamps. Entrepreneurs find it harder to start without individual access to healthcare.
Yet Republicans are opposed to the existence of all of these. Perhaps business in America relies on more subsidies and government services than Republicans are willing to admit!
I’m playing with typeful language stuff. Having only done a pinch of Haskell, Scala, and Go tinkering amidst Ruby work over the past ten years, it’s jarring. But, things are much better than they were before I started with Ruby.
Elm in particular is like working with a teammate who is helpful but far more detail oriented than myself. It lets me know when I missed something. It points out cases I overlooked. It’s good software.
I’m also tinkering with Elixir, which is not really a typed thing. Erlang’s dialyzer is similar in concept to Flow, but different in implementation. Both allow gradually introducing types to systems.
I’m more interested in types stuff for frontends than backends. I want some assurance, in the wild world of browsers and devices, that my systems are soundly structured. Types buy me that. Backends, I feel, benefit from a little more leeway, and are often faster to deploy quick fixes to, such that I can get away without the full rigor of types.
Either way, I’m jazzed about today’s tools that help me think better as I build software.
Hello, America. We have to talk. You are built on top of a mountain of federal (a trillion or so dollars) debt. That debt covers some things we need (roads, health care, social safety nets, education, scientific research) and subsidizes distasteful things (energy companies, military contractors, banks, real estate). You could consider that debt the tip of the iceberg. We can see how it contributes to the annual federal budget in dollars and by percentages. It’s a measurable, knowable thing.
Unfortunately, there’s also a ton of unmeasured debt we are accruing. We have to pay the price for it through social norms and charity. Here’s a hackish list:
food service is systematically underpaid so we tip them, most often poorly
the people who clean our hotel rooms are underpaid because they are invisible, unskilled, and often immigrant; depending on what you read, you should tip them but they also say you should hide your valuables from them so which is it, leave money laying around or distrust them not to rub your toothbrush in the toilet?
we pay a small tax on the amount of gasoline we use, but it is comically low, hasn’t gone up in years, and isn’t enough to pay for the usage of our crumbling roads, bridges, etc. sometimes it’s also used to pay for public transit, which is perverse during high gasoline prices if you’ve studied even rudimentary supply-and-demand
our children are raised mostly by women who are expected to just do it for free, despite what else they may want to do with their lives
we let financiers play with our retirement money, in theory because they know how to allocate it, get the occasional Google but more often some business tragicomedy, and in return they get to take a few percent off the top, which ends up being a huge number, for the service basically of them having gone to Harvard or their daddy knew a guy
millions of people live paycheck to paycheck, go hungry, go into massive debt if life comes at them wrong, etc. all because the Walmarts of the world (and there are way more than just Walmart) pay them next to nothing expecting the federal government to pick up the slack except the federal government has been systematically dismantled over the course of decades by men who fancy themselves smart enough to start The Next Walmart but in fact are barely smart enough to get themselves elected in a fair contest let alone actually lead a congressional district
But I digress and rant. And rant. Economists call these externalities. It’s when you have some accidental cost or benefit that is paid for by a third party, e.g. Walmart paying less than a living wage because the government will pick up the tab through welfare.
Point is, we’re underpaying for a lot of stuff. And that’s fun for some of us. We eat avocado toast, take exciting trips around the world, maybe drive race cars. We sort ourselves out so we don’t see the literally millions of people suffering because we’re not paying what it takes to give everyone a chance at doing better off than their parents or picking themselves up when life knocks them down. And then when some transparently awful populist blowhard runs for president, we’re shocked, just shocked, that he ends up winning.
Bring the higher taxes. Make me pay more to eat out. Charge me more for gas. I don’t mind thinking twice about whether I should subscribe to HBO and Showtime and Netflix. If I can’t go to Disney World as often, so be it.
It’s a small price to pay to have avoided what’s coming over the next four years: an increasingly unequal, unfair world for those of us who aren’t already doing great and white and male. Let me pay more for a greater country where everyone, not just the affluent, seek what it is that makes them happy in life without the fear of illness, bad circumstance, political or racial backlash. Let’s not lord that greater country over people to “motivate them to work harder and escape their current lot in life”. Let’s price the externalities that separate the concerns of the rich from the stresses of the poor and let’s all pay our share.