Worknotes - October 23, 2022

  • During my absence, my team was reorganized and I moved under a new director and from developer experience to the product development organization. It’s been exciting (new people, new relationships, new opportunities) and also tiring (new people, new relationships, new opportunities). My team was an odd duck in the old structure, and less-so but still odd in the new structure. My verdict is out if that’s an improvement. I think it can be sometimes be easier to stick out hugely instead of subtly: it’s called whackamole, not whackagiraffe.
  • My team, Ruby Architecture, moved from “Build & Test” within DX, to “UI and Monolith Platform” within Core Productivity. In my old group I was figuring out collaborations with the testing and CI platform. With the new group, we’re figuring out how to better explain “platforms” ourselves. I see a lot of “Shifting Left” in my future and I’m here for it.
  • “A feeling you don’t act upon isn’t real.” I’ve picked up this quote from nearly every Kim Stanley Robinson novel I’ve read. I shared it with a few of my reports this week; I’ve been (gently, I hope!) pushing people to share feedback more actively outside the team.
  • “It’s ok to be mad, it’s not ok to be mean”. Angelina and I had dinner this week with family friends who have a 10-year old and they’ve been a resource during our foster parenting journey. This phrase came up and I have been thinking about this as a better alternative to “Assume good intent.” I’m a big fan of Non-Violent Communication and it fits right in there.
  • Performance Review Season is kicking off again. I’m eligible. It feels like no time has passed but this week is my 6 month anniversary at GitHub! It’s still fun.
  • With my leadership coach, we’ve been talking about Moral Mazes, which led to Meditations on Moloch. The overall theme, and I’ve now been working with the coach for three (!) years is (my words): taking action authentically. And then exploring different shapes of that. Ikigai.

Impenetrable legal language

From the paper “What did I sign? A study of the impenetrability of legalese in contracts” via Assaf Arkin’s Labnotes.

The description of “Center-embedded clauses” was particularly interesting to me in regards to plain language.

Each legalese text was drafted to contain the following language properties that have been identified as difficult to process and common to legal texts:

(a) Low-frequency legal terms – Words that are infrequently used in everyday speech provide processing difficulties for readers relative to higher-frequency synonyms (Marks, Doctorow, & Wittrock, 1974). Legal texts are laden with “archaic words” such as aforesaid, herein, and to wit (P. Tiersma, 2008), which have been shown to be frequently misunderstood by laypeople (e.g. P. M. Tiersma, 1993). Each legalese text was constructed to contain several instances of legal jargon, which were replaced with high-frequency synonyms in the plain-English versions.

(b) Center-embedded clauses – Center-embedded structures have long been observed to pose processing difficulties on a reader (Miller & Chomsky, 1963; Gibson, 1998; Pinker, 2003). The tendency for lawyers to “embed” legal jargon “in convoluted syntax” has been observed not only to be prevalent in legal texts but as a potential badge of honor for those who wish to “talk like a lawyer” and be accepted by their profession (P. Tiersma, 2008). Each legalese text was constructed to contain multiple center-embedded clauses (“Artist and Tour, said parties being hereinafter referred as…”), which were written as separate sentences in the corresponding plain-English version.

(c) Passive-voice structures – Relative to their active-voice counterparts, passive-voice structures are acquired later by children (Baldie, 1976), and may continue to pose difficulties for adults (Ferreira, 2003). Gozdz-Roszkowski (2011) found passive structures to be more prevalent in contracts relative to other legal and non-legal genres (such as newspapers). Our legalese texts each contained multiple passive-voice structures (“This agreement has been formed by the parties”), which we converted into active-voice structures in the corresponding plain-English versions.

(d) Capitalization – Non-standard capitalization is ubiquitous in provisions such as warranty disclaimers and limitations of liability, which “must be conspicuous” in order to be legally upheld (American Law Institute and National Conference of Commissioners on Uniform State Laws, 2002). Arbel and Toler (2020) found that most standard form agreements used by major companies contain a provision in all-caps. Although the use of all-caps provisions is ostensibly for the benefit of the reader, evidence suggests that they do not aid comprehension (Arbel & Toler, 2020). Here we included at least one chunk of all-capitalized text in each legalese passage (“THE WARRANTY IS HEREBY DISCLAIMED”), which was replaced with standard capitalization in the simple version.

From the set of legalese materials, each passage was encoded in terms of legally relevant propositions. From these propositions, each passage was then translated into a “plain-English” version, which differed only with respect to the four surface properties described above, resulting in 24 total passages.

For each contract pair, 12-15 comprehension questions were drafted. The questions were multiple choice with four options. These questions both targeted comprehension of specific important legal propositions, as well as more general understanding of the legal content. To reduce a response bias for a given register, we controlled the overlap in form between contract excerpt and comprehension question. Both types of comprehension question were drafted in a “neutral” register. Passive/active structures were replaced by nominalizations. For example, “shipment of the goods on the part of merchant” instead of “the goods were shipped by merchant” or “merchant shipped the goods”). High or low frequency synonyms were replaced with a third synonym (e.g. “renter” instead of “lessee” or “tenant”).

Persian Tahchin-inspired crispy chicken rice

Tahchin

This is a Milk Street recipe, but because I detest their instructional design, I redesigned it here. I like this dish because:

  • It can be made with ingredients from Trader Joe’s.
  • It has currants.
  • Crispy, buttery starch is great.
  • It’s resilient; the second time I made it with indirect heat on a propane bbq grill because my oven was on the fritz. Still great. Also I’ve tried brown basmati rice, tried doubling the eggs, tripled the garlic, I’m not measuring the butter and currents. Still great.

Ingredients

  • 1.5 cups basmati rice
  • 1/4 teaspoon saffron threads
  • 2 tablespoons boiling water
  • 12 ounces boneless skinless chicken thighs. I think this would also work with seitan or tempeh just mix a bit more oil in.
  • 1 lemon, for juice and zest
  • 2 garlic cloves
  • 0.5 cups whole milk greek yogurt
  • 1 large egg (yolk only)
  • 3 tablespoons dried currants
  • 2 tablespoons salted butter, melted
  • Parsley, to garnish
  • Roasted Pistachios, to garnish
  • Olive oil
  • Salt and pepper

A pie plate. Milk Street spends a paragraph saying why glass is best (you can see the browning), but I’ve been doing ceramic and it’s fine.

30 minutes to 12 hours ahead

Soak the rice. Place the rice in a bowl with enough water to cover by 1 inch and let rest at room temperature for at least 30 minutes or up to 12 hours. Drain and rinse the rice again.

To begin

  • Place the oven rack at lowest position and preheat the oven to 400 degrees
  • Prepare a large pot of salted boiling water to cook the rice.
  • Thoroughly oil your pie plate.

Prep the ingredients

  • Melt the butter and set aside.
  • Crumble the saffron threads and soak the saffron in 2 tablespoons of boiling water in a small bowl. Set aside.
  • Zest the lemon resulting in about 3 teaspoons of lemon zest, to be divided between the chicken and the yogurt sauce. Put the rest of the lemon aside to be wedged later.
  • Grate the garlic.
  • Trim the chicken thighs into 1 to 1.5 inch pieces and in a medium bowl combine the chicken with 1 tbsp of oil, 1 teaspoon lemon zest, and garlic Salt and pepper it.
  • Separate the egg yolk (discard the white) and mix the yogurt, egg yolk, remaining 2 teaspoons of lemon zest, and saffron water in a bowl large enough to eventually hold the rice too. Salt and pepper it. Whisk to combine well.

Cooking

  • Add the rice to the pot of salted boiling water and cook for 5 minutes until par-boiled; the rice will still be slightly crunchy. Drain the rice.
  • Mix the par-boiled rice with the yogurt mixture and stir to combine.
  • Add about 1/3 of the rice mixture to the bottom of the pie plate, pressing it into an even layer on the bottom and halfway up the sides.
  • Mix the currants and the yogurt-chicken mixture into the remaining rice and yogurt mixture and then transfer the mixture to the pie dish. Do not compact or press the rice, but do distribute it evenly.
  • Drizzle the melted butter over the rice mixture.
  • Tightly cover the pie dish with foil and bake for 1 hour covered.

While it bakes, clean up and prepare

  • Chop the parsley and reserve for serving.
  • Chop the pistachios and reserve for serving.
  • Slice the lemon into wedges for personal squeezing.

After baking for 1 hour

  • Remove the foil and then uncovered, bake for an additional 10 minutes until the bottom is golden brown.
  • Remove from the oven and rest for about 5 minutes.
  • Run a knife or spatula around the edge to loosen the rice from the pie plate, then invert onto a serving plate.
  • Sprinkle with the parsley and pistachios and serve with the lemon wedges on the side.

Weeknotes: September 19, 2022

  • My mom, Susan, Sue, passed away at her home last Tuesday morning. Her wishes were that people recognize her life through donations to the Santa Barbara Food Bank and Save the Children. My brother and I are figuring out everything else; email me at [email protected] if you’d like to stay updated.
  • Having spent the last 5 weeks with my mom, her doctors’ ongoing prognoses that she “has days” was incorrect for quite a while until it wasn’t. We got to the zoo and the Botanic Gardens together. I enjoyed flustering the hospice nurse over the phone by passing along their questions directly, like “hey mom, how are your bowels?” and the nurse’s response of “oh, oh, I didn’t realize she was awake”. To her doctor’s surprise the day before she passed, what would be my mom’s last meal: taquitos.
  • I learned the stories behind all the butts in my mom’s nude paintings. And that, though my mom wouldn’t have the opportunity to exercise it, California has an End of Life Option.
  • I’m grateful for my family, friends, and colleagues who have been gracious and supportive. Both to those I’ve told, and those who are yet to find out. Thank you.
  • I wrote this biography as part of a family history for Mr. Harris’s 10th grade humanities class in 1999 (“fabulous photos, good layout! A”)

    Born in 1947 (though when interviewed maintained it was 1964), and grew up in the era of McCarthyism, bomb shelters, Elvis, Sputnik, Rock and Roll, and the Beatles. That got her through high school. Then she finished the sixties with a bachelors in painting from California College of the Arts and her masters in Library Science at UC Berkeley. Her first library job was in charge of the Art and Architecture collection at San Jose State. She met my father in Library school and got married in 1971. She quit her job to get married and moved to Alaska where she was in charge of the largest medical library in State of Alaska. She did that for two years and then they moved to Ithaca New York, where she was a library outreach consultant for a five county public library system. At the end of that period she had my brother, and moved to California. I was born four years after, and later she became very active in the Friends of the Poway Library, working on getting a new library in Poway. After divorcing she drew on her experiences as a volunteer and paid substitute in school libraries and decided to become a school librarian which necessitated getting both a teaching credential and a library media teachers credential, which she will finish next year.

    Sue

Reflections on Brompt, 2022

In response to a r/advancedentrepreneur thread, I wrote up some reflections on Brompt in response to “How well did this project do?”:

Not well. I dunno how much help this is, but my thoughts about the experience are:

People who are already inconsistently posting likely aren’t searching for a solution. It would be better to target overachievers who want to get to the next level, than lift up underachievers to just ok. Nagging people doesn’t work on it’s own.

I think “post daily/regularly” isn’t much of a goal. I think it would be better to tap into the actual outcome they want (“top influencer”, “alternative income stream”) and then help pave that path within your service, of which regularly posting is just one “goal” or step on the staircase.

I originally built Brompt back in the mid 2000s when it was a lot easier to attract early adopters. I never monetized it (it was a hobby project that I used in my portfolio to further my regular career). If I was doing it over again, I’d have never built it and probably would have focused on figuring out acquisition (e.g. spend a couple hundred bucks on Facebook ads; focus on a hands-on concierge service, figure out what it is at the intersection of what people are searching to do and are willing to pay for).

Also, the space is incredibly saturated and it’s tough to get visibility. I’ve used Crowdfire before (i found it extremely difficult to use). Also done a lot with Priceonomics model. And there are some other Twitter tools that I wanted to highlight for you… but I literally can’t remember their name and have spent a good 30 minutes trying to Google and can’t find them. So like, that’s not a good environment to build in.

Edit: it was https://ilo.so/

Object Thinking

I’m looking for a book that helps align the practice of software development with the rest of my life, In the sense of a humanistic neural plasticity, an approach that harmonizes rather than hegemonizes (or ignores) the rest of my life.

This book is based on the following beliefs:

  • Agility, especially in the form of extreme programming, is essential if the software development profession, and industry, are to improve themselves.
  • XP offers a way to create “better developers” to improve the intrinsic abilities of human beings to develop software for use by other human beings—a way to produce “master” developers.
  • XP cannot be understood, and those practicing XP will not realize the full potential of the approach, until they understand object thinking and the shared historical and philosophical roots of both object thinking and XP core values and practices.
  • In particular, programmers and technical developers will fail to realize the full potential of XP-based development without a thorough understanding of object orientation—the “object thinking” promised by the title of this book.

I initially found this book searching for “Sapir-Whorf” on the O’Reilly Bookshelf. To the extent that it approaches things humanistically, this is it:

Inheritance: Humans naturally aggregate similar things into sets (or classes). Another “natural” kind of thinking is to create taxonomies—hierarchical relationships among the sets.

Responsibility: If an object states that it is capable of providing a given service, it should perform that service in all circumstances, and the results should be consistent… Responsibility implies that an object must assume control of itself.

This wasn’t quite the book I wanted, though I enjoyed the introduction and the conclusion. The middle was a bunch of methodology that, well, was fine, but I probably won’t think about again; the conclusion does admit that the methodology and modeling section is written primarily as legitimating material for academic formalists and can be transcended and discarded. So that’s cool (but I would have appreciated that being said upfront than afterwards).

  • All methods are someone else’s idea about what you should do when you develop software. It may be useful, from time to time, to borrow from those ideas and integrate them into your own style. It is essential, however, to transcend any method, even your own idiosyncratic method, and “just do it.”
  • Software development is like riding a surfboard—there is no process that will assure a successful ride, nor is there any process that will assure that you will interact propitiously with the other surfers sharing the same wave. Published processes, like published methods, provide observational data from which you can learn and thereby improve your innate abilities—just as observation of master surfers enables you to improve yourself.
  • No model has any value other than to assist in object thinking and to provide a means for interpersonal communication. If you can model your objects and your scenarios in your head while engaged in writing code, and if those mental models are consistent with object thinking, great! No need to write them down. If you and your colleagues use a visual model on a whiteboard as an aid in talking about scenarios and in clarifying your collective thinking about those scenarios, and you erase the board when you’re done meeting, also great! If your models are crudely drawn and use only a subset of the syntax defined here (or a completely different syntax that you and your colleagues collectively agree upon), still great! Model when you must, what you must, and only what you must.

Here’s the good stuff, though it doesn’t have much of a developmental model:

  • Decompose the problem space into behavioral objects, and make sure the behaviors assigned to those objects are consistent with user expectations. This requires understanding why users make distinctions among objects and the illusions they project on those objects. User illusions (following Alan Kay) consist of how people recognize different objects in their world and, having recognized an object, what assumptions are made about how to interact with that object and what its responses will be.
  • User illusions should be maintained; your software objects should not violate them unless you can construct a plausible alternative story that shows a different set of domain entities interacting in different ways or having different capabilities. Business reengineering involves exactly this kind of activity—using domain language and user illusions creatively to craft new stories, some of which might lead to new software.
  • Decompose your problems (applications) in terms of conversations among groups of objects. Everything of interest in the domain is currently accomplished by groups of objects (people and things). Any artifact you construct must participate in a natural way in these same groups. Perhaps your artifact is simply replacing an existing object in the domain with a computer-based simulacrum, in which case it must know how to respond to and supply some relevant subset of recognizable and intuitive interaction cues. Perhaps it is an entirely new object, in which case it will need to be “socialized” to conform to the existing community.

Weeknotes: Aug 29, 2022

  • My mom entered hospice this past weekend. Medicare’s hospice benefits are pretty great, given the circumstances; American healthcare gets progressively better til you die. My mom has a story of her mom, in the 1990s, unsuccesfully convincing my mom of the benefits of single-payer healthcare. My mom says it took until herself going on Medicare to understand. With hospice, you call your caseworker and say “Can the nurse please bring over some blue chux next time?” and that’s all.
  • Angelina and I had originally planned to attend a big family trip to Germany and Amsterdam; we are in Santa Barbara, the American Riveria, instead. YMCA membership portability is the best.
  • I think many shared human experiences are of long boredom punctuated by short excitement or terror. Per the former, I finally added on-site search with lunr.js to this blog; no more Google.
  • I’m currently reading Moral Mazes. From my personal experience reading Bad Blood and Super Pumped, and starting yet not finishing a whole bunch of other non-fiction: I can only handle terrible business books that have no thesis or advice other than gratitude for not being there. I have a bunch of other book reviews to catch up on.

Hate and sarcasm

Two things I read recently were commentary on forcefully-weak communications.

The first, from a r/rails thread in which the poster wrote “I hate React as it’s not using MVC pattern and It’s not organised + I hate JS.” A response:

You mentioned that you’re looking for junior positions which implies that you’re relatively new to the industry and have limited programming experience. Despite this, it seems that you’ve developed a lot of strong opinions.

There’s nothing wrong with having strong opinions and some of the best engineers are very opinionated. However, one of the biggest things you learn as you gain more experience is that you don’t know what you don’t know and that while forming opinions is important, one should understand why we may form certain opinions and whether those reasons are actually valid enough to hold those opinions strongly enough.

For example, you say that you hate JS. Hate is a very strong word for junior developers. Why do you hate JS? Is the hate that you have for the language actually for the language itself or rather code that you’ve written in it? If you’ve been forced to work on an awful codebase, then the language itself isn’t to blame.

You mentioned that you hate React as it’s not using MVC pattern. What is it about the MVC pattern that you like? There’s a lot of advantages with the MVC approach, but other approaches also have merit. As you gain more real-world experience, you’ll realize that there are many ways to do things and each approach has its own merits/disadvantages. You mentioned that React is not organized, but React is not a framework - it’s a library. You can organize it however you want which can be a double-edge sword if you’re inexperienced. Any disorganized React project is not React’s fault nor is it a fault of JS.

Unlike React, Rails is a framework and a very opinionated one. It can be beginner friendly as things will just work out of the box as a lot of decisions have already been made for you. However, it can also be difficult for beginners to level up as Ruby is a lot less explicit and a lot of the behind the scenes magic can be very confusing to figure out why things work the way they do. There is also a lot more ways to write your code in Ruby which means there’s a lot more syntaxes and patterns you may need to be aware of to be competent. (e.g., there’s only a certain number of ways to write a loop in Python but a multitudes of ways in Ruby). This flexibility may seem like a blessing to be able to write expressive and elegant code, but for beginners, it can make the process of leveling up a lot more work.

You should be open to the possibility that you may also not end up loving Ruby when it actually comes to working on production code. Many of us here love Ruby, but it should be stated that there’s a difference between tinkering and using Ruby for toy-projects and maintaining a Rails app. Also, Rails does not make JS go away. You may find yourself writing plenty of JS in Rails to get the desired UX on the frontend.

At the end of the day, I do love Ruby and there are plenty of Rails opportunities in the market so I do think it’s worth learning. But if you want to pursue Rails, you should jump in with both eyes open. You may find that your criticisms of JS & React may not actually be as valid and be specific to the projects that you worked on. If there are a lot more opportunities for you in JS/React than Ruby/Rails, it may be worth continuing down that former path.

And Andrew Bosworth “On Sarcasm”:

At first being sarcastic was incredibly satisfying. Whereas previously I might have made an earnest argument or asked a question, I now seemed to be able to jump right to the part where the group appreciated me and my contribution. What is even more impressive is it required very little thought to execute. I could often get a positive reaction even on topics I knew almost nothing about.

It was when I noticed this last point that I decided that sarcasm was not for me.

Sarcasm “works” because it alludes to a critique without ever actually making it. It shifts the burden of substantiating the criticism as an exercise for the audience and further suggests that if they don’t already understand it then they are deficient. Making a critique implicit is an unassailable rhetorical position. The most socially acceptable response for the group is to go along with it, as you have given them nothing specific to challenge. And if someone does challenge it you can simply demur and say it was “just a joke.”

Sarcasm does nothing to advance our understanding of the world around us or help us improve it.

Four dumb-cringe tech interview stories

In my previous write-up about NodeTiles, I said that I had dumb interview stories to share. They are also cringe. Here they are.

“Oh yeah, me too.”

I failed my very first professional job interview.

I was 21 and it was 2004. It was my last year at the University of California, Santa Barbara. I was graduating early, in three years, with a BS in Math Sciences, with Honors, and I was looking at Summer internships as something to do because the last credit course I needed was only offered at the tail-end of Summer quarter, right before my AmeriCorps*VISTA service began in Boston. I had never done a college internship before, mainly out of ignorance of their importance; this would be my first (and only) attempt at landing one.

UCSB is gorgeous, it’s on the beach; it is a bare-shouldered, sunny, surfy beach town. I was boring. Yes, I surfed and swam and sailed and hiked and ballroom danced and tended a community garden and worked on my 1973 Porsche 914 through Santa Barbara High School’s vocational auto-shop. But I wore a lot of cargo shorts, I didn’t drink or party, and I mainly loaded up on math and writing courses and worked in the campus library’s Map and Imagery Lab pulling and shelving topos and ortho photos. Santa Barbara!

My internship interview was with a local military contractor that was creating sensor fusion software. I thought it was pretty cool because it was maps and spatial and lined up with my honors research project, using statistical sensing methods to probe physical topologies, albeit of knotted proteins, not the Middle East. Also, I had not yet untangled for myself the distinctions between patriotic service and imperial militarism. I was 21 and it was 2004.

I don’t remember a lot of the details of the interview. There was a primary interviewer who was maybe a year or two graduated from UCSB himself. He walked me around between cubicles I was given the chance to briefly chat with various people, including the CEO. At the end, we sat down for more formal chatting, and he said something like:

“You know, we don’t like to work very hard around here. Do you?”

And me, just trying to fit in, was like “Oh yeah, me too. I try to take it easy.”

Ded. I was declined. I’ll never know if that was a trick question, or like they knew I was not actually a good fit. But it was fine. I took another writing class.

“Code is our craft”

It was 2012, and my Code for America Fellowship was coming to an end. Having moved the previous year from Boston to the Bay Area for the fellowship, I now retooled my resume to downplay my decade-ish career of “community media and technology leadership” and instead highlight my “web applications and freelance software development” experience. I was trying to land my first official Software Engineering job.

There were a number of companies in Code for America’s orbit, so multiple fellows were interviewing at the same place. Us fellows were more collegial than competitive, so there was lots of helpful backchanneling and suggestions and level-setting that some of the jobs were faintly ridiculous, but sure, why not. It was the Bay Area in 2012.

I got a face-to-face interview with a company that I’ll vaguely describe as “a social network for baristas”. It was a Javascript company. There was a tech-screener project I apparently passed, so I came into the office. I can say this, with more hindsight and experience: there were some red flags.

  • I was introduced to the lead engineer and we chatted for a minute. I asked them something like “How do you see the business growing? I mean, where do you think the value lies in the product?” This was the wrong question for them. The lead engineer explained that “Code is our craft” and that well, who knows what the future will bring, but they want people who really are interested in the software.
  • One portion of the interview was reviewing my tech screener project. There was one part of the screener where I was unsure of the situationally best way to accomplish it, so I did the most direct unoptimized way and left some comments about different optimizations and their pros/cons. I was asked about why I hadn’t just picked one, and I explained that I wanted to treat this like real life and talk through it with a more experienced colleague who could represent the actual business needs and not prematurely optimize at the expense of readability and openness to change. That was the wrong answer for them. They explained that “Code is our craft” and they’d expect me to make the best call on my own.

I was declined. I want to admit that I did mostly fail a different part of the technical interview: it was a whiteboarding exercise along the lines of “solve this problem using only pipes”. I think everything may have been built with pipes, but it was Javascript in 2012, so I probably should have known how to do it to be qualified.

Sidenote: Huge props and respect that the company successfully socialized and operationalized a core company value. Even if I think it’s dumb.

“Focused on the code”

This was 2016, my professional circumstances were different, and I want to assert that I had become a real catch of an engineer. I was leading a fullstack web UI and CLI team at a B2B platform-infrastructure startup, and also moonlight solopreneuring a successful consumer web and cross-platform mobile native app too. Professionally, maybe, kind of, a big deal 💅

I was courted. I was reached out to over LinkedIn by someone I had only known of to that point. We got coffee and walked around San Francisco and they shared their vision. They invited me, and several other engineers, some of who I also knew of to a fancy private dinner. It was nice.

And there was a standard interview too. We talked about developing high-performant, early-adopter, power-user consumer interfaces, and our shared history and respect for Ruby and Rails and Javascript. We pair programmed on a problem, and I think I was nailing it.

And then there was a question, like “Ben, I know that you’ve been a manager in the past, and you’re currently leading a team. Is that something you really want to do in your next job?”

I replied saying something like “I’m happy being an IC. And I think a strength is my flexibility to help where it’s needed. If that’s what you and the business and the team eventually need, I’d feel confident and comfortable stepping into that role again.”

That was the wrong answer for them. I was declined. I received a reply later saying they wanted someone “focused on the code.” This is one time when I do wonder if I should have like, followed up and clarified my message, but interviewing is like bizarro-world dating so who knows.

Sidenote: If you’re reading this as flat advice, you should follow-up, because the worst that will happen is they’ll say “still a no”.

“Should we go back in there?”

In this story I was one of two technical interviewers, along with a hiring manager and the director of engineering.

We were debriefing after a week of interviewing candidates. There were two finalists. None of this may have actually mattered, or everything mattered, but I want to paint the picture. Both engineering candidates were women; we were all men along with the entire engineering team of 15 or so; not great!

  • Candidate 1 was very outgoing, had a ton of analogous Bay Area tech experience, lots in common to talk about… and did not pass our technical interviews.
  • Candidate 2 was a kinda awkward, their experience was weakly adjacent sorta kinda… and they totally aced the technical interviews, like finished in half the time then schooled us. Which made it even more awkward because we’re all awkward engineers truly and now we had like 30 minutes of dead time to fill trying to chitchat. I heard something similar happened in the manager interviews: the candidate answered too succinctly.

Ok, so the debrief. We went around the table, shared our experiences. And Management wanted to hire Candidate 1, the candidate that didn’t pass our technical interviews. For real! But this is business, and we have to be collegial, and they’re the managers, so my other engineering colleague and I disagreed and committed and rolled our eyes but left the meeting like yep, this is business, we’re all business here.

And we were walking down the hallway back to our desks and we both said to each other at the same time “What the fuck was that?”

“Should we go back in there?”

“That wasn’t right.”

So we kind of treaded water out in the hall for a minute, and worked up the courage to… gently go back and knock on the conference room door and politely ask if we could say one more thing.

“We should hire Candidate 2.” Seriously.

To management’s credit, they listened and I think correctly read that we were distressed and this wasn’t just our standard grumpy-engineer bikeshedding bit. Management agreed to make an offer to Candidate 2. Mission accomplished.

Ok, so I want to say there are two possible futures here:

  1. We hire Candidate 2, and they are a solid if unremarkable engineer. They do good work, meet and occassionally exceed expectations, and are an incremental contributor like everyone else in pushing out our startup’s runway toward some brighter future and shared equity event.
  2. We hire Candidate 2, and they are an absolute-based 100x engineer. They frankly save the company in my mind, bulldozing through any problem you throw their way with a nonchalant “alrighty then”. They exhaust the backlog leading them to entirely rewrite the product twice over better/faster/more-maintainably as a distraction while the backlog is rebuilt then they plow through it again.

It does not matter which future actually happened (though one of them definitely did!), because they were qualified, capable, and if we removed the fucking bias of our otherwise reasonably designed interview loop, the best candidate in our pool.

In the previous story when I played the role as befuddled candidate I was like “I dunno, bizarro dating”; but if you are ever in the position as an interviewer and there are some bogus soft-no’s or bogus soft-yes’s, speak the fuck up and use your power to the extent you safely can. Seriously, you can do this, even in business.

“What the fuck are you talking about?”: The story of NodeTiles

NodeTiles' trippy demo image that says "NODTILES" written across a map ofthe globe

I recently lost access to my 10-year old Code for America email address when I changed jobs. I tried to preserve some of the good stuff and this is one story.

During my time as a Code for America Fellow in 2012, I created a Javascript-based slippy map tile renderer called NodeTiles (kinda sorta like Mapnik). Several colleagues helped vastly expand it, we presented at NACIS, and I know of at least one successful company that is still powered by forked version of it today.

Jessica

During our Fellowship, Jessica Lord gave a tech talk on building custom map tiles and first introduced me to TileMill. I couldn’t find a record in my email of when that happened, but know she planted this seed 🌱

Tom

On April 25, 2012, I sent this email to Tom Carden:

This week I came across a gist of yours and eventually made my way to nodemap while researching how to generate server-side map tiles. Thank you so much for putting those pieces together; they’re fantastic! I matched your code with node-canvas-heroku to get it running in the cloud and it’s pretty fantastic:

http://morning-spring-2292.herokuapp.com/

Anyways, just wanted to send you a big thanks for the code and inspiration. I’m working on building a node-based utfgrid renderer to bootstrap an entire wax interaction layer… all without Mapnik (though maybe I should just work on packaging that for Heroku).

Cheers,
Ben

Tom gave some helpful advice and caveat emptor about JS performance and data caching. He continued to follow up with node-canvas and cairo suggestions for getting stuff running on Heroku. Tom ended up being a Code for America mentor for a different project and he was the source of us using the Toner map style in demos and also a nice leaflet clustering plugin.

Rob

Rob Brackett was the first person I explained what I was doing to create a tile render in Javascript. His reaction to my explanation was “What the fuck are you talking about?” Rob is one of my best friends, and I don’t remember how I explained what would become Nodeiles initially, but I’m sure it took 20 minutes and was a non-linear train of thought.

On May 2, 2012, I sent this email to “Fuzz”, Code for America’s random-nerdsnipe list:

Last week Rob and I built a heroku-compatible map-tile renderer (and UTFGrid generator) that can quickly (and with low bandwidth/client-processing) serve interactive maps and markers comprising tens of thousands of points and polygons—and unlike TileMill, the final map can be connected to a live database and updated on-the-fly. It’s kind’ve badass.

Here are 2 examples:

  1. Static map of San Francisco streets and Parks:  http://morning-spring-2292.herokuapp.com/

  2. Map of all ~1.5k Occupy sites worldwide (I did this in about 15min, so it’s a little clunky): http://occupy-map.herokuapp.com/

In terms of why it’s badass (from less to more geeky):

  1. It’s fast. Nothing is rendered in the browser, instead all of the tiles are rendered and streamed to the browser as PNGs.
  2. It’s small. No shapefiles are sent to the browser. Each Map (the entire initial pageload) is less than 500kb.
  3. It can do dynamic data. TileMill makes beautiful maps, but once you export them to MapBox (or your own mbtile server), you can’t change them. This can be hooked up to a live database (right now it parses geojson).
  4. It runs on Heroku. It uses node-canvas (not Mapnik) so it is fast, lightweight and has few dependencies.
  5. It renders UTFGrids, which can provide mouse-hovers and other straightforward UI stuff that most maps don’t (way less clicky)
  6. It’s not a tileserver, it’s a tile renderer. Seriously, all those maptiles are being generated on on-the-fly (we should probably cache them, but hey, this is bleeding edge)
  7. It’s nodejs and all the code is on Github:  https://github.com/bensheldon/nodetiles  

I’m still working on it, so if you have a big dataset that you’ve had trouble mapping before, let me know since I’m looking for more/better use cases.

Prashant

Prashant Singh, another Code for America fellow, was excited about the project and gave me lots of feedback. Prashant was using my project to generate large static maps from the commandline, and he gave some feedback on his experience doing similar work with Mapnik. Prashant and two other Fellows, Alicia Rouault and Matt Hampel, would subsequently build a business on top of it.

On June 5, 2012 I sent this email to Eric Gundersen at Mapbox:

I haven’t done a big writeup yet. I’m hoping to submit to NACIS for their October conference, but I’m still trying to clean up the code, modularize it, and write tests and documentation.

General backstory: I had been playing around a lot with TileMill and Mapnik and trying to programmatically generate map tiles; at CfA we have a lot of big, dynamic data and I was trying to set up an automated tile renderer. Then I came across a Tom Carden project where he was use Node-Canvas to render tiles… and then I discovered a node-canvas module that would run on Heroku… and by that point I was in love with the idea of a low-dependency (compared to mapnik) on-the-fly tile rendering implementation.

From there, I wanted to see how close I could get to a full-blown TileJSON implementation. I had my coworker Rob Brackett write me a Javascript UTFGrid implementation and I hooked that up to the tile rasterizer. And bam. It’s clunky as hell, and sort’ve slow (it’s rendering an entire shapefile then cropping it down for every tile rather than spatially indexing the features), but I think it has potential. 

I think the next step (in addition to cleanup and documentation) is loading up some OSM metro data and actually seeing how the performance compares to Mapnik. Also, while I can’t foresee implementing something like Cascadenik, node-canvas gives you direct access to the graphics renderer and it might be useful for creating boutique maps with graphical flourishes that Mapnik hasn’t implemented… and of course for creating layers with dynamic data.

Let me know if you have any specific questions or ideas you’d like me to try to implement or use as demos. Thanks for the interest!

Alex

Alex Yule, another Code for America Fellow, and an actual experienced cartographer, was also interested. Alex would build a proper database adapter layer and the actual spatial indexing functionality that all of my previous emails yolo. Alex joined Rob and my presentation proposal at NACIS. This was our abstract:

NodeTiles: Joyful Map Tile Rendering with Node.js

Mapnik has become the de facto open-source standard for rendering map tiles. While Mapnik is extremely powerful, it can be difficult to set up and deploy. We present NodeTiles, a lightweight, JavaScript-based, open-source map tile renderer that is easy to deploy, use, and extend. Built to support applications with dynamic data, NodeTiles offers an accessible and cloud-friendly alternative to Mapnik. While still in early-stage development, features on the road-map include styling with the CSS-based Carto language for compatibility with MapBox TileMill, UTFGrid generation for client-side interactivity, and data adaptors for PostGIS and Shapefiles.

NACIS

The NACIS (North American Cartographic Information Society) conference was October 17-19, 2012 in Portland, Oregon. Alex and Rob and I had gotten an AirBnB and I mostly remember us doing a lot of last-minute implementing. Alex built a really nice Postgres Adapter plugin and Rob was reimplementing Cascadenik (“CSS for Maps”) somewhere between Javascript and Cairo; there was a deep-dive into blitting. We presented at a breakout called “Slippy Maps”.

Afterwards, I remember riding BART back from the airport when we arrived home in San Francisco. I was talking with a maybe-a-big-deal person from the map-tech community, and they asked me something pointed like “But how much did you really contribute to NodeTiles?” I said something like “It was a team effort” and then it got really quiet. In hindsight that was probably a job interview. And also fuck that, it was a team effort.

That’s it

During Fall of 2012 Code for America Fellowship was ending and interviewing as an inexperienced engineer is freaking hard (and also incredibly dumb, but those are different stories). So I mostly put down NodeTiles. And also:

  • Going from something that’s a tech demo to something understandable (“What the fuck are you talking about”) and usable by outsiders is hard.
  • The sheer difficulty of spatial work. That dumb NodeTiles logo took me hours just to get the tooling together to just like, draw straight lines on a globe to say “NODETILES”.
  • Maps are a commodity, and also if you need to dynamically map a billion+ polyons (I’ve been informed that today there is Postgres MVT) and you need a pipeline for auth and anti-scrape and billing and raster and…. well, god bless you.
  • I leaned into some questionable architectural decisions to make NodeTiles more Javascripty, splitting up the front and backends, and modularizing all the different pieces into their own packages. In hindsight that was a lot of valueless work that only introduced friction into building the tool and delivering the value. That’s on me; never forget.
  • Given that this is an email-based retrospective, I will admit I found some emails from kinda big deals like Stamen that I didn’t respond to. I dunno why I didn’t respond; probably burnout. If that was you, it wasn’t personal, and I’m happy with the path I’ve taken, and I hope you are too 🤗

NodeTiles is still up on GitHub. If you can get node-canvas linking to cairo (memories of this seems like a fever dream), NodeTiles is really cool. Maybe you’ll do something neat with Nodetiles ❤️


Newer posts Older posts