Podcasts about stephanie oh

  • 13PODCASTS
  • 145EPISODES
  • 42mAVG DURATION
  • 1MONTHLY NEW EPISODE
  • Sep 10, 2024LATEST

POPULARITY

20172018201920202021202220232024


Best podcasts about stephanie oh

Latest podcast episodes about stephanie oh

An Interview with Melissa Llarena
247: Entreprenista Co-Founder Stephanie Cartin: Communities for Business Growth This Fall! (Hot Off the Press News! Join Melissa on Sept 23rd for a FREE LIVE Masterclass: Master Networking for Business Growth without Burnout!)

An Interview with Melissa Llarena

Play Episode Listen Later Sep 10, 2024 33:11


The Bike Shed
431: Developers Are Professional Question Askers

The Bike Shed

Play Episode Listen Later Jul 2, 2024 38:54


Stephanie shares her newfound interest in naming conventions, highlighting a resource called "Classnames" that provides valuable names for programming and design. Joël, in turn, talks about using AI to generate names for D&D characters, emphasizing how AI can help provide inspiration and reasoning behind name suggestions. Then, they shift to Joël's interest in Roman history, where he discusses a blog by a Roman historian that explores distinctions between state and non-state peoples in the ancient Mediterranean. Together, the hosts delve into the importance of asking questions as consultants and developers to understand workflows, question assumptions, and build trust for better onboarding. Stephanie categorizes questions by engagement stages and their social and technical aspects, while Joël highlights how questioning reveals implicit assumptions and speeds up learning. They stress maintaining a curious mindset, using questions during PR reviews, and working with junior developers to foster collaboration. They conclude with advice on documenting answers and using questions for continuous improvement and effective decision-making in development teams. Class names inspiration (https://classnames.paulrobertlloyd.com/) How to Raise a Tribal Army in Pre-Roman Europe, Part II: Government Without States (https://acoup.blog/2024/06/14/collections-how-to-raise-a-tribal-army-in-pre-roman-europe-part-ii-government-without-states/) Diocletian, Constantine, Bedouin Sayings, and Network Defense (https://www.youtube.com/watch?v=qCUI5ryyMSE) The Power of Being New: A Proven Recipe for High Impact (https://hazelweakly.me/blog/the-power-of-being-new--a-proven-recipe-for-high-impact/#the-power-of-being-new-a-proven-recipe-for-high-impact) How to ask good questions (https://jvns.ca/blog/good-questions/) Transcript:  JOËL: Hello and welcome to another episode of the Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Joël Quenneville. STEPHANIE: And I'm Stephanie Minn. And together, we're here to share a bit of what we've learned along the way. JOËL: So, Stephanie, what's new in your world? STEPHANIE: So, if it has not been clear about just kind of the things I'm mentioning on the podcast the past few weeks, I've been obsessed with naming things lately [chuckles] and just thinking about how to name things, and, yeah, just really excited about...or even just having fun with that more than I used to be as a dev. And I found a really cool resource called "Classnames." Well, it's like just a little website that a designer and developer shared from kind of as an offshoot from his personal website. I'll link it in the show notes. But it's basically just a list of common names that are very useful for programming or even design. It's just to help you find some inspiration when you're stuck trying to find a name for something. And they're general or abstract enough that, you know, it's almost like kind of like a design pattern but a naming pattern [laughs], I suppose. JOËL: Ooh. STEPHANIE: Yeah, right? And so, there's different categories. Like, here's a bunch of words that kind of describe collections. So, if you need to find the name for a containment or a group of things, here's a bunch of kind of words in the English language that might be inspiring. And then, there's also other categories like music for describing kind of the pace or arrangement of things. Fashion, words from fashion can describe, like, the size of things. You know, we talk about T-shirt sizes when we are estimating work. And yeah, I thought it was really cool that there's both things that draw on, you know, domains that most people know in real life, and then also things that are a little more abstract. But yeah, "Classnames" by Paul Robert Lloyd — that's been a fun little resource for me lately. JOËL: Very cool. Have you ever played around at all with using AI to help you come up with the naming? STEPHANIE: I have not. But I know that you and other people in my world have been enjoying using AI for inspiration when they feel a little bit stuck on something and kind of asking like, "Oh, like, how could I name something that is, like, a group of things?" or, you know, a prompt like that. I suspect that that would also be very helpful. JOËL: I've been having fun using that to help me come up with good names for D&D characters, and sometimes they're a little bit on the nose. But if I sort of describe my character, and what's their vibe, and a little bit of, like, what they do and their background, and, like, I've built this whole, like, persona, and then, I just ask the AI, "Hey, what might be some good names for this?" And the AI will give me a bunch of names along with some reasoning for why they think that would be a good match. So, it might be like, oh, you know, the person's name is, I don't know, Starfighter because it evokes their connection to the night sky or whatever because that was a thing that I put in the background. And so, it's really interesting. And sometimes they're, like, just a little too obvious. Like, you don't want, you know, Joe Fighter because he's a fighter. STEPHANIE: And his name is Joe [laughs]. JOËL: Yeah, but some of them are pretty good. STEPHANIE: Cool. Joël, what's new in your world? JOËL: I guess in this episode of how often does Joël think about the Roman Empire... STEPHANIE: Oh my gosh [laughs]. JOËL: Yes [laughs]. STEPHANIE: Spoiler: it's every day [laughs]. JOËL: Whaaat? There's a blog that I enjoy reading from a Roman historian. It's called "A Collection of Unmitigated Pedantry", acoup.blog. He's recently been doing an article series on not the Romans, but rather some of these different societies that are around them, and talking a little bit about a distinction that he calls sort of non-state peoples versus states in the ancient Mediterranean. And what exactly is that distinction? Why does it matter? And those are terms I've heard thrown around, but I've never really, like, understood them. And so, he's, like, digging into a thing that I've had a question about for a while that I've been really appreciating. STEPHANIE: Can you give, like, the reader's digest for me? JOËL: For him, it's about who has the ability to wield violence legitimately. In a state, sort of the state has a monopoly on violence. Whereas in non-state organizations, oftentimes, it's much more personal, so you might have very different sort of nobles or big men who are able to raise, let's say, private armies and wage private war on each other, and that's not seen as, like, some, like, big breakdown of society. It's a legitimate use of force. It's just accepted that that's how society runs. As opposed to in a state, if a, you know, wealthy person decided to raise a private army, that would be seen as a big problem, and the state would either try to put you down or, like, more generally, society would, like, see you as having sort of crossed a line you shouldn't have crossed. STEPHANIE: Hmm, cool. I've been reading a lot of medieval fantasy lately, so this is kind of tickling my brain in that way when I think about, like, what drives different characters to do things, and kind of what the consequences of those things are. JOËL: Right. I think it would be really fascinating to sort of project this framework forwards and look at the European medieval period through that lens. It seems to me that, at least from a basic understanding, that the sort of feudal system seems to be very much in that sort of non-state category. So, I'd be really interested to see sort of a deeper analysis of that. And, you know, maybe he'll do an addendum to this series. Right now, he's mostly looking at the Gauls, the Celtiberians, and the Germanic tribes during the period of the Roman Republic. STEPHANIE: Cool. Okay. Well, I also await the day when you somehow figure how this relates to software [laughter] and inevitably make some mind-blowing connection and do a talk about it [laughs]. JOËL: I mean, theming is always fun. There's a talk that I saw years ago at Strange Loop that was looking at the defense policy of the Roman Emperor Diocletian and the Roman Emperor Constantine, and the ways that they sort of defended the borders of the empire and how they're very different, and then related it to how you might handle network security. STEPHANIE: Whaat? JOËL: And sort of like a, hey, are we using more of a Diocletian approach here, or are we using more of a Constantine approach here? And all of a sudden, just, like, having those labels to put on there and those stories that went with it made, like, what could be a really, like, dry security talk into something that I still remember 10 years later. STEPHANIE: Yeah. Yeah. We love stories. They're memorable. JOËL: So, I'll make sure to link that in the show notes. STEPHANIE: Very cool. JOËL: We've been talking a lot recently about my personal note system, where I keep a bunch of, like, small atomic notes that are all usually based around a single thesis statement. And I was going through that recently, and I found one that was kind of a little bit juicy. So, the thesis is that consultants are professional question-askers. And I'm curious, as a consultant yourself, how do you feel about that idea? STEPHANIE: Well, my first thought would be, how do I get paid to only ask in questions [laughs] or how to communicate in questions and not do anything else [laughs]? It's almost like I'm sure that there is some, like, fantasy character, you know, where it's like, there's some villain or just obstacle where you have this monster character who only talks in questions. And it's like a riddle that you have to solve [laughs] in order to get past. JOËL: I think it's called a three-year-old. STEPHANIE: Wow. Okay. Maybe a three-year-old can do my job then [laughter]. But I do think it's a juicy one, and it's very...I can't wait to hear how you got there, but I think my reaction is yes, like, I do be asking questions [laughs] when I join a project on a client team. And I was trying to separate, like, what kinds of questions I ask. And I kind of came away with a few different categories depending on, like, the stage of the engagement I'm in. But, you know, when I first join a team and when I'm first starting out consulting for a team, I feel like I just ask a lot of basic questions. Like, "Where's the Jira board [laughs]?" Like, "How do you do deployments here?" Like, "What kind of Git process do you use?" So, I don't know if those are necessarily the interesting ones. But I think one thing that has been nice is being a consultant has kind of stripped the fear of asking those questions because, I don't know, these are just things I need to know to do my work. And, like, I'm not as worried about, like, looking dumb or anything like that [laughs]. JOËL: Yeah. I think there's often a fear that asking questions might make you look incompetent or maybe will sort of undermine your appearance of knowing what you're talking about, and I think I've found that to be sort of the opposite. Asking a lot of questions can build more trust, both because it forces people to think about things that maybe they didn't think about, bring to light sort of implicit assumptions that everyone has, and also because it helps you to ramp up much more quickly and to be productive in a way that people really appreciate. STEPHANIE: Yeah. And I also think that putting those things in, like, a public and, like, documented space helps people in the future too, right? At least I am a power Slack searcher [laughs]. And whenever I am onboarding somewhere, one of the first places I go is just to search in Slack and see if someone has asked this question before. I think the next kind of category of question that I discerned was just, like, questions to understand how the team understands things. So, it's purely just to, like, absorb kind of like perspective or, like, a worldview this team has about their codebase, or their work, or whatever. So, I think those questions manifest as just like, "Oh, like, you know, I am curious, like, what do you think about how healthy your codebase is? Or what kinds of bugs is your team, like, dealing with?" Just trying to get a better understanding of like, what are the challenges that this team is facing in their own words, especially before I even start to form my own opinions. Well, okay, to be honest, I probably am forming my own opinions, like, on the side [laughs], but I really try hard to not let that be the driver of how I'm showing up and especially in the first month I'm starting on a new team. JOËL: Would you say these sorts of questions are more around sort of social organization or, like, how a team approaches work, that sort of thing? Or do you classify more technical questions in this category? So, like, "Hey, tell me a little bit about your philosophy around testing." Or we talked in a recent episode "What value do you feel you get out of testing?" as a question to ask before even, like, digging into the implementation. STEPHANIE: Yeah, I think these questions, for me, sit at, like, the intersection of both social organization and technical questions because, you know, asking something like, "What's the value of testing for your team?" That will probably give me information about how their test suite is like, right? Like, what kinds of tests they are writing and kind of the quality of them maybe. And it also tells me about, yeah, like, maybe the reasons why, like, they only have just unit tests or maybe, like, just [inaudible 12:31] test, or whatever. And I think all of that is helpful information. And then, that's actually a really...I like the distinction you made because I feel like then the last category of questions that I'll mention, for now, feels like more geared towards technical, especially the questions I ask to debunk assumptions that might be held by the team. And I feel like that's like kind of the last...the evolution of my question-asking. Because I have, hopefully, like, really absorbed, like, why, you know, people think the way they do about some of these, you know, about their code and start to poke a little bit on being like, "Why do you think, you know, like, this problem space has to be modeled this way?" And that has served me well as a consultant because, you know, once you've been at an organization for a while, like, you start to take a lot of things for granted about just having to always be this way, you know, it's like, things just are the way they are. And part of the power of, you know, being this kind of, like, external observer is starting to kind of just like, yeah, be able to question that. And, you know, at the end of day, like, we choose not to change something, but I think it's very powerful to be able to at least, like, open up that conversation. JOËL: Right. And sometimes you open up that conversation, and what you get is a link to a big PR discussion or a Wiki or something where that discussion has already been had. And then, that's good for you and probably good for anybody else who has that question as well. STEPHANIE: I'm curious, for you, though, like, this thesis statement, atomic note, did you have notes around it, or was it just, like, you dropped it in there [laughs]? JOËL: So, I have a few things, one is that when you come in as a consultant, and, you know, we're talking here about consultants because that's what we do. I think this is probably true for most people onboarding, especially for non-junior roles where you're coming in, and there's an assumption of expertise, but you need to onboard onto a project. This is just particularly relevant for us as consultants because we do this every six months instead of, you know, a senior developer who's doing this maybe every two to three years. So, the note that I have here is that when you're brought on, clients they expect expertise in a technology, something like Ruby on Rails or, you know, just the web environment in general. They don't expect you as a consultant to be an expert in their domain or their practices. And so, when you really engage with this sort of areas that are new by asking a lot of questions, that's the thing that's really valuable, especially if those questions are coming from a place of experience in other similar things. So, maybe asking some questions around testing strategies because you've seen three or four other ways that work or don't work or that have different trade-offs. Even asking about, "Hey, I see we went down a particular path, technically. Can you walk me through what were the trade-offs that we evaluated and why we decided this was the path that was valuable for us?" That's something that people really appreciate from outside experts. Because it shows that you've got experience in those trade-offs, that you've thought the deeper thoughts beyond just shipping the next ticket. And sometimes they've made the decisions without actually thinking through the trade-offs. And so, that can be an opening for a conversation of like, "Hey, well, we just went down this path because we saw a blog article that recommended this, or we just did this because it felt right. Talk us through the trade-offs." And now maybe you have a conversation on, "Hey, here are the trade-offs that you're doing. Let me know if this sounds right for your organization. If not, maybe you want to consider changing some things or tweaking your approach." And I think that is valuable sort of at the big level where you're thinking about how the team is structured, how different parts of work is done, the technical architecture, but it also is valuable at the small level as well. STEPHANIE: Yeah, 100%. There is a blog post I really like by Hazel Weakly, and it's called "The Power of Being New: A Proven Recipe for High Impact." And one thing that she says at the beginning that I really enjoy is that even though, like, whenever you start on a new team there's always that little bit of pressure of starting to deliver immediate value, right? But there's something really special about that period where no one expects you to do anything, like, super useful immediately [laughs]. And I feel like it is both a fleeting time and, you know, I'm excited to continue this conversation of, like, how to keep integrating that even after you're no longer new. But I like to use that time to just identify, while I have nothing really on my plate, like, things that might have just been overlooked or just people have gotten used to that sometimes is, honestly, like, can be a quick fix, right? Like, just, I don't know, deleting a piece of dead code that you're seeing is no longer used but just gets fallen off other people's plates. I really enjoy those first few weeks, and people are almost, like, always so appreciative, right? They're like, "Oh my gosh, I have been meaning to do that." Or like, "Great find." And these are things that, like I said, just get overlooked when you are, yeah, kind of busy with other things that now are your responsibility. JOËL: You're talking about, like, that feeling of can you add value in the, like, initial time that you join. And I think that sometimes it can be easy to think that, oh, the only value you can add is by, like, shipping code. I think that being sort of noisy and asking a lot of questions in Slack is often a great way to add value, especially at first. STEPHANIE: Yeah, agreed. JOËL: Ideally, I think you come in, and you don't sort of slide in under the radar as, like, a new person on the team. Like, you come in, and everybody knows you're there because you are, like, spamming the channel with questions on all sorts of things and getting people to either link you to resources they have or explaining different topics, especially anything domain-related. You know, you're coming in with an outside expertise in a technology. You are a complete new person at the business and the problem domain. And so, that's an area where you need to ask a lot of questions and ramp up quickly. STEPHANIE: Yes. I have a kind of side topic. I guess it's not a side topic. It's about asking questions, so it's relevant [laughs]. But one thing that I'm curious about is how do you approach kind of doing this in a place where question asking is not normalized and maybe other people are less comfortable with kind of people asking questions openly and in public? Like, how do you set yourself up to be able to ask questions in a way that doesn't lead to just, like, some just, like, suspicion or discomfort about, like, why you're asking those questions? JOËL: I think that's the beauty of the consultant title. When an organization brings in outside experts, they kind of expect you to ask questions. Or maybe it's not an explicit expectation, but when they see you asking a lot of questions, it sort of, I think, validates a lot of things that they expect about what an outside expert should be. So, asking a lot of questions of trying to understand your business, asking a lot of questions to try to understand the technical architecture, asking questions around, like, some subtle edge cases or trade-offs that were made in the technical architecture. These are all things that help clients feel like they're getting value for the money from an outside expert because that's what you want an outside expert to do is to help you question some of your assumptions, to be able to leverage their, like, general expertise in a technology by applying it to your specific situation. I've had situations where I'll ask, like, a very nuanced, deep technical question about, like, "Hey, so there's, like, this one weird edge case that I think could potentially happen. How do we, like, think through about this?" And one of the, like, more senior people on the team who built the initial codebase responded, like, almost, like, proud that I've discovered this, like, weird edge case, and being like, "Oh yeah, that was a thing that we did think about, and here's why. And it's really cool that, like, day one you're, like, just while reading through the code and were like, 'Oh, this thing,' because it took us, like, a month of thinking about it before we stumbled across that." So, it was a weird kind of fun interaction where as a new person rolling on, one of the more experienced devs in the codebase almost felt, like, proud of me for having found that. STEPHANIE: I like that, yeah. I feel like a lot of the time...it's like, it's so easy to ask questions to help people feel seen, to be like, "Oh yeah, like, I noticed this." And, you know, if you withhold any kind of, like, judgment about it when you ask the question, people are so willing to be like, yeah, like you said, like, "Oh, I'm glad you saw that." Or like, "Isn't that weird? Like, I was feeling, you know, I saw that, too." Or, like, it opens it up, I think, for building trust, which, again, like, I don't even think this is something that you necessarily need to be new to even do. But if at any point you feel like, you know, maybe your working relationship with someone could be better, right? To the point where you feel like you're, like, really on the same page, yeah, ask questions [laughs]. It can be that easy. JOËL: And I think what can be really nice is, in an environment where question asking is not normalized, coming in and doing that can help sort of provide a little bit of cover to other people who are feeling less comfortable or less safe doing that. So, maybe there's a lot of junior members on the team who are feeling not super confident in themselves and are afraid that asking questions might undermine their position in the company. But me coming in as a sort of senior consultant and asking a lot of those questions can then help normalize that as a thing because then they can look and say, "Oh, well he's asking all these questions. Maybe I can ask my question, and it'll be okay." STEPHANIE: I also wanted to talk about setting yourself up and asking questions to get a good answer, asking good questions to get useful answers. One thing that has worked really well for me in the past few months has been sharing why I'm asking the question. And I think this goes back to a little bit of what I was hinting at earlier. If the culture is not really used to people asking questions and that just being a thing that is normal, sharing a bit of intention can help, like, ease maybe some nervousness that people might feel. Especially as consultants, we also are in a bit of a, I don't know, like, there is some power dynamics occasionally where it's like, oh, like, the consultants are here. Like, what are they going to come in and change or, like, start, you know, doing to, quote, unquote, "improve", whatever, I don't know [laughs]. JOËL: Right, right. STEPHANIE: Yeah, that's the consultant archetype, I think. Anyway. JOËL: Just coming in and being like, "Oh, this is bad, and this is bad, and you're doing it wrong." STEPHANIE: [laughs] JOËL: Ooh, I would be ashamed if I was the author of this code. STEPHANIE: Yeah, my hot take is that that is a bad consultant [laughs]. But maybe I'll say, like, "I am looking for some examples of this pattern. Where can I find them [laughs]?" Or "I've noticed that the team is struggling with, like, this particular part of the codebase, and I am thinking about improving it. What are some of your biggest challenges, like, working with this, like, model?" something like that. And I think this also goes back to, like, proving value, right? Even if it's like, sometimes I know kind of what I want to do, and I'll try to be explicit about that. But even before I have, like, a clear action item, I might just say like, "I'm thinking about this," you know, to convey that, you know, I'm still in that information gathering stage, but the result of that will be useful to help me with whatever kind of comes out of it. JOËL: A lot of it is about, like, genuine curiosity and an amount of empathetic listening. Existing team knows a lot about both the code and the business. And as a consultant coming on or maybe even a more senior person onboarding onto a team, the existing team has so much that they can give you to help you be better at your job. STEPHANIE: I was also revisiting a really great blog post from Julia Evans about "How to Ask Good Questions." And this one is more geared towards asking technical questions that have, like, kind of a maybe more straightforward answer. But she included a few other strategies that I liked a lot. And, frankly, I feel like I want to be even better at finding the right time to ask questions [laughs] and finding the right person to ask those questions to. I definitely get in the habit of just kind of like, I don't know, I'll just put it out there and [laughs], hopefully, get some answers. But there are definitely ways, I think, that you can be more strategic, right? About identifying who might be the best person to provide the answers you're looking for. And I think another thing that I often have to balance in the consulting position is when to know when to, like, stop kind of asking the really big questions because we just don't have time [laughs]. JOËL: Right. You don't want to be asking questions in a way that's sort of undermining the product, or the decisions that are being made, or the work that has to get done. Ideally, the questions that you're asking are helping move the project forward in a positive way. Nobody likes the, you know, just asking kind of person. That person's annoying. STEPHANIE: Do you have an approach or any thoughts about like, once you get an answer, like, what do you do with that? Yeah, what happens then for you? JOËL: I guess there's a lot of different ways it can go. A potential way if it's just, like, an answer explained in Slack, is maybe saying, "We should document this." Or maybe even like, "Is this documented anywhere? If not, can I add that documentation somewhere?" And maybe that's, you know, a code comment that we want to add. Maybe that's an entry to the Wiki. Maybe that's updating the README. Maybe that's adding a test case. But converting that into something actionable can often be a really good follow-up. STEPHANIE: Yeah, I think that mitigates the just asking [laughs] thing that you were saying earlier, where it's like, you know, the goal isn't to ask questions to then make more work for other people, right? It's to ask questions so, hopefully, you're able to take that information and do something valuable with it. JOËL: Right. Sometimes it can be a sort of setup for follow-up questions. You get some information and you're like, okay, so, it looks like we do have a pattern for interacting with third-party APIs, but we're not using it consistently. Tell me a little bit about why that is. Is that a new pattern that we've introduced and we're trying to, like, get more buy-in from the team? Is this a pattern that we used to have, and we found out we didn't like it? So, we stopped using it, but we haven't found a replacement pattern that we like. And so, now we're just kind of...it's a free-for-all, and we're trying to figure it out. Maybe there's two competing patterns, and there is this, like, weird politics within the tech team where they're sort of using one or the other, and that's something I'm going to have to be careful to navigate. So, asking some of those follow-up questions and once you have a technical answer can yield a lot of really interesting information and then help you think about how you can be impactful on the organization. STEPHANIE: And that sounds like advice that's just true, you know, regardless of your role or how long you've been in it, don't you think? JOËL: I would say yes. If you've been in the role a long time, though, you're the person who has that sort of institutional history in your mind. You know that in 2022, we switched over from one framework to another. You know that we used to have this, like, very opinionated architect who mandated a particular pattern, and then we moved away from it. You know that we were all in on this big feature last summer that we released and then nobody used it, and then the business pivoted, but there's still aspects of it that are left around. Those are things that someone knew onboarding doesn't know and that, hopefully, they're asking questions that you can then answer. STEPHANIE: Have you been in the position where you have all that, like, institutional knowledge? And then, like, how do you maintain that sense of curiosity or just that sense of kind of, like, what you're talking about, that superpower that you get when you're new of being able to just, you know, kind of question why things are the way they are? JOËL: It's hard, right? We're talking about how do you keep that sort of almost like a beginner's mindset, in this case, maybe less of a, like, new coder mindset and more of a new hire mindset. It's something that I think is much more front of mind for me because I rotate onto new clients every, like, 6 to 12 months. And so, I don't have very long to get comfortable before I'm immediately thrown into, like, a new situation. But something that I like to do is to never sort of solely be in one role or the other, a sort of, like, experienced person helping others or the new person asking for help. Likely, you are not going to be the newest person on the team for long. Maybe you came on as a cohort and you've got a group of new people, all of whom are asking different questions. And maybe somebody is asking a question that you've asked before, that you've asked in a different channel or on a call with someone. Or maybe someone joins two weeks after you; you don't have deep institutional knowledge. But if you've been asking a lot of questions, you've been building a lot of that for yourself, and you have a little bit that you can share to the next person who knows even less than you do. And that's an approach that I took even as an apprentice developer. When I was, like, brand new to Rails and I was doing an internship, and another intern joined me a couple of weeks after, and I was like, "You know what? I barely know anything. But I know what an instance variable is. And I can help you write a controller action. Let's pair on that. We'll figure it out. And, you know, ask me another question next week. I might have more answers for you." So, I guess a little bit of paying it forward. STEPHANIE: Yeah, I really like that advice, though, of, like, switching up the role or, like, kind of what you're working on, just finding opportunities to practice that, you know, even if you have been somewhere for a long time. I think that is really interesting advice. And it's hard, too, right? Because that requires, like, doing something new, and doing something new can be hard [laughs]. But if you're, you know, aren't in a consultant role, where you're not rotating onto new projects every 6 to 12 months, that, I feel like, would be a good strategy to grow in that particular way. JOËL: And even if you're not switching companies or in a consulting situation, it's not uncommon to have people switch from one team to another within an organization. And new team might mean new dynamics. That team might be doing a slightly different approach to project management. Their part of the code might be structured slightly differently. They might be dealing with a part of the business domain that you're less familiar with. While that might not be entirely new to you because, you know, you know a little bit of the organization's DNA and you understand the organization's mission and their core product, there are definitely a lot of things that will be new to you, and asking those questions becomes important. STEPHANIE: I also have another kind of, I don't know, it's not even a strategy. It's just a funny thing that I do where, like, my memory is so poor that, like, even code I wrote, you know, a month ago, I'm like, oh, what was past Stephanie thinking here [laughs]? You know, questioning myself a little bit, right? And being willing to do that and recognizing that, like, I have information now that I didn't have in the past. And, like, can that be useful somehow? You know, it's like, the code I wrote a month ago is not set in stone. And I think that's one way I almost, like, practice that skill with myself [laughs]. And yeah, it has helped me combat that, like, things are the way they are mentality, which, generally, I think is a very big blocker [laughs] when it comes to software development, but that's a topic for another day [laughs]. JOËL: I like the idea of questioning yourself, and I think that's something that is a really valuable skill for all developers. I think it can come up in things like documentation. Let's say you're leaving a comment on a method, especially one that's a bit weird, being able to answer that "Why was this weird technical decision made?" Or maybe you do this in your PR description, or your commit message, or in any of the other places where you do this, not just sort of shipping the code as is, but trying to look at it from an outsider's eyes. And being like, what are the areas where they're going to, like, get a quizzical look and be like, "Why is this happening? Why did you make this choice?" Bonus points if you talked a little bit about the trade-offs that were decided on to say, "Hey, there were two different implementations available for this. I chose to take implementation A because I like this set of trade-offs better." That's gold. And, I guess, as a reviewer, if I'm seeing that in a PR, that's going to make my job a lot easier. STEPHANIE: Yes. Yeah, I never thought about it that way, but yeah, I guess I do kind of apply, you know, the things that I would kind of ask to other team members to myself sometimes. And that is...it's cool to hear that you really appreciate that because I always kind of just did it for myself [laughs], but yeah, I'm sure that it, like, is helpful for other people as well. JOËL: I guess you were asking what are ways that you can ask questions even when you are more established. And talking about these sorts of self-reflective questions in the context of review got me thinking that PRs are a great place to ask questions. They're great when you're a newcomer. One of the things I like to do when I'm new on a project is do a lot of PR reviews so I can just see the weird things that people are working on and ask a lot of questions about the patterns. STEPHANIE: Yep. Same here. JOËL: Do a lot of code reading. But that's a thing that you can keep doing and asking a lot of questions on PRs and not in a, like, trying to undermine what the person is doing, but, like, genuine questions, I think, is a great way to maintain that mindset. STEPHANIE: Yeah, yeah, agreed. And I think when I've seen it done well, it's like, you get to be engaged and involved with the rest of your team, right? And you kind of have a bit of an idea about what people are working on. But you're also kind of entrusting them with ownership of that work. Like, you don't need to be totally in the weeds and know exactly how every method works. But, you know, you can be curious about like, "Oh, like, what were you thinking about this?" Or like, "What about this pattern appeals to you?" And all of that information, I think, helps you become a better, like, especially a senior developer, but also just, like, a leader on the team, I think. JOËL: Yeah, especially the questions around like, "Oh, walk me through some of the trade-offs that you chose for this method." And, you know, for maybe a person who's more senior, that's great. They have an opportunity to, like, talk about the decisions they made and why. That's really useful information. For a more junior person, maybe they've never thought about it. They're like, "Oh, wait, there are trade-offs here?" and now that's a great learning opportunity for them. And you don't want to come at it from a place of judgment of like, oh, well, clearly, you know, you're a terrible developer because you didn't think about the performance implications of this method. But if you come at it from a place of, like, genuine curiosity and sort of assuming the best of people on the team and being willing to work alongside them, help them discover some new concepts...maybe they've never, like, interacted so much with performance trade-offs, and now you get to have a conversation. And they've learned a thing, and everybody wins. STEPHANIE: Yeah. And also, I think seeing people ask questions that way helps more junior folks also learn when to ask those kinds of questions, even if they don't know the answer, right? But maybe they start kind of pattern matching. Like, oh, like, there might be some other trade-offs to consider with this kind of code, but I don't know what they are yet. But now I know to at least start asking and find someone who can help me determine that. And when I've seen that, that has been always, like, just so cool because it's upskilling happening [laughs] in practice. JOËL: Exactly. I love that phrase that you said: "Asking questions where you don't know the answers," which I think is the opposite of what lawyers are taught to do. I think lawyers the mantra they have is you never ask a witness a question that you don't know the answer to. But I like to flip that for developers. Ask a lot of questions on PRs where you don't know the answer, and you'll grow, and the author will grow. And this is true across experience levels. STEPHANIE: That's one of my favorite parts about being a developer, and maybe that's why I will never be a lawyer [laughter]. JOËL: On that note, I have a question maybe I do know the answer to. Shall we wrap up? STEPHANIE: Let's wrap up. Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeee!!!!!!! AD: Did you know thoughtbot has a referral program? If you introduce us to someone looking for a design or development partner, we will compensate you if they decide to work with us. More info on our website at: tbot.io/referral. Or you can email us at: referrals@thoughtbot.com with any questions.

The Bike Shed
430: Test Suite Pain & Anti-Patterns

The Bike Shed

Play Episode Listen Later Jun 25, 2024 40:57


Stephanie and Joël discuss the recent announcement of the call for proposals for RubyConf in November. Joël is working on his proposals and encouraging his colleagues at thoughtbot to participate, while Stephanie is excited about the conference being held in her hometown of Chicago! The conversation shifts to Stephanie's recent work, including completing a significant client project and her upcoming two-week refactoring assignment. She shares her enthusiasm for refactoring code to improve its structure and stability, even when it's not her own. Joël and Stephanie also discuss the everyday challenges of maintaining a test suite, such as slowness, flakiness, and excessive database requests. They discuss strategies to balance the test pyramid and adequately test critical paths. Finally, Joël emphasizes the importance of separating side effects from business logic to enhance testability and reduce complexity, and Stephanie highlights the need to address testing pain points and ensure tests add real value to the codebase. RubyConf CFP (https://sessionize.com/rubyconf-2024/) RubyConf CFP coaching (https://docs.google.com/forms/d/e/1FAIpQLScZxDFaHZg8ncQaOiq5tjX0IXvYmQrTfjzpKaM_Bnj5HHaNdw/viewform?pli=1) Testing pyramid (https://thoughtbot.com/blog/rails-test-types-and-the-testing-pyramid) Outside-in testing (https://thoughtbot.com/blog/testing-from-the-outsidein) Writing fewer system specs with request specs (https://thoughtbot.com/blog/faster-tests-with-capybara-and-request-specs) Unnecessary factories (https://thoughtbot.com/blog/speed-up-tests-by-selectively-avoiding-factory-bot) Your Test Suite is Making Too Many Database Calls (https://www.youtube.com/watch?v=LOlG4kqfwcg) Your flaky tests might be time dependent (https://thoughtbot.com/blog/your-flaky-tests-might-be-time-dependent) The Secret Ingredient: How To Understand and Resolve Just About Any Flaky Test (https://www.youtube.com/watch?v=De3-v54jrQo) Separating side effects to improve tests (https://thoughtbot.com/blog/simplify-tests-by-extracting-side-effects) Functional core, imperative shell (https://www.destroyallsoftware.com/screencasts/catalog/functional-core-imperative-shell) Thoughtbot testing articles (https://thoughtbot.com/blog/tags/testing) Transcript: STEPHANIE: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Stephanie Minn. JOËL: And I'm Joël Quenneville. And together, we're here to share a bit of what we've learned along the way. STEPHANIE: So, Joël, what's new in your world? JOËL: Something that's new in my world is that RubyConf just announced their call for proposals for RubyConf in November. They're open for...we're currently recording in June, and it's open through early July, and they're asking people everywhere to submit talk ideas. I have a few of my own that I'm working with. And then, I'm also trying to mobilize a lot of other colleagues at thoughtbot to get excited to submit. STEPHANIE: Yes, I am personally very excited about this year's RubyConf in November because it's in Chicago, where I live, so I have very little of an excuse not to go [laughs]. I feel like so much of my conference experience is traveling to just kind of, like, other cities in the U.S. that I want to spend some time in and, you know, seeing all of my friends from...my long-distance friends. And it definitely does feel like just a bit of an immersive week, right? And so, I wonder how weird it will feel to be going to this conference and then going home at the end of the night. Yeah, that's just something that I'm a bit curious about. So, yeah, I mean, I am very excited. I hope everyone comes to Chicago. It's a great city. JOËL: I think the pitch that I'm hearing is submit a proposal to the RubyConf CFP to get a chance to get a free ticket to go to RubyConf, where you get to meet Bike Shed co-host Stephanie Minn. STEPHANIE: Yes. Ruby Central should hire me to market this conference [laughter] and that being the main value add of going [laughs], obviously. Jokes aside, I'm excited for you to be doing this initiative again because it was so successful for RailsConf kind of internally at thoughtbot. I think a lot of people submitted proposals for the first time with some of the programming you put on. Are you thinking about doing things any differently from last time, or any new thoughts about this conference cycle? JOËL: I think I'm iterating on what we did last time but trying to keep more or less the same formula. Among other things, people don't always have ideas immediately of what they want to speak about. And so, I have a brainstorming session where we're just going to get together and brainstorm a bunch of topics that are free for anyone to take. And then, either someone can grab one of those topics and pitch a talk on it, or it can be, like, inspiration where they see that it jogs their mind, and they have an idea that then they go off and write a proposal. And so, that allows, I think, a lot of colleagues as well, who are maybe not interested in speaking but might have a lot of great ideas, to participate and sort of really get a lot of that energy going. And then, from there, people who are excited to speak about something can go on to maybe draft a proposal. And then, I've got a couple of other events where we support people in drafting a proposal and reviewing and submitting, things like that. STEPHANIE: Yes, I really love how you're just involving people with, you know, just different skills and interests to be able to support each other, even if, you know, there's someone on our team who's, like, not interested in speaking at all, but they're, like, an ideas person, right? And they would love to see their idea come to life in a talk from someone else. Like, I think that's really cool, and I certainly appreciate it as a not ideas person [laughs]. JOËL: Also, I want to shout out that Ruby Central is doing CFP coaching sessions on June 24th, June 25th, and June 26th, and those are open to anyone. You can sign up. We'll put a link to the signup form in the show notes. If you've never submitted something before and you'd like some tips on what makes for a good CFP, how can you up your chances of getting accepted, or maybe you've submitted before, you just want to get better at it; I recommend joining one of those slots. So, Stephanie, what's new in your world? STEPHANIE: So, I just successfully delivered a big project on my client work last week. So, I'm kind of riding that wave and getting into the next bit of work that I have been assigned for this team, and I'm really excited to do this. But I also, I don't know, I've been just, like, thinking about it quite a bit. Basically, I'm getting to spend two dedicated weeks to just refactoring [laughs] some really, I guess, complicated code that has led to some bugs recently and just needing some love, especially because there's some whiffs of potentially, like, really investing in this area of the product, and people wanting to make sure that the foundation does feel very stable to build on top of for extending and changing that code. And I think I, like, surprised myself by how excited I was to do this because it's not even code I wrote. You know, sometimes when you are the one who wrote code, you're like, oh, like, I would love time to just go back and clean up all these things that I kind of missed the first time around or just couldn't attend to for whatever reason. But yeah, I think I was just a little bit in the peripheries of that code, and I was like, oh, like, just seeing some weird stuff. And now to kind of have the time to be like, oh, this is all I'm going to be doing for two weeks, to, like, really dive into it and get my hands dirty [laughs], I'm very excited. JOËL: I think that refactoring is a thing that can be really fun. And also, when you have a larger chunk of time, like two days, it's easy to sort of get lost in sort of grand visions or projects. How do you kind of balance the, I want to do a lot of refactoring; I want to take on some bigger things while maybe trying to keep some focus or have some prioritization? STEPHANIE: Yeah, that's a great question. I was actually the one who said, like, "I want two weeks on this." And it also helped that, like, there was already some thoughts about, like, where they wanted to go with this area of the codebase and maybe what future features they were thinking about. And there are also a few bugs that I am fixing kind of related to this domain. So, I think that is actually what I started with. And that was really helpful in just kind of orienting myself in, like, the higher impact areas and the places that the pain is felt and exploring there first to, like, get a sense of what is going on here. Because I think that information gathering is really important to be able to kind of start changing the code towards what it wants to be and what other devs want it to be. I actually also started a thread in Slack for my team. I was, like, asking for input on what's the most confusing or, like, hard to reason about files or areas in this particular domain or feature set and got a lot of really good engagement. I was pleasantly surprised [laughs], you know, because sometimes you, like, ask for feedback and just crickets. But I think, for me, it was very affirming that I was, like, exploring something that a lot of people are like, oh, we would love for someone to, you know, have just time to get into this. And they all were really excited for me, too. So, that was pretty cool. JOËL: Interesting. So, it sounds like you sort of budgeted some refactoring time and then, from there, broke it down into a series of a couple of debugging projects and then a couple of, like, more bounded refactoring projects, where, like, specifically, I want to restructure the way this object works or something like that. STEPHANIE: Yeah. I think there was that feeling of wanting to clean up this area of the codebase, but you kind of caught on to that bit of, you know, it can go so many different ways. And, like, how do you balance your grand visions [laughs] of things with, I guess, a little bit of pragmatism? So, it was very much like, here's all these bugs that are causing our customers problems that are kind of, like, hard for the devs to troubleshoot. You know, that kind of prompts the question, like, why? And so, if there can be, you know, the fixing of the bugs, and then the learning of, like, how that part of the system works, and then, hopefully, some improvements along the way, yeah, that just felt like a dream [laughs] for me. And two weeks felt about the right amount of time. I don't know if anyone kind of hears that and feels like it's too long or too little. I would be really curious. But I feel like it is complex enough that, like, context switching would, I think, make this work harder, and you kind of do have to just sit with it for a little bit to get your bearings. JOËL: A scenario that we encounter on a pretty regular basis is a customer coming to us and telling us that they're feeling a lot of test pain and asking what are the ways that we can help them to make things better and that test pain can come under a lot of forms. It might be a test suite that's really slow and that's hurting the team in terms of their velocity. It might be a test suite that is really flaky. It might be one that is really difficult to add to, or maybe one that has very low coverage, or one that is just really brittle. Anytime you try to make a change to it, a bunch of things break, and it takes forever to ship anything. So, there's a lot of different aspects of challenging test suites that clients come to us with. I'm curious, Stephanie, what are some of the ones that you've encountered most frequently? STEPHANIE: I definitely think that a slow test suite and a flaky test suite end up going hand in hand a lot, or just a brittle one, right? That is slowing down development and, like you said, causing a lot of pain. I think even if that's not something that a client is coming to us directly about, it maybe gets, like, surfaced a little bit, you know, sometime into the engagement as something that I like to keep an eye on as a consultant. And I actually think, yeah, that's one of kind of the coolest things, I think, about our consulting work is just getting to see so many different test suites [laughs]. I don't know. I'm a testing nerd, so I love that kind of stuff. And then, I think you were also kind of touching on this idea of, like, maintaining a test suite and, yeah, making testing just a better experience. I have a theory [laughs], and I'd be curious to get your thoughts on it. But one thing that I really struggle with in the industry is when people talk about writing tests as if it's, like, the morally superior thing to do. And I struggle with this because I don't think that it is a very good strategy for helping people feel better or more confident and, like, upskill at writing tests. I think it kind of shames people a little bit who maybe either just haven't gotten that experience or, you know, just like, yeah, like, for whatever reason, are still learning how to do this thing. And then, I think that mindset leads to bad tests [laughs] or tests that aren't really serving the purpose that you hope they would because people are doing it more out of obligation rather than because they truly, like, feel like it adds something to their work. Okay, I kind of just dropped that on you [laughs]. Do you have any reactions? JOËL: Yeah, I guess the idea that you're just checking a box with your test rather than writing code that adds value to the codebase. They're two very different perspectives that, in the end, will generate more lines of code if you're just doing a checkbox but may or may not add a whole lot of value. So, maybe before even looking at actual, like, test practices, it's worth stepping back and asking more of a mindset question: Why does your team test? What is the value that your team feels they get out of testing? STEPHANIE: Yeah. Yeah. I like that because I was about to say they go hand in hand. But I do think that maybe there is some, you know, question asking [laughs] to be done because I do think people like to kind of talk about the testing practices before they've really considered that. And I am, like, pretty certain from just kind of, at least what I've seen, and what I've heard, and what I've experienced on embedding into client teams, that if your team can't answer that question of, like, "What value does testing bring?" then they probably aren't following good testing practices [laughs]. Because I do think you kind of need to approach it from a perspective of like, okay, like, I want to do this because it helps me, and it helps my team, rather than, like you said, getting the check mark. JOËL: So, once we've sort of established maybe a bit of a mindset or we've had a conversation with the team around what value they think they're getting out of tests, or maybe even you might need to sell the team a little bit on like, "Hey, here's, like, all these different ways that testing can bring value into your life, make your life as developers easier," but once you've done that sort of pre-work and you can start looking at what's actually the problem with a test suite, a common complaint from developers is that the test suite is too slow. How do you like to approach a slow test suite? STEPHANIE: That's a good question. I actually...I think there's a lot of ways to answer that. But to kind of stay on the theme of stepping back a little bit, I wonder if assessing how well your test suite aligns with the testing pyramid would be a good place to start; at least, that could be where I start if I'm coming into a client team for the first time, right, and being asked to start assessing or just poking around. Because I think the slowness a lot of the time comes from a lot of quote, unquote, "integration tests" or, like, unit tests masquerading as integration tests, where you end up having, like, a lot of duplication of things that are being tested in ways that are integrating with some slow parts of the system like the database. And yeah, I think even before getting into some of the more discreet reasons why you might be writing slow tests, just looking at the structure of your test suite and what kinds of things you're testing, and, again, even going back to your team and asking, like, "What kinds of things do you test?" Or like, "Do you try to test or wish to be testing more of, less of?" Like looking at the structure, I have found to be a good place to start. JOËL: And for those who are not familiar, you used the term testing pyramid. This is a concept which says that you probably want to have a lot of small, fast unit tests, a medium amount of integration tests that test a few different components together, and then a few end-to-end tests. Because as you go up that pyramid, tests become more expensive. They take a lot longer to run, whereas the little unit tests are super cheap. You can create thousands of them, and they will barely impact your run time. Adding a dozen end-to-end tests is going to be noticeable. So, you want to balance sort of the coverage that you get from end to end with the sort of cheapness and ubiquity of the little unit tests, and then split the difference for tests that are in between. STEPHANIE: And I think that is challenging, even, you know, you're talking about how you want the peak of your pyramid to be end-to-end tests. So, you don't want a lot of them, but you do want some of them to really ensure that things are totally plumbed and working correctly. But that does require, I think, really looking at your application and kind of identifying what features are the most critical to it. And I think that doesn't get paid enough attention, at least from a lot of my client experiences. Like, sometimes teams just end up with a lot of feature bloat and can't say like, you know, they say, "Everything's important [chuckles]," but everything can't be equally important, you know? JOËL: Right. I often like to develop using a sort of outside-in approach, where you start by writing an end-to-end test that describes the behavior that your new feature ticket is asking for and use that to drive the work that I'm doing. And that might lead to some lower-level unit tests as I'm building out different components, but the sort of high-level behavior that we're adding is driven by adding an end-to-end spec. Do you feel that having one new end-to-end spec for every new feature ticket that you work on is a reasonable thing to do, or do you kind of pick and choose? Do you write some, but maybe start, like, coalescing or culling them, or something like that? How do you manage that idea that maybe you would or would not want one end-to-end spec for each feature ticket? STEPHANIE: Yeah, it's a good question. Actually, as you were saying that, I was about to ask you, do you delete some afterwards [laughs]? Because I think that might be what I do sometimes, especially if I'm testing, you know, edge cases or writing, like, the end-to-end test for error states. Sometimes, not all of them make it into my, like, final, you know, commit. But they, you know, had their value, right? And at least it prompted me to make sure I thought about them and make sure that they were good error states, right? Like things that had visible UI to the user about what was going on in case of an error. So, I would say I will go back and kind of coalesce some of them, but they at least give me a place to start. Does that match your experience? JOËL: Yeah, I tend to mostly write end-to-end tests for happy paths and then write kind of mid-level things to cover some of my edge cases, maybe a couple of end-to-end tests for particularly critical paths. But, at some point, there's just too many paths through the app that you can't have end-to-end coverage for every single branch on every single path that can happen. STEPHANIE: Yeah, I like that because if you find yourself having a lot of different conditions that you need to test in an end-to-end situation, maybe there's room for that to, like, be better encapsulated in that, like, more, like, middle layer or, I don't know, even starting to ask questions about, like, does this make sense with the product? Like, having all of these different things going on, does that line up with kind of the vision of what this feature is trying to be or should be? Because I do think the complexity can start at that high of a level. JOËL: How do you feel about the idea that adding more end-to-end tests, at some point, has diminishing returns? STEPHANIE: I'm not quite sure I'm following [laughs]. JOËL: So, let's say you have an end-to-end test for the happy path for every core feature of the app. And you decide, you know what, I want to add maybe some, like, side features in, or maybe I want to have more error states. And you start, like, filling in more end-to-end tests for those. Is it fair to say that adding some of those is a bit of a diminishing return? Like, you're not getting as much value as you would from the original specs. And maybe as you keep finding more and more rare edge cases, you get less and less value for your test. STEPHANIE: Oh, yeah, I see. And there's more of a cost, too, right? The cost of the time to run, maintain, whatever. JOËL: Right. Let's say they're roughly all equally expensive in terms of cost to run. But as you stray further and further off of that happy path, you're getting less and less value from that integration test or that end-to-end test. STEPHANIE: I'm actually a little conflicted about this because that sounds right in theory, but then in practice, I feel like I've seen error states not get enough love [laughs] that it's...I don't even want to say, like, you make any kind of claim [laughs] about it. But, you know, if you're going to start somewhere, if you have, like, a limited amount of time and you're like, okay, I'm only going to write a handful of end-to-end tests, yeah, like, write tests for your happy paths [laughs]. JOËL: I guess it's probably fair to say that error states just don't get as much love as they should throughout the entire testing stack: at the unit level, at the integration level, all the way up to end to end. STEPHANIE: I'm curious if you were trying to get at some kind of conclusion, though, with the idea of diminishing returns. JOËL: I guess I'm wondering if, from there, we can talk about maybe a breakdown of a particular testing pyramid for a particular test suite is being top heavy, and whether there's value in maybe pushing some of these tests, some of these edge cases, some of these maybe less important features down from that, like, top end-to-end layer into maybe more of an integration layer. So, in a Rails context, that might be moving system specs down to something like a request spec. STEPHANIE: Yeah, I think that is what I tend to do. I'm trying to think of how I get there, and I'm not quite sure that I can explain it quite yet. Yeah, I don't know. Do you think you can help me out here? Like, how do you know it's time to start writing more tests for your unhappy paths lower on the pyramid? JOËL: Ideally, I think a lot of your code should be unit-tested. And when you are unit testing it, those pieces all need coverage of the happy and unhappy paths. I think the way it may often happen naturally is if you're pushing logic out of your controllers because it's a little bit challenging sometimes to test Rails controllers. And so, if you're moving things into domain objects, even service objects, depending on how you implement them, just doing that and then making sure you unit test them can give you a lot more coverage of all the different edge cases that can happen. Where things sometimes fall apart is getting out of that business layer into the web layer and saying, "Hey, if something raises an error or if the save fails or something like that, does the user get a good experience, or do we just crash and give them a 500 page?" STEPHANIE: Yeah, that matches with a lot of what I've seen, where if you then spend too much time in that business layer and only handling errors there, you don't really think too much about how it bubbles up. And, you know, then you are digging through, like, your error monitoring [laughs] service, trying to find out what happened so that you can tell, you know, your customer support team [laughs] to help them resolve, like, a bug report they got. But I actually think...and you were talking about outside in, but, in some ways, in my experience, I also get feedback from the bottom up sometimes that then ends up helping me adjust some of those integration or end-to-end tests about kind of what errors are possible, like, down in the depths of the code [laughs], and then finding ways to, you know, abstract that or, like, kind of be like, "Oh, like, here are all these possible, like, exceptions that might be raised." Like, what HTTP status code do I want to be returned to capture all of these things? And what do I want to say to the user? So, yeah, I'm [laughs] kind of a little lost myself, but this idea that going both, you know, outside in and then maybe even going back up a little bit has served me well before. JOËL: I think there can be a lot of value in sort of dropping down a level in the pyramid, and maybe instead of doing sort of end-to-end tests where you, like, trigger a scenario where something fails, you can just write a request back against the controller and say, "Hey, if I go to this controller and something raises an error, expect that you get redirected to this other location." And that's really cheap to run compared to an end-to-end test. And so, I think that, for me, is often the right compromise is handling error states at sort of the next lowest level and also in slightly more atomic pieces. So, more like, if you hit this endpoint and things go wrong, here's how things happen. And I use endpoint not so much in an API sense, although it could be, but just your, you know, maybe you've got a flow that's multiple steps where, you know, you can do a bunch of things. But I might have a test just for one controller action to say, "Hey, if things go wrong, it redirects you here, or it shows you this error page." Whereas the end-to-end test might say, "Oh, you're going to go through the entire flow that hits multiple different controllers, and the happy path is this nice chain." But each of the exit points off at where things fail would be covered by a more scoped request spec on that controller. STEPHANIE: Yeah. Yeah. That makes sense. I like that. JOËL: So, that's kind of how I've attempted to balance my pyramid in a way that balances complexity and time with coverage. You mentioned that another area that test suites get slow is making too many requests to the database. There's a lot of ways that that happens. Oftentimes, I think a classic is using a factory where you really don't need to, persisting data to the database when all you needed was some object in memory. So, there are different strategies for avoiding that. It's also easy to be creating too much data. So, maybe you do need to persist some things in the database, but you're persisting a hundred objects into memory or into the database when you really meant to persist two, so that's an easy accident. A couple of years ago, I gave a talk at RailsConf titled "Your Test Suite is Making Too Many Database Requests" that went over a bunch of different ways that you can be doing a lot of expensive database requests you didn't plan on making and how that slows down your test suite. So, that is also another hot spot that I like to look at when dealing with a slow test suite. STEPHANIE: Yeah, I mentioned earlier the idea of unit tests really masquerading as integration tests [laughs]. And I think that happens especially if you're starting with a class that may already be a little bit too big than it should be or have more responsibilities than it should be. And then, you are, like, either just, like, starting with using the create build, like, strategy with factories, or you find yourself, like, not being able to fully run the code path you're trying to test without having stuff persisted. Those are all, I think, like, test smells that, you know, are signaling a little bit of a testing anti-pattern that, yeah, like, is there a way to write, like, true unit tests for this stuff where you are only using objects in memory? And does that require breaking out some responsibilities? That is a lot of what I am kind of going through right now, actually, with my little refractoring project [laughs] is backfilling some tests, finding that I have to create a lot of records. And you know what? Like, the first step will probably be to write those tests and commit them, and just have them live there for a little while while I figure out, you know, the right places to start breaking things up, and that's okay. But yeah, I did want to, like, just mention that if you are having to create a lot of records and then also noticing, like, your test is running kind of slow [laughs], that could be a good indicator to just give a good, hard look at what kind of style of test you think you're writing [laughs]. JOËL: Yeah, your tests speak to you, and when you're feeling pain, oftentimes, it can be a sign that you should consider refactoring your implementation. And I think that's doubly true if you're writing tests after the fact rather than test driving. Because sometimes you sort of...you came up with an implementation that you thought would be good, and then you're writing tests for it, and it's really painful. And that might be telling you something about the underlying implementation that you have that maybe it's...you thought it's well scoped, but maybe it actually has more responsibilities than you initially realized, or maybe it's just really tightly coupled in a way that you didn't realize. And so, learning to listen to your tests and not just sort of accepting the world for being the way it is, but being like, "No, I can make it better." STEPHANIE: Yeah, I've been really curious why people have a hard time, like, recognizing that pain sometimes, or maybe believing that this is the way it is and that there's not a whole lot that you can do about it. But it's not true, like, testing really does not have to be painful. And I feel like, again, this is one of those things that's like, it's hard to believe until you really experience it, at least, that was the case for me. But if you're having a hard time with tests, it's not because you're not smart enough. Like, that, I think, is a thing that I really want to debunk right now [laughs] for anyone who has ever had that thought cross their mind. Yeah, things are just complicated and complex somehow, or software entropy happens. That's, like, not how it should be, and we don't have to accept that [laughs]. So, I really like what you said about, oh, you can change it. And, you know, that is a bit of a callback to the whole mindset of testing that we mentioned earlier at the beginning. JOËL: Speaking of test suites, we have not covered yet is paralyzing it. That could probably be its own Bike Shed episode on its own entirely on paralyzing a test suite. We've done entire engagements where our job was to come in and help paralyze a test suite, make it faster. And there's a lot of, like, pros and cons. So, I think maybe we can save that for a different episode. And, instead, I'd like to quickly jump in a little bit to some other common pain points of test suites, and I would say probably top of that list is test flakiness. How do you tend to approach flakiness in a client project? STEPHANIE: I am, like, laughing to myself a little bit because I know that I was dealing with test flakiness on my last client engagement, and that was, like, such a huge part of my day-to-day is, like, hitting that retry button. And now that I am on a project with, like, relatively low flakiness, I just haven't thought about it at all [laughs], which is such a privilege, I think [laughs]. But one of the first things to do is just start, like, capturing metrics around it. If you, you know, are hearing about flakiness or seeing that, like, start to plague your test suite or just, you know, cropping up in different ways, I have found it really useful to start, like, I don't know, just, like, maybe putting some of that information in a dashboard and seeing how, just to, like, even make sure that you are making improvements, that things are changing, and seeing if there's any, like, patterns around what's causing the flakiness because there are so many different causes of it. And I think it is pretty important to figure out, like, what kind of code you're writing or just trying to wrangle. That's, you know, maybe more likely to crop up as flakiness for your particular domain or application. Yeah, I'm going to stop there and see, like, because I know you have a lot of thoughts about flakiness [laughs]. JOËL: I mean, you mentioned that there's a lot of different causes for flakiness. And I think, in my experience, they often sort of group into, let's say, like, three different buckets. Anytime you're testing code that's doing things that are non-deterministic, that's easy for tests to be flaky. And so, you might think, oh, well, you know, you have something that makes a call to random, and then you're going to assert on a particular outcome of that. Well, clearly, that's going to not be the same every time, and that might be flaky. But there are, like, more subtle versions of that, so maybe you're relying on the system clock in some way. And, you know, depending on the time you run that test, it might give you a different value than you expect, and that might cause it to fail. And it doesn't have to be you're asserting on, like, oh, specifically a given millisecond. You might be doing math around, like, number of days, and when you get near to, let's say, the daylight savings boundary, all of a sudden, no, you're off by an hour, and your number of days...calculation breaks because relying on the clock is something that is inherently non-deterministic. Non-determinism is a bucket. Leaky tests is another bucket of failures that I see, things where one test might impact another that gets run after the fact, oftentimes by mutating some sort of global state. So, maybe you're both relying on some sort of, like, external file that you're both writing to or maybe a cache that one is writing to that the other one is reading from, something like that. It could even just be writing records into the database in a way that's not wrapped in a transaction, such that there's more data in the database when the next test runs than it expects. And then, finally, if you are doing any form of parallelization, that can improve your test suite speed, but it also potentially leads to race conditions, where if your resources aren't entirely isolated between parallel test runners, maybe you're sharing a database, maybe you're sharing Redis instance or whatever, then you can run into situations where you're both kind of fighting over the same resources or overriding each other's data, or things like that, in a way that can cause tests to fail intermittently. And I think having a framework like that of categorization can then help you think about potential solutions because debugging approaches and then solutions tend to be a little bit different for each of these buckets. STEPHANIE: Yeah, the buckets of different causes of flaky tests you were talking about, I think, also reminded me that, you know, some flakiness is caused by, like, your testing environment and your infrastructure. And other kinds of flakiness are maybe caused more from just the way that you've decided how your code should work, especially that, like, non-deterministic bucket. So, yeah, I don't know, that was just, like, something that I noticed as you were going through the different categories. And yeah, like, certainly, the solutions for approaching each kind are very different. JOËL: I would like to pitch a talk from RubyConf last year called "The Secret Ingredient: How To Resolve And Understand Just About Any Flaky Test" by Alan Ridlehoover. Just really excellent walkthrough of these different buckets and common debugging and solving approaches to each of them. And I think having that framework in mind is just a great way to approach different types of flaky tests. STEPHANIE: Yes, I'll plus one that talk, lots of great pictures of delicious croissants as well. JOËL: Very flaky pastry. STEPHANIE: [laughs] Joël, do you have any last testing anti-pattern guidances for our audience who might be feeling some test pain out there? JOËL: A quick list, I'm going to say tight coupling that has then led to having a lot of stubbing in your tests often leads to tests that are very brittle, so tests that maybe don't fail when they should when you've actually broken things, or maybe, alternatively, tests that are constantly failing for the wrong reasons. And so, that is a thing that you can fix by making your code less coupled. Tests that also require stubbing a lot of things because you do a lot of side effects. If you are making a lot of HTTP calls or things like that, that can both make a test more complex because it has to be aware of that. But also, it can make it more non-deterministic, more flaky, and it can just make it harder to change. And so, I have found that separating side effects from sort of business logic is often a great way to make your test suite much easier to work with. I have a blog post on that that I'll link in the show notes. And I think this maybe also approaches the idea of a functional core and an imperative shell, which I believe was an idea pitched by Gary Bernhardt, like, over ten years ago. There's a famous video on that that we'll also link in the show notes. But that architecture for building an app can lead to a much nicer test to write. I guess the general idea being that testing code that does side effects is complicated and painful. Testing code that is more functional tends to be much more pleasant. And so, by not intermingling the two, you tend to get nicer tests that are easier to maintain. STEPHANIE: That's really interesting. I've not heard that guidance before, but now I am intrigued. That reminded me of another thing that I had a conversation with someone about. Because after the RailsConf talk I gave, which was about testing pain, there was some stubbing involved in the examples that I was showing because I just see a lot of that stuff. And, you know, this audience member kind of had that question of, like, "How do you know that things are working correctly if you have to stub all this stuff out?" And, you know, sometimes you just have to for the time being [chuckles]. And I wanted to just kind of call back to that idea of having those end-to-end tests testing your critical paths to at least make sure that those things work together in the happy way. Because I have seen, especially with apps that have a lot of service objects, for some reason, those being kind of the highest-level test sometimes. But oftentimes, they end up not being composed well, being quite coupled with other service objects. So, you end up with a lot of stubbing of those in your test for them. And I think that's kind of where you can see things start to break down. JOËL: Yep. And when the RailsConf videos come out, I recommend seeing Stephanie's talk, some great gems in there for building a more maintainable test suite. Stephanie and I and, you know, most of us here at thoughtbot, we're testing nerds. We think about this a lot. We've also written a lot about this. There are a lot of resources in the show notes for this episode. Check them out. Also, just generally, check out the testing tag on the thoughtbot blog. There is a ton of content there that is worth looking into if you want to dig further into this topic. STEPHANIE: Yeah, and if you are wanting some, like, dedicated, customized testing training, thoughtbot offers an RSpec workshop that's tailored to your team. And if you kind of are interested in the things we're sharing, we can definitely bring that to your company as well. JOËL: On that note, shall we wrap up? STEPHANIE: Let's wrap up. Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeeee!!!!!!!! AD: Did you know thoughtbot has a referral program? If you introduce us to someone looking for a design or development partner, we will compensate you if they decide to work with us. More info on our website at: tbot.io/referral. Or you can email us at: referrals@thoughtbot.com with any questions.

The Bike Shed
429: Transforming Experience Into Growth

The Bike Shed

Play Episode Listen Later Jun 18, 2024 43:38


Stephanie has a newfound interest in urban foraging for serviceberries in Chicago. Joël discusses how he uses AI tools like ChatGPT to generate creative Dungeons & Dragons character concepts and backstories, which sparks a broader conversation with Stephanie about AI's role in enhancing the creative process. Together, the hosts delve into professional growth and experience, specifically how to leverage everyday work to foster growth as a software developer. They discuss the importance of self-reflection, note-taking, and synthesizing information to enhance learning and professional development. Stephanie shares her strategies for capturing weekly learnings, while Joël talks about his experiences using tools like Obsidian's mind maps to process and synthesize new information. This leads to a broader conversation on the value of active learning and how structured reflection can turn routine work experiences into meaningful professional growth. Obsidian (https://obsidian.md/) Zettelkasten (https://en.wikipedia.org/wiki/Zettelkasten) Mindmaps in Mermaid.js (https://mermaid.js.org/syntax/mindmap.html) Module Docs episode (https://bikeshed.thoughtbot.com/417) Writing Quality Method docs blog post (https://thoughtbot.com/blog/writing-quality-method-docs) Notetaking for Developers episode (https://bikeshed.thoughtbot.com/357) Learning by Helping blog post (https://thoughtbot.com/blog/learning-by-helping) Transcript:  JOËL: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Joël Quenneville. STEPHANIE: And I'm Stephanie Minn. And together, we're here to share a bit of what we've learned along the way. JOËL: So, Stephanie, what's new in your world? STEPHANIE: So, as of today, while we record this, it's early June, and I have started foraging a little bit for what's called serviceberries, which is a type of tree/shrub that is native to North America. And I feel like it's just one of those, like, things that more people should know about because it makes these little, tiny, you know, delicious fruit that you can just pick off of the tree and have a little snack. And what's really cool about this tree is that, like I said, it's native, at least to where I'm from, and it's a pretty common, like, landscaping tree. So, it has, like, really pretty white flowers in the spring and really beautiful, like, orange kind of foliage in the fall. So, they're everywhere, like, you can, at least where I'm at in Chicago, I see them a lot just out on the sidewalks. And whenever I'm taking a walk, I can just, yeah, like, grab a little fruit and have a little snack on them. It's such a delight. They are a really cool tree. They're great for birds. Birds love to eat the berries, too. And yeah, a lot of people ask my partner, who's an arborist, like, if they're kind of thinking about doing something new with the landscaping at their house, they're like, "Oh, like, what are some things that I should plant?" And serviceberry is his recommendation. And now I'm sharing it with all of our Bike Shed listeners. If you've ever wondered about [laughs] a cool and environmentally beneficial tree [laughs] to add to your front yard, highly recommend, yeah, looking out for them, looking up what they look like, and maybe you also can enjoy some June foraging. JOËL: That's interesting because it sounds like you're foraging in an urban environment, which is typically not what I associate with the idea of foraging. STEPHANIE: Yeah, that's a great point because I live in a city. I don't know, I take what I can get [laughs]. And I forget that you can actually forage for real out in, you know, nature and where there's not raccoons and garbage [laughs]. But yeah, I think I should have prefaced by kind of sharing that this is a way if you do live in a city, to practice some urban foraging, but I'm sure that these trees are also out in the world, but yeah, have proved useful in an urban environment as well. JOËL: It's really fun that you don't have to, like, go out into the countryside to do this activity. It's a thing you can do in the environment that you live in. STEPHANIE: Yeah, that was one of the really cool things that I got into the past couple of years is seeing, even though I live in a city, there's little pieces of nature around me that I can engage with and picking fruit off of people's [inaudible 03:18] [laughs], like, not people's, but, like, parkway trees. Yeah, the serviceberry is also a pretty popular one here that's planted in the Chicago parks. So, yeah, it's just been like, I don't know, a little added delight to my days [laughs], especially, you know, just when you're least expecting it and you stumble upon it. It's very fun. JOËL: That is really fun. It's great to have a, I guess, a snack available wherever you go. STEPHANIE: Anyway, Joël, what is new in your world? JOËL: I've been intersecting two, I guess, hobbies of mine: D&D and AI. I've been playing a lot of one-shot games with friends, and that means that I need to constantly come up with new characters. And I've been exploring what AI can do to help me develop more interesting or compelling character concepts and backstories. And I've been pretty satisfied with the result. STEPHANIE: Cool. Yeah. I mean, if you're playing a lot and having to generate a lot of new ideas, it can be hard if you're, you know, just feeling a little empty [laughs] in terms of, you know, coming up with a whole character. And that reminds me of a conversation that you and I had in person, like, last month as we were talking about just how you've been, you know, experimenting with AI because you had used it to generate images for your RailsConf talk. And I think I connected it to the idea of, like, randomness [laughs] and how just injecting some of that can help spark some more, I think, creativity, or just help you think of things in a new way, especially if you're just, like, having a hard time coming up with stuff on your own. And even if you don't, like, take exactly what's kind of provided to you in a generative AI, it at least, I don't know, kind of presents you with something that you didn't see before, or yeah, it's just something to react to. JOËL: Yeah, it's a great tool for getting unstuck from that kind of writer's block or that, like, blank page feeling. And oftentimes, it'll give you a thing, and you're like, that's not really exactly what I wanted. But it sparks another idea, which is what I actually want. Or sometimes you can be like, "Hey, here's an idea I have. I'm not sure what direction to take it in. Give me a few options." And then, you see that, and you're like, "Oh, that's actually pretty interesting." One thing that I think is interesting is once I've come up with a little bit of the character concept, or maybe even, like, a backstory element...so, I'm using ChatGPT, and it has that concept of memory. And so, throughout the conversation, it keeps bringing it back. So, if I tell it, "Look, this is an element that's going to be core to the character," and then later on, I'm like, "Okay, help me brainstorm some potential character flaws for this character," it'll actually find things that connect back to my, like, core concept, or maybe an element of the backstory. And it'll give me like, you know, 5 or 10 different ideas, and some of them can be actually really good. So, I've really enjoyed doing that. It's not so much to just generate me a character so much as it is like a conversation back and forth of like, "Okay, help me come up with a vibe for it. Okay, now that I have a vibe or a backstory element or, like, a concept, help me workshop this thing. And what about that?" And if I want to say, "It's going to be this character class, what are maybe some ways I could develop it that are unusual?" and just sort of step by step kind of choose your own adventure. And it kind of walking me through the process has been really fun. STEPHANIE: Nice. Yeah, the way you're talking about it makes a lot of sense to me how asking it to help you, not necessarily do all of it, like, you know, kind of just spit out something that you're like, okay, like, that's what I'm going to use, approaching it as a tool, and yeah, that's really fun. Have you had good experiences then playing with those characters [chuckles]? JOËL: I have. I think it's also really great for sort of padding out some of the content. So, I had a character I played who was a washed-up politician. And at one point, I knew that I was going to have to make a campaign speech. And I asked ChatGPT, "Can you help me, like...here are the themes I want to hit. Give me a, like, classic, very politician-sounding speech that sounds inspiring but also says nothing at the same time." And it did a really good job of that. And you can tell it, "Oh, that's too long. That's too short. I want three sentences. I want five sentences." And that was great. So, I saved that, brought it to the table, and read out my campaign speech, and it was a hit. STEPHANIE: Amazing. That's really fun. I like that because, yeah, I don't think...I am so poor at just improvising things like that, even though, like, I want to really embody the character. So, that's cool that you found a way to help you be able to do that because that just feels like kind of what playing D&D can be about. JOËL: I've never DM'd, but I could imagine a situation where, because the DMs have to improv so much, and you know what the players do, I could imagine having a tool like that available behind the DM screen being really helpful. So, all of a sudden, someone's just like, "Oh, I went to a place," and, like, all of a sudden, you have to, like, sort of generate a village and, like, ten characters on the spot for people that you didn't expect, or an organization or something like that. I could imagine having a tool like that, especially if it's already primed with elements from your world that you've created, being something really helpful. That being said, I've never DM'd myself, so I have no idea what it actually is like to be on the other side of that screen. STEPHANIE: Cool. I mean, if you ever do try that or have a DM experience and you're like, hmm, I wonder kind of how I might be able to help me here, I bet that would be a very cool experience to share on the show. JOËL: I definitely have to report back here. Something that I've been thinking about a lot recently is the difference between sort of professional growth and experience, so the time that you put into doing work. Particularly maybe because, you know, we spend part of our week doing client work, and then we have part of the week that's dedicated to maybe more directly professional growth: our investment day. How do we grow from that, like, four days a week where we're doing client work? Because not all experience is created equal. Just because I put in the hours doesn't mean that I'm going to grow. And maybe I'm going to feel like I'm in a rut. So, how do I take those four days a week that I'm doing code and transform that into some sort of growth or expansion of my knowledge as a developer? Do you have any sort of tactics that you like to use or ways you try to be a little bit more mindful of that? STEPHANIE: Yeah, this is a fun question for me, and kind of reminds me of something we've talked a little bit about before. I can't remember if it was, like, on air or just separately, but, you know, we talk a lot about, like, different learning strategies on the show, I think, because that's just something you and I are very into. And we often, like, lean on, you know, our investment day, so our Fridays that we get to not do client work and kind of dedicate to professional development. But you and I also try to remember that, like, most people don't have that. And most people kind of are needing to maybe find ways to just grow from the day-to-day work that they do, and that is totally possible, I think. And some of the strategies that I have are, I guess, like, it is really...it can be really challenging to, like, you know, be like, okay, I spent 40 hours doing this, and like, what did I learn [chuckles]? Feeling like you have to have something to show for it or something to point to. And one thing that I've been really liking is these automated check-ins we have at the end of the week. And, you know, I suspect that this is not that uncommon for just, like, a workplace to be like, "Hey, like, how did your week go? Like, what are some ways that it was successful? Like, what are your challenges? Like, where do you need support or help?" And I think I've now started using that as both, like, space for giving an update on just, like, business-y things. Like, "Here's the status of this project," or, like, "Here's, you know, a roadblock that we faced that took some extra time," or whatever. Then also being like, oh, this is a great time to make this space for myself, especially because...I don't know about you, but whenever I have, like, performance review time and I have to write, like, a self-review, I'm just like, did I do anything in the last six months [laughs], or how have I grown in the last six months? It feels like such a big question, kind of like you were talking about that blank page syndrome a little bit. But if I have kind of just put in the 10 minutes during my Friday to be like, is there something that was kind of just for me that I can say in my check-in? I can go back and, yeah, just kind of start to see just, like, you know, pick out or just pay attention to how, like, my 40 hours is kind of serving me in growing in the ways that I want to and not just to deliver code [laughs]. JOËL: What you're describing there, that sort of weekly check-in and taking notes, reminds me of the practice of journaling. Is that something that you've ever tried to do in your, like, regular life? STEPHANIE: Oh yeah, very much so. But I'm not nearly as, like, routine about it in my personal life. But I suspect that the routine is helpful in more of a, like, workplace setting, at least for me, because I do have, like, more clear pathways of growth that I'm interested in or just, like, something that, I don't know, not that it's, like, expected of everyone, but if that is part of your goals or, like, part of your company's culture, I feel like I benefit from that structure. And yeah, I mean, I guess maybe that's kind of my way of integrating something that I already do in my personal life to an environment where, like I said, maybe there is, like, that is just part of the work and part of your career progression. JOËL: I'm curious about the frequency. You mentioned that you sort of do this once a week, sort of a check-in at the end of the week. Do you find that once a week is about the right frequency versus maybe something like daily? I know a lot of these sort of more modern note-taking systems, Roam Research, or Obsidian, or whatever, have this concept of, like, a daily note that's supposed to encourage something that's kind of like journaling. Have you ever tried something more on a daily basis, or do you feel like a week is about...or once a week is about the right cadence for you? STEPHANIE: Listen, I have, like, complicated feelings about this because I think the daily note is so aspirational for me [laughs] and just not how I work. And I have finally begrudgingly come to accept this no matter how much, like, I don't know, like, bullet journal inspirational content I consume on the internet [laughs]. I have tried and failed many a time to have more frequency in that way. But, I don't know, I think it almost just, like, sets me up for failure [laughs] because I have these expectations. And that's, like, the other thing. It's like, you can't force learning necessarily. I don't know if this is, like, a strategy, but I think there is some amount of, like, making sure that I'm in the right headspace for it and, you know, like, my environment, too, kind of is conducive to it. Like, I have, like, the time, right? If I'm trying to squeeze in, I don't know, maybe, like, in between meetings, 20 minutes to be like, what did I learn from this experience? Nothing's coming out [laughs]. That was another thing that I was kind of mulling over when he had this topic proposed is this idea of, like, mindset and environment being really important because you know when you are saying, like, not all time is created equal, and I suspect that if, you know, either you or, like, the people around you and the environment you're in is not also facilitating growth, and, like, how much can you really expect for it to be happening? JOËL: I mean, that's really interesting, right? The impact of sort of a broader company culture. And I think that definitely can act as a catalyst for growth, either to kind of propel you forward or to pull you back. I want to dig into a little bit something you were saying about being in the right headspace to capture ideas. And I think that there's sort of almost, like, two distinct phases. There's the, like, capturing data, and information, and experiences, and then, there's synthesizing it, turning information into learning. STEPHANIE: Yes. JOËL: And it sounds like you're making a distinction between those two things, specifically that synthesis step is something that has to happen separately. STEPHANIE: Ooh, I don't even...I don't know if I would necessarily say that I'm only talking about synthesis, but I do like that you kind of separated those categories because I do think that they are really important. And they kind of remind me a lot about the scientific method a little bit where, you know, you have the gathering data and, like, observations, and you have, you know, maybe some...whatever is precipitating learning that you're doing maybe differently or new. And that also takes time, I think, or intention at least, to be like, oh, do I have what I need to, like, get information about how this is going? And then, yeah, that synthesis step that I think I was talking about a little bit more. But I don't think either is just automatic. There is, I think, quite a bit of intention involved. JOËL: I think maybe the way I think about this is colored by reading some material on the Zettelkasten method of note-taking, which splits up the idea of fleeting notes and literature notes, which are sort of just, like, jotting down ideas, or things you've seen, things that you've learned, maybe a thought you had when you read a particular paragraph in a blog post, something like that. And then, the permanent notes, which are more, like, fully formed thoughts that arise out of the more fleeting ones. And so, the idea is that the fleeting ones maybe you're taking those in a notebook if you're doing it pen and paper. You could be doing it in some sort of, like, daily note, or something like that. And then, those are temporary. They were there to just capture information. Later on, you process that, and then you can throw them out if you need to. STEPHANIE: Yeah, that makes a lot of sense. This has actually been a shift for me, where I used to rely a lot more on memory and perhaps, like, didn't have a great system for taking things like fleeting notes and, like, documenting kind of [inaudible 18:28] what I was saying earlier about how do I make sure that the information is recorded, you know, for me to synthesize later? And I have found a lot more success lately in that fleeting note style of operating. And thanks to Obsidian honestly, now it's so easy to be like, oh, I'm just going to open a quick new file. And I need as little friction as possible to, like, put stuff somewhere [laughs]. And, actually, I'm excited to talk a little bit more about this with you because I think you're a little bit different where you somehow find the time [laughs] and care to create your diagrams. I'm like, if I can, for some reason, even get an Obsidian file open, I'll tab to Slack. And I send myself a lot of notes in my just own personal DM space. In fact, it's actually kind of embarrassing because I use the Command+K shortcut to navigate to my own personal DMs, which you can get to by typing me, like, M-E. And sometimes I've accidentally just entered that into a channel chat [laughs], and then I have to delete it really quick later when I realize what I've done. So, yeah, like, I meant to navigate to my personal notes, and I just put in our team chat, "Me [laughs]." And, I don't know, I have no idea how that comes up [laughs], what people think is going on. But if anyone's listening to this podcast from thoughtbot and has seen that of me, that's what happened. JOËL: You may not be the only one who's done that. STEPHANIE: Thank you. Yeah [laughs], that's good to know. JOËL: I want to step back a little bit because we've been talking about, like, introspection, and synthesis, and finding moments to capture information. And I think we've sort of...there's an unspoken assumption here that a way to kind of turbocharge learning from day-to-day experience is some form of synthesis or self-reflection. Would you agree with that statement? STEPHANIE: Okay. This is another thing that I am perhaps, like, still trying to figure out, and we can figure it out together, which is separating, like, self-driven learning and, like, circumstance-driven learning. Because it's so much easier to want to reflect on something and find time to be, like, oh, like, how does this kind of help my goals or, like, what I want to be doing with my work? Versus when you are just asked to do something, and it could still be learning, right? It could still be new, and you need to go do some research or, you know, play around with a new tool. But there's less of that internal motivation or, like, kind of drive to integrate it. Like, do you have this distinction? JOËL: I've definitely noticed that when there is motivation, I get more out of every hour of work that I put in in terms of learning new things. The more interest, the more motivation, the more value I get per unit of effort I put in. STEPHANIE: Yeah. I think, for me, the other difference is, like, generative learning versus just kind of absorbing information that's already out there that someone else's...that is kind of, yeah, just absorbing rather than, like, creating something new from, like, those connections. JOËL: Ooh. STEPHANIE: Does that [chuckles] spark something for you? JOËL: The gears are turning in my head because I'm almost hearing that as, like, a passive versus active learning thing. But just sort of like, I'm going to let things happen to me, and I will come out of that with some experience, and something is going to happen. Versus an active, I am going to, like, try to move in a direction and learn from that and things like that. And I think this maybe connects back to the original question. Maybe this sort of, like, checking in at the end of the week, taking notes is a way to convert something that's a bit more of a passive experience, spending four days a week doing a project for a client, into something that's a little bit of a more active learning, where you say, "Okay, I did four weeks of this particular type of Rails work. What do I get out of it? What have I learned? What is something new that I've seen? What are some opinions I have formed, patterns I like or dislike?" STEPHANIE: Yeah, I like that distinction because, you know, a few weeks ago, we were at RailsConf. We had kind of recapped it in a previous episode. And I think we had talked about like, oh, do we, like, to sit in talks or participate in workshops? And I think that's also another example of, like, passive versus active, right? Because I 100%, like, don't have the same type of learning by just, you know, listening to a talk that I do with maybe then going to look up, like, other things this person has put out in the world, finding them to talk to them about it, like, doing something with the content, right? Otherwise, it's just like, oh yeah, I heard this talk. Maybe one day I'll remember it when the need arises [laughs]. I, like, have a pointer to it in my brain. But until then, it probably just kind of, like, sits there, and nothing's really happened with it. JOËL: I think maybe another thing that's interesting in that passive versus active distinction is that synthesis is inherently an act of creation. You are now creating new ideas of your own rather than just capturing information that is being thrown at you, either by sitting in a talk or by shipping tickets. The act of synthesizing and particularly, I think, making connections between ideas, either because something that, let's say you're in a talk, a speaker said that sparks an idea for yourself, or because you can connect something that speaker said with another idea that you already have or an idea that you've seen elsewhere. So, you're like, oh, the thing this person is saying connects to this thing I read in a book or something another speaker said in an earlier session, or something like that. All of a sudden, now you're creating these new bits of knowledge, new perspectives, maybe even new mental models. We talked about mental models last week. And so, knowledge is not just the facts that you absorb or memorize. A lot of it is building the connections between those facts. And those are things that are not always given to you. You have to create them yourself. STEPHANIE: Yeah, I am nodding my head a lot because that's resonating with, like, an experience that I'm having kind of coaching and mentoring a client developer on my team who is earlier in her career. And one thing that I've been really, like, working on with her is asking like, "Oh, like, what do you think of this?" Or like, "Have you seen this before? What are your reactions to this code, or, like this comment?" or whatever. And I get the sense that, like, not a lot of people have prompted her to, like, come up with answers for those kinds of questions. And I'm really, really hopeful that, like, that kind of will help her achieve some of the goals that she's, like, hoping for in terms of her technical growth, especially where she's felt like she's stagnated a little bit. And I think that calls back really well to what you said at the beginning of, like, you can spend years, right? Just kind of plugging away. But that's not the same as that really active growth. And, again, like, that's fine if that's where you're at or want to be at for a little while. But I suspect if anyone is kind of, like, wondering, like, where did that time go [laughs]...even for me, too, like, once someone started asking me those questions, I was like, oh, there's still so much to figure out or explore. And I think you're actually really good at doing that, asking questions of yourself. And then, another thing that I've picked up from you is you ask questions about, like, what are questions other people would have? And that's a skill that I feel like I still have yet to figure out. I'm [chuckles] curious what you think about that. JOËL: That's interesting because that kind of goes to another level. I often think of the questions other people would have from a more, like, pedagogical sense. So, I write a lot of blog posts. I write a lot of talks that I give. So, oftentimes when I'm creating that kind of material, there's a bit of an inner critic who's trying to, you know, sitting in the audience listening to myself speak, and who's going to maybe roll their eyes at certain points, or just get lost, or maybe raise their hand with a question. And that's who I try to address those things so that then when I go through it the next time, that inner critic is actually feeling engaged and paying attention. STEPHANIE: Do you find that you're able to do that because you've seen that happen enough times where you're like, oh, I can kind of predict maybe what someone might feel confused about? I'm curious, like, how you got from being, like, well, I know what I would be confused about to what would someone else be unsure or, like, want more information about. JOËL: Part of the answer there is that I'm a very harsh critic myself. STEPHANIE: [laughs] Yes. JOËL: So, I'm sitting in somebody else's talk, and there are probably parts where I'm rolling my eyes or being like, wait a minute, how did you get from this idea to this other thing? That doesn't follow. And so, I try to turn that back towards myself and use that as fuel to make my own work better. STEPHANIE: Yeah, that's cool. I like that. Even if it's just framed as, like, a missed opportunity for people to have better or more comprehensive understanding. I know that's something that you're, like, very motivated to help kind of spread more of [laughs]. Understanding and learning is just important to you and to me. So, I think that's really cool that you're able to find ways to do that. JOËL: Well, you definitely want to, I think, to keep a sort of beginner's mindset for a lot of these things, and one of the best ways to do that is to work with beginners. So, I spent a lot of time, back in the day, for example, in the Elm language chat room, just helping people answer basic questions, looking up documentation, explaining sort of basic concepts. And that, I think, helped me get a sense of like, where were newcomers to the language getting stuck? And what were the explanations of those concepts that really connected? Which I could then translate into my work. And I think that that made me a better developer and helped me build this, like, really deep understanding of the underlying concepts in a way that I wouldn't have had just writing code on my own. STEPHANIE: Wow, forum question answering hero. I have never thought to do that or felt compelled to do that. But I remember my friend was telling me, she was like, "Yeah, sometimes I just want to feel good about myself. And I remember that I know things that other people, like, are wanting to find out," and she just will answer some easy questions on Stack Overflow, you know, about, like, basic Rails stuff or something. And she is like, "Yeah, and that's doing my good deed [laughs]." And yeah, I think that it also, you know, has the same benefits that you were just saying earlier about...because you want to be helpful, you figure out how to actually be helpful, right? JOËL: There's maybe a sense as well that helping others, once more, forces you into more of an active mindset for growth in the same way that interrogating yourself does, except now it's a beginner who's interrogating you. And so, it forces you to think a little bit more about those whys or those places where people get stuck. And you've just sort of assumed it's a certain way, but now you have to, like, explain it and really get into some of the concepts. STEPHANIE: So, on the show, we've talked a lot about the fun things you share in the dev channel in our Slack workspace. But I recently discovered that someone (Was it you?) created an Obsidian MD channel for our favorite note-taking software. And in it, you shared a really cool tool that is available in Obsidian called mind maps. JOËL: Yeah, so mind maps are a type of diagram. They're effectively a tree structure, but they don't really look like that when you draw them out. You start with a sort of topic in the center, and then you just keep drawing branches off of that, going every direction. And then, maybe branches off branches and keep going as you add more content. Turns out that Mermaid.js supports mind maps as a graph type, and Obsidian embeds Mermaid diagrams. So, you can use Mermaid's little language to express a mind map. And now, all of a sudden, you have mind mapping as a tool available for you within Obsidian. STEPHANIE: And how have you been using that to kind of process and experience or maybe, like, end up with some artifacts from, like, something that you're just doing in regular day-to-day work? JOËL: So, kind of like you, I think I have the aspiration of doing some kind of, like, daily note journaling thing and turning that into bigger ideas. In practice, I do not do that. Maybe that's the thing that I will eventually incorporate into my practice, but that's not something that I'm currently doing. Instead, a thing that I've done is a little bit more like you, but it's a little bit more thematically chunked. So, for example, recently, I did several weeks of work that involved doing a lot of documentation for module-level documentation. You know, I'd invested a lot of time learning about YARD, which is Ruby's documentation system, and trying to figure out, like, what exactly are docs that are going to be helpful for people? And I wanted that to not just be a thing I did once and then I kind of, like, move on and forget it. I wanted to figure out how can I sort of grow from that experience maximally? And so, the approach I took is to say, let's take some time after I've completed that experience and actually sort of almost interrogate it, ask myself a bunch of questions about that experience, which will then turn into more broad ideas. And so, what I ended up doing is taking a mind-mapping approach. So, I start that center circle is just a circle that says, "My experience writing docs," and then I kind of ring it with a series of questions. So, what are questions that might be interesting to ask someone who just recently had experience writing documentation? And so, I come up with 4,5,6 questions that could be interesting to ask of someone who had experience. And here I'm trying to step away from myself a little bit. And then, maybe I can start answering those questions, or maybe there are sub-questions that branch off of that. And maybe there are answers, or maybe there are answers that are interesting but that then trigger follow-up questions. And so I'm almost having a conversation with myself and using the mind map as a tool to facilitate that. But the first step is putting that experience in the center and then ringing it with questions, and then kind of seeing where those lead. STEPHANIE: Cool. Yeah, I am, like, surprised that you're still following that thread because the module docs experience was quite a little bit a while ago now. We even, you know, had an episode on it that I'll link in the show notes. How do you manage, like, learning new things all the time and knowing what to, like, invest energy and attention into and what to kind of maybe, like, consider just like, oh, like, I don't know, that was just an experience that I had, and I might not get around to doing anything with it? JOËL: I don't know that I have a great system. I think sometimes when I do, especially a more prolonged chunk of time doing a thing, I find it really worthwhile to say, hey, I don't want that to sort of just be a thing that was in my memory, and then it moves out. I'd like to pull out some more maybe practical or long-term ideas from it. Part of that is capture, but some of that is also synthesis. I just spent two weeks or I just spent a month using a particular technology or doing a new kind of task. What do I have to show for it? Are there any, like, bigger ideas that I have here? Does this connect with any other technologies I've done or any other ideas or theories? Did I come up with any opinions? Did I like this technology? Did I not? Are there elements that were inspirational? And then capturing some of that eventually with the idea of...so I do a sort of Zettelkasten-style permanent note collection, the idea to create at least a few of those based off of the experience that I can then connect to other things. And maybe it eventually turns into other content. Maybe it's something I hold onto for a while. In the case of the module docs, it turned into a Bike Shed episode. It also turned into a blog post that was published this past week. And so, it does have a way of coming back. STEPHANIE: Yeah. Yeah. One thing that sparked for me was that, you know, you and I spend a lot of time thinking about, like, the practice of writing software, you know, in the work we do as consultants, too. But I find that, like, you can also apply this to the actual just your work that you are getting paid for [laughs]. This was, I think, a nascent thought in the talk that I had given. But there's something to the idea of, like, you know, if you are working in some code, especially legacy code, for a long time, and you learn so much about it, and then what do you have to show for it [chuckles], you know? I have really struggled with feeling like all of that work and learning was useful if it just, like, remains in my memory and not necessarily shared with the team or, I don't know, just, like, knowing that if I leave, especially since I am a contractor, like, just recognizing that there's value in being like, oh, I spent an hour or, like, half a day sifting through this complex legacy code just to make, like, a small change. But that small change is not the full value of all of the work that I did. And I suspect that, like, just the mind mapping stuff would be really interesting to apply to more. It's not, like, just practical work, but, like, more mundane, I don't know, like, labor [laughs], if you will. JOËL: I can think of, like, sort of two types of knowledge that you can take out of something like that. Some of it is just understanding how this legacy system works, saying, oh, well, they have this user model that's connected to this old persona table, which is kind of unused, but we sometimes rely for in this legacy case. And you've got to have this permission flag turned on and, like, all those things that you had to just discover by reading the code and exploring. And that's going to be useful to you as long as you work in that legacy codebase, as long as you work through that path. But when you move on to another project, that knowledge probably doesn't serve you a whole lot. There are things that you did throughout that journey, though, that you can probably pull out that are going to be useful to you on other projects. And that might be maybe you came up with a new way of navigating the code or a new way of, like, finding how different pieces were connected. Maybe it was a diagramming tool; maybe it was some sort of gem. Maybe it was just a, oh, a heuristic, like, when I see a model, I like to follow the associations first. And I always go for the hasmanys over the belongstos because those generally lead me in the right direction. Like, that's really interesting insight, and that's something that might serve you on a following project. You can also pull out bigger things like, are there refactoring techniques that you experimented with or that you learned on this project that you would use again elsewhere? Are there ways of maybe quarantining scary code on a legacy project that are a thing that you would want to make more consistent part of your practice? Those are all great things to pull out of, just a like, oh yeah, I did some work on a, like, old legacy part of an app. And what do I have to show for it? I think you can actually have a lot to show for it. STEPHANIE: Yeah, that's really cool. That sounds like a sure way of multiplying the learning. And I think I didn't really consider that when I was first talking about it, too. But yeah, there are, like, both of those things kind of available to you to, like, learn from. Yeah, it's like, that time is never just kind of, like, purely wasted. Oh, I don't know, sometimes it really feels like that [laughs] when you are debugging something really silly. But yeah, like, I would be interested in kind of thinking about it from both of those lenses because I think there's value in what you learn about that particular system in that moment of time, even if it might not translate to just future works or future projects. And, like, that's something that I think we would do better at kind of capturing, and also, there's so much stuff, too, kind of to that higher level growth that you were speaking to. JOËL: I think some of the distinctions we're talking about here is something that was explored in an older episode on note-taking with Amanda Beiner, where we sort of explored the difference between exploratory notes, debugging notes, idea notes, and how note-taking is not a single thing. It can serve many purposes, and they can have different lifespans. And those are all just ways to aid your thinking. But being maybe aware of the kind of thinking that you're trying to do, the kind of notes you're trying to take can help you make better use of that time. STEPHANIE: I have one last question for you before we wrap up, which is, do you find, like, the stuff we're talking about to be particularly true about software development, or it just happens to be the thing that you and I both do, and we also love to learn, and so, therefore, we are able to talk about this for, like, 50 minutes [laughs]? Are you able to make any kind of distinction there, or is it just kind of part of pedagogy in general? JOËL: I would say that that sort of active versus passive thing is a thing that's probably true, just about anything that you do. For example, I do a lot of bouldering. Just going spending a lot of time on the wall, climbing a lot; that's going to help me get better. But a classic way that people try to improve is filming themselves or having a friend film themselves, and then you can look at it, and then you evaluate, oh, that's what I did. This is where I was struggling to get the next hold. What if I try to do something different? So, building in an amount of, like, self-reflection into the loop all of a sudden catalyzes that learning and helps you grow at a rate that's much more than if you're just kind of mindlessly putting time into it. So, I would go so far as to say that self-reflection, synthesis—those are all things that are probably going to catalyze growth in most areas of your life if you're being a little bit more self-aware. But I've found that it's been particularly useful for me when it comes to trying to get better at the job that I do every week. STEPHANIE: Yeah, I think, for me, it's like, yeah, getting better at being a developer rather than being, you know, a software developer at X company. Like, not necessarily just getting better at working at that company but getting better at the skill itself. JOËL: And those two things have a way of sort of, like, folding back into themselves, right? If you're a better software developer in general, you will probably be a better developer at that company. Yes, you want domain knowledge and, like, a deep understanding of how the system works is going to make you a better developer at that company. But also, if you're able to find more generic approaches to onboard onto new things, or to debug more effectively, or to better read or understand unknown code of high complexity, those are all going to make you much better at being a developer at that company as well. And they're transferable skills, so they're all really good things to have. STEPHANIE: On that note. Shall we wrap up? JOËL: Let's wrap up. STEPHANIE: Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeee!!!!!! AD: Did you know thoughtbot has a referral program? If you introduce us to someone looking for a design or development partner, we will compensate you if they decide to work with us. More info on our website at: tbot.io/referral. Or you can email us at: referrals@thoughtbot.com with any questions.

The Bike Shed
428: Ruminating on Ruby Enumerators

The Bike Shed

Play Episode Listen Later Jun 11, 2024 35:44


Joël explains his note-taking system, which he uses to capture his beliefs and thoughts about software development. Stephanie recalls feedback from her recent RailsConf talk, where her confidence stemmed from deeply believing in her material despite limited rehearsal. This leads to a conversation about the value of mental models in building a comprehensive understanding of a topic, which can foster confidence and adaptability during presentations and discussions. The episode then shifts focus to the practical application of enumerators in Ruby, exploring various mental models to understand their functionality better. Joël introduces several metaphors, such as enumerators as cursors, lazy collections, and sequence generators, which help demystify their use cases. Episode on note-taking (https://bikeshed.thoughtbot.com/357) What we believe about software (https://bikeshed.thoughtbot.com/172) Ruby Enumerators (https://ruby-doc.org/3.3.1/Enumerator.html) Enumerator Lazy (https://ruby-doc.org/3.3.1/Enumerator/Lazy.html) Modeling a Paginated API as a lazy stream (https://thoughtbot.com/blog/modeling-a-paginated-api-as-a-lazy-stream) Solving a memory performance issue with enumerator (https://thoughtbot.com/blog/how-we-used-a-custom-enumerator-to-fix-a-production-problem) Find in batches (https://api.rubyonrails.org/classes/ActiveRecord/Batches.html#method-i-find_in_batches) Binary tree implementation with different traversals (https://gist.github.com/JoelQ/02f3ef9f61bebc7c8e5ea67d10ed92c6) Teaching Ruby to Count (https://www.youtube.com/watch?v=PHMOsTK1jSE) Transcript:  STEPHANIE: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Stephanie Minn. JOËL: And I'm Joël Quenneville, and together, we're here to share a bit of what we've learned along the way. STEPHANIE: So, Joël, what's new in your world? JOËL: So, what's new in my world isn't exactly a new thing. I've talked about it on the podcast here before, and it's my note-taking system. I have a system where I try to capture notes that are things I believe about software or things I think are probably true about software. They're chunked up in really small pieces, such that every note is effectively one small thesis statement and a paragraph of text, and maybe a diagram or a code snippet to support that. And then, it's highly hyperlinked to other notes. So, I sort of build out some thoughts on software that way. A thing that I've done recently that's been pretty exciting with that is introducing a sort of separate set of notes that connect to my sort of opinion notes. So, I create individual notes for public works that I've done, things like blog posts or conference talks. Because a lot of those are built on top of ideas that have been sitting in my note system for a while. Readers and listeners get to sort of see the final product, but often sort of built up over several months or even a couple of years as I added different notes that kind of circled a topic and then eventually got to a thing. What I did, though, was actually making those connections explicit. And so I use Obsidian. Obsidian has this cool graph view where it just sort of shows all of the notes, and it circles them with, like, connections between them where the notes connect. So, I can now see in a visual format how my thoughts cluster in different topics, but then also which clusters have talks and blog posts hanging off of them and also which ones don't, which ones are like, oh, I have a lot of thoughts on this topic, and I've not yet written about it in a public forum; maybe that would be a thing to explore. So, seeing that visual got me really excited. I was having a good time. STEPHANIE: Yes, I have several thoughts coming to mind in response, which is, I know you love a visual. I really like the system of, even if you have created content for it, like, you have a space for, like, thoughts about it to evolve. Because you said, like, sometimes content comes out of notes that you've been...or, like, thoughts you've been having over years, but it's like, even afterwards, I'm sure there will still be new thoughts about it, too. I always have a hard time finding a place for that thing kind of once I, I don't know, it's like some of that stuff is never really considered done, right? So, that is really cool. And I also was just thinking about an old episode of The Bike Shed back when Chris Toomey and Steph Viccari hosted the podcast called "What We Believe About Software," I think, is the title. And I was just thinking about how, like, if only we could just dump all of your notes [laughs] into some, you know, stream [laughs], and that would be really cool. If we ever do, like, an episode like that, that would be really fun. And I'm sure, you know, you already have this, like, huge bank of ideas [laughs]. JOËL: Yes. It is really fun because I build up...the thoughts are often sort of interconnected, and so they might have a topic, but they are very focused. So, I might have, like, three or four things I believe about a particular topic that cluster together. So, we could...and, actually, I have used, in the past, some of those clusters as initial food for thought for a Bikeshed episode. STEPHANIE: Yeah, that's really neat. I like this idea of a kind of just, like, a repository for putting down what you believe about software as kind of, like, guiding principles for yourself as a developer a little bit. I remember a piece of feedback I got about my RailsConf talk that I gave a few weeks ago, and someone said like, "Oh, you sounded really confident in what you were talking about." And that surprised me because I, like, didn't practice rehearsing giving the talk all that much [laughs]. It's because they had asked like, "Oh, like, did you practice a lot?" or something like that. And I think I realized that I, like, really believed in what I was sharing and kind of that, I think, was perhaps what they were picking up on. And even though, like, maybe the rehearsal of the presentation itself was not where I had spent a lot of time on, I had spent a lot of time thinking about what I wanted to share and just building up my confidence around that. So, I thought that was an interesting connection. JOËL: Yeah, you fully developed the idea. You kind of explored all the side trails, maybe a little bit on your own as well. You're on very familiar terrain. And so, that is a way of building confidence separate from just sort of memorizing a talk. STEPHANIE: Yeah, yeah. Exactly. JOËL: In a sense, I almost feel like that's a better sense of confidence because then you can sort of...you can roll with the punches. You know, if a slide is out of order or something, sure, it maybe messes up a little bit of the narrative that you're trying to say. But you're not like, "Oh no, what is this content?" You're like, "Oh yeah, this thing," and you can dive right into it. Somebody asks you a question, and you're not like, "Oh no, that was not in the script," because, again, you've sort of mastered your topic. You know the area as a whole, even sort of the blurry edges beyond the talk, and can react in a way that is pretty confident. STEPHANIE: Yeah. I still definitely fear the open Q&A. I've never done it before, but maybe one day I will be able to because I just, you know, know my topic so well inside and out [laughs] that I can roll with the punches, as you say. JOËL: Open Q&A is just...it's a roll of the dice. Sometimes, you get some really good conversation topics there, and sometimes, it's just a waste of everyone's time. STEPHANIE: I like that take [laughs]. JOËL: Maybe that should go into the things I believe about software. So, other than receiving feedback about your RailsConf talk, what is new in your world? STEPHANIE: Yeah, so I am wrapping up a pretty large project on my client work that we're hoping to release soon. And, in fact, it's actually being released along with a big announcement from the client company to their customers. Essentially, at a conference, they're going to say like, "Hey, like, we now have this new feature." And so, I think there's some hype generated around it. And this past week, we've been doing a lot of internal testing of the feature because there are a lot of employees of my client company who are, like, pretty big users of the product, which is cool because I think we're getting, you know, we have easy access to people who can give us good feedback. But I am having a hard time with being on the receiving end of the feedback and figuring out, like, what is stuff I need to attend to now before, you know, this big release? And what is stuff that is just kind of, like, general feedback like, "Oh, like, I wish it did this," but, you know, it turns out that that's not really what we were building? And how do I just kind of, like, accept that? You know, it's coming from a good place, but I can't really help them there, at least right now. And that's hard for me because I like helping people, right? And so, if someone says something like, "Oh, like, I wish it did this," or like, "Oh, that's kind of weird," I'm like, "Oh, I want to just, like, fix that for you right now [laughs]." And I suspect that a lot of other devs can relate to this, especially if, like, you know, you've been working on something for a little bit, and it feels...I'm just going to say it: it feels a little precious to me. So, what I'm trying to do today, actually, is not look at any of the feedback at all [laughs] and come at it tomorrow with a bit of a calmer vibe and be able to separate out, like, you know, I think all feedback is informative, but not all of it is useful for you at any given moment. Like, if there are bugs, then those will be my immediate priority. If there's maybe some small tweaks that we can make the feature just a little bit more polished, then I also think those are good. But then we are discovering a few things, too, about, like, what this feature is or could be. And I think those are the things that, you know, need to be brought into a conversation with a broader group and think about, like, is this the direction we want to go? So, that's kind of how I'm bucketing that feedback right now. JOËL: How do you feel about receiving direct feedback versus having something filtered through something like a product team? STEPHANIE: Ooh, that's an interesting question. Because right now we're doing, I think, a mix of both that I'm not sure that I really like. On one hand, when it's filtered, it's hard to get to the root of what someone is asking for. And oftentimes, like, it may not even include enough information after the fact to be able to come at it from a dev perspective. But then direct feedback, I think, is just a little bit overwhelming sometimes. And it can be hard to figure out what to pay attention to if you don't have that, like, input from a product team about, like, what the roadmap is looking like or where, you know, strategically their heads are at. So, one thing that kind of has emerged from this is like, oh, I was getting, you know, notifications for the feedback coming in. And what we did was set up a meeting [laughs] so that we can...maybe all of us can, like, scan it together ahead of time and then come at it with a little bit of context about what's come in but then maybe coalesce around the things that we feel are important. JOËL: Well, you'll have to keep us updated on how that plays out, and we can kind of hear what is the balance that ends up working well for you. STEPHANIE: Yeah, I hope so. I think this is actually maybe something that's a bit underexplored from the dev perspective, you know, that in-between stage of you're not totally done because it's not shipped to the world yet, but, you know, you're starting to get a little bit of that input. And what you do with that? Because I think there is some value in being engaged in that process. JOËL: So, we were talking earlier about this note-taking system that I use and sort of a renewed excitement that I have about it. And one thing that I did when I was going through and finding clusters of things that hadn't been written about was I found that I had a cluster of notes on different mental models that I had for understanding Ruby enumerators, not the enumerable module, but the enumerator object. And I decided, you know what? This would probably make for a good blog post. So, I drafted a blog post, and I've been thinking about this a little bit more recently. So, I've been really hyped about digging into enumerators because of that experience. STEPHANIE: Yeah, that's very cool. I have to say that I feel like I did not know a lot about enumerators and the API for them kind of before you brought this topic up, and I did a bit of a deep dive in preparation for us to discuss it. I feel like most devs, you know, work with enumerators via methods on enumerable without totally knowing that they are. So, I think that this would be a really interesting episode for people to be like, oh, like, I've been using this stuff, you know, the whole time, and now I can have a different perspective or just more insight on what they can do. JOËL: Before we dig into individual mental models, though, I want to think a little bit about the concept of mental models as a whole. Years ago, someone gave me advice to sort of pay attention to mental models, ways I think about the world or different code structures, different code approaches, and that really stuck with me. So, I've since been, like, kind of, like, collecting mental models. And, in a way, they're like a, for me, a bit more of a concrete way to look at a particular topic. So, I can say I'm looking at this particular topic through the lens of a particular mental model that helps me build more clarity around it. And if I have three or four, then I can kind of look at it from three or four different perspectives. And now, all of a sudden, I feel like I'm seeing in three dimensions. STEPHANIE: Whoa, the Matrix even [laughs]. That's cool. Yeah, I really like that advice. I think I'm going to steal it and start kind of suggesting it to other people because I think, in a way, on this show, that has come through a lot. And talking about things on the podcast has helped me develop a lot of my mental models. And I think we've done a few, like, episodes in the past about various ones we have for just our work because it's like, that's infinite [laughs]. But what I really have been appreciating is that mental models just need to work for you. As long as you're able to understand something, then it's valuable. And that has really helped me also, like, just get on the same understanding with others because the goal is not necessarily to, like, explain it the way that I would think of it, but figure out what would help them kind of develop their own mental model for understanding something, and, you know, kind of as long as we both feel like we have that shared understanding, no matter what lens it's through. And, you know, sometimes it's even more effective when we are able to share it. But I feel like, you know, you can still find ways to collaborate on something with a diversity of mental models. JOËL: Yeah, they're a great way to build self-understanding. They're a great way to sort of build understanding between two people. So, I'm a huge fan of the concept. And part of what I've been doing with my note-taking system is trying to capture those as much as possible. If I'm ever, like, trying to understand a complex topic and I'm like, oh, I think I've got a breakthrough here; I understand it; it's kind of like this, or you can imagine it in this perspective, it's like, write that down. That's gold. STEPHANIE: Very cool. So, Joël, would you be able to share some of your mental models for enumerator? JOËL: So, one way that I look at it is the idea that an enumerator is effectively a cursor over a collection. So, you have an array and a regular array; you're either in the middle of iterating through it using something like each, or you're not. You just have a collection of items. Enumerator introduces the idea that you're actually sort of at a position in the array. So, you're sort of focused on, let's say, the third item or the fourth item. You have a cursor there, and you can move that cursor forward as you sort of step through. But the really cool thing is you can also kind of pause and just pass that cursor on to someone else, and someone else can move the cursor a few steps further down the collection, pause, pass it on to someone else. And it's totally fine. Nobody has to, like, go through an entire, like, each iteration. STEPHANIE: Yeah. So, when you were talking about cursors, that got me thinking a little bit because I actually have struggled with that concept, especially when it comes to, you know, things code-related. Like, when I've had to work with database things and stuff, like, the idea of a cursor was a little, like, difficult for me to wrap my head around. And I was looking at the methods on enumerator, like the instance methods on enumerator. And one of them actually is what helped me develop this mental model. And I'm excited to see what you think. But there is a rewind method that basically rewinds the sequence back to its beginning, right? And what that triggered for me was a VHS tape [laughs] and just those, like, car-shaped rewinders for tapes back in the '90s. I don't know if you ever had one in your house, but I did. And I just thought that was such a cool method name because it was very, I don't know, it was just like a word that we use in the English language, right? So, the idea of, like, tapes, you know, like, cassette tapes or VHS tape kind of also it sounds like it matches well with what you were sharing, too, where it's like, I could pass, I don't know, maybe I, like, listen to a few songs on my cassette tape, and then I give it to someone else, and they can pick up where I left off. And yeah, that was really helpful in understanding, like, a marker of a position a little more than cursor was able to for me. JOËL: That's really interesting because now I wonder, like, how far we could push that metaphor. So, musical data is encoded on magnetic tape. Cassette tapes typically there are sort of two spools. You start off with all of the tape wound up around one spool, and then as it sort of moves across the read head, it gets wound up on sort of the, I don't know, destination spool. I guess you can call them origin and destination. And because of that, you can sort of be in a, like, partly read state where, you know, half the tape is on the destination spool, half of it is on the origin spool, and you have that read head that's in the middle, and you're just kind of paused there. And you can kind of jump forward in that. So, I imagine something like that in your metaphor is like an enumerator. Contrast that to imagine just a single spool, which is just we have musical data encoded on magnetic tape, and we wrapped it up on a spool. I feel like that's almost more like a regular array because you don't have that concept of, like, position, or being able to read parts of it or anything like that. It's just, here's some data. STEPHANIE: Yeah. While you were talking about the two spools, I was thinking about, like, part of what is nice about enumerator is that you can go forward or backwards, right? And that feels a little more possible with that two-spool metaphor [laughs], rather than just unraveling something, where you are kind of discarding what has already been read. JOËL: The one caveat there is that enumerators can move forward one item at a time. They can only move backwards by jumping back to the beginning. So, you can't step forward or step back. STEPHANIE: Yeah, that's fair. JOËL: You step forward, or you, like, rewind to the beginning. I think, in my mind, I was thinking a little bit more about this metaphor. And I think it's also just a metaphor for what's called the External Iterator Pattern. It's one of the classic Gang of Four Patterns, which is what enumerator, the object in Ruby, is an implementation of. I feel like I always see that in the documentation, like, oh, enumerator is an implementation of the External Iterator Pattern. And I just kind of go, what? STEPHANIE: [laughs] JOËL: Or maybe I kind of understand the idea of, like, okay, it's a way to, like, be able to step through a collection. But thinking in terms of a cursor or even your model as a cassette tape, I think that gives me a model, not just for enumerators, but then for better understanding that external iterator pattern. Like, I'm now not going to think of if I'm ever reading through the Gang Of Four book, or some other languages say we're an doing External Iterator Pattern, and I'll immediately be like, oh, that's a cursor, or that's a cassette tape. STEPHANIE: Yeah, very cool. I like it. JOËL: Another mental model that I have is thinking of enumerator in terms of a lazy collection. This is something that you tend to see more in functional programming languages, so the idea that you have a collection of potentially infinite length, or it could even be unknown length. But each element only sort of comes into being as you attempt to read it. So, it's kind of, like, a potentially infinite chain of Schrodinger's boxes. And you've got to open each of them to find out what's inside. STEPHANIE: Do you know what this reminded me of? Like elementary school math questions that were like, "What comes next in this pattern?" And it has, like, you know, the first, like, four or five values in a sequence or something. And then, you have to figure out, like, what the next value is. But then, in some ways, you know, I think it can depend on whether your enumerator is using the previous value to determine the next one. But yeah, it's like, you can't just jump ahead to figure out what the 10th, you know, value in this pattern is without kind of knowing what's come before it. JOËL: And sort of that needing to step through the entire collection, sort of one element at a time. STEPHANIE: Yeah, exactly. JOËL: I think a way that that concept is interesting, to me, is situations where a collection might be expensive, and you don't necessarily need all of it. So, you might have a bunch of calculations, but you can stop when you've hit the first one that succeeds or that matches a certain criteria. And so, it's not worth it to calculate the entire array of calculations if you're going to stop at the third one. And you could do that with some sort of, like, loop or something like that. But having it as a collection means you get to just treat it like an array, and you can call detect on it and do all the nice things that you're used to. It just happens to be a little bit more efficient in terms of not creating more data than you need to. STEPHANIE: Yeah. And I think there's some really cool stuff you can do when you start chaining enumerators with this concept of it being lazy evaluated. So, one of the things I learned in my deep dive is that when you are using the lazy method, you're able to chain enumerators. And they work a bit differently, where the default functionality is, like, everything in the collection gets evaluated through the first method, and then it gets iterated over in the second method. Whereas if you use lazy, I believe how it works is that, like, the first value gets kind of processed by all of the methods. And then, you get, you know, the output before moving on to the second, like, the next value. Does that sound right? JOËL: Yes. And I think that's where there's often a lot of confusion because there's sort of plain enumerator, and then there's a lazy enumerator that Ruby provides. A plain enumerator is a lazy list in the sense that items don't get evaluated unless you try to reach for them. So, if you have an enumerator and you say, "Just give me the first five items," it will do that. And even if the collection was 200 items long, the next 195 don't get evaluated. So, that's very efficient there. Where you would get into trouble is that plain enumerators are not lazy when it comes to traversals. So, any method that would traverse the entire collection, so something like a map or a select, is not going to be lazy because it's going to traverse the entire collection, therefore forcing us to evaluate each of the items in there. Whereas something like enumerable lazy will not actually traverse the collection when you do your map or you're selecting. It will wait for you to say, "Give me the first item," or "Give me the first ten items," or something like that. But you don't always need lazy. You really only need lazy when you're doing a traversal method. STEPHANIE: Okay. Cool, cool, cool. That makes a lot of sense. JOËL: I think a sort of spinoff metaphor that I have there is this idea of a lazy list. Another concept that, in my mind, is very adjacent to lazy lists is the concept of streams. And streams I typically think of them in terms of, like, files or networking, things like that. But a thing that you can do let's say you're working on data that's in a very large file, so big that you can't fit it into memory, a common solution there is streaming it. So, you don't load the entire file into memory and then operate on it. Instead, little chunks of it are loaded into memory. You operate on them, and then you release that memory and load the next chunk. So, you sort of work through that file in chunks, but you'd only have, you know, 1 line or ten lines or however big your chunk is in memory at a time. An enumerator allows you to do that with things that are not files. So, this could be a situation where, let's say, you're reading a lot of data from the database. You just have too many rows. You can't load them all into memory at once. But you do want to traverse through them. You could chunk that using enumerator so that every, you know, it loads 100 rows at a time or 1,000 rows at a time, or something like that. And your enumerator allows you to treat that as though it's a single array, even though, in the background, it's being chunked into pieces so that you never have more than a thousand rows at a time in memory. So, it allows you to do some, like, really nice sort of memory performance things. STEPHANIE: When would you want to use this over kind of something like batching queries? JOËL: So, I think ActiveRecord findinbatches does something like this under the hood. STEPHANIE: Oh, cool. JOËL: I don't know if they use Ruby's enumerator or if they sort of build their own custom extension to it, but it's built on this idea. STEPHANIE: Okay, that's really neat. I have another mental model that I wanted to get your thoughts on. JOËL: Yeah! STEPHANIE: One of the ways that I looked up that you can construct an enumerator, an infinite enumerator like we were talking about a little bit earlier, was with the produce class method. And that actually got me thinking about a production line and this idea that, you know, you have this mechanism for, you know, producing some kind of material or, like, good or something like that. And it's just there and waiting and ready [laughs] for you to, like, kind of ask for it, like, what it needs to do. And you can do that, like, sometimes in batches, right? If you are asking for like, "Okay, I want a thousand units," and then the production line goes to work [laughs]. But yeah, that was another one of those things where I'm like, wow, they really, I think, came up with a cool method name that evoked, like, an image in my head. JOËL: That's the power of naming, right? And I think it's interesting you've mentioned twice how going through the method names on enumerator and finding different method names all of a sudden, like, turned on a light bulb in your mind. So, if you're naming things well, it can be incredibly useful for users of your library to pick up on what you're trying to do. So, I want to circle back to something that you mentioned earlier, the idea of elementary school quizzes where you have to, like, figure out the next item in the sequence. Because that, for me, is very similar to my mental model: the idea that an enumerator is a sequence generator. So, instead of thinking of it as, oh, it's like an array or it's some kind of collection, instead, think of it as a robot that I can just ask it, hey, give me a value, and it will give me a value. And then, it will, like, keep doing that as long as I keep asking it for it. And those values, you know, they could be totally random. You can build one of those. But you can also have it so that the values sort of come from a sequence. It's not like an array where you're like, oh, I'm going to, like, predefine an array of, I don't know, the Fibonacci sequence, and when someone asks me for the third value, I'll just go and read that third value from the array. Instead, it knows the algorithm, and it just says, "Oh, you want the next value in the Fibonacci sequence? Let me calculate it. Here it is. Oh, you want the next value? Here it is." And so, thinking from that perspective helped me really come to terms with the concept that values really do get calculated just in time. It's not really a collection. It's an object that can give you new values if you ask it. STEPHANIE: Yeah, okay. That is making a lot more sense kind of in conjunction with the lazy list model that you shared earlier, and even a little bit with the production line that I was kind of sharing where it's like, you know, in this case, kind of, it's, like, the potential for a value, right? JOËL: Right, exactly. And, you know, these are all mental models that converge on the same ideas because they're all just slightly different perspectives on what the same object does. And so, there is going to be some overlap, some converging between all of them. I have another fun one. Can I throw it at you? STEPHANIE: Please. JOËL: This one's a little bit different, and it's the idea that enumerators are a tool to bring your own iteration to a collection. So, imagine a situation where you're building your own, let's say, binary tree implementation. And there are multiple ways to traverse through a binary tree. In particular, let's say you're doing depth-first search. There are sort of three classic ways to traverse that are called pre-order, post-order, and in-order traversals. And it really is just sort of what order do you visit all the children in your tree? Now, the point of a collection, oftentimes, is you need a way to iterate through it. And a classic solution would be to include enumerable, the module. In order to do that, you have to define a way to iterate through your collection. You call that each. And then, enumerable just gives you all the other nice things for free. The question is, though, for something like a tree where there are multiple valid ways to traverse, which one do you pick to make it the each that gets sort of all the enumerable goodies, and then the others are just, like, random methods you've defined? Because if you define, let's say, pre-order traversal as each, now your detect and select and all those are going to work in pre-order, but the others are not going to get that. So, if you map over a tree, you're forced to map over in pre-order because that's what the library author chose. But what if you want to map over a tree in post-order or in-order? STEPHANIE: Yeah, well, I'm guessing that here's where enumerator comes in handy [laughs]. JOËL: Yes. The approach here is instead of designating sort of one of those traversals as the sort of blessed traversal that gets to have enumerable; you build three of these, one for each of these traversals. And then, what's really nice is that because enumerators are themselves enumerable, they have map and select and all of these things built in. Now you can do something like mytree dot preorder dot map or mytree dot postorder dot map. And you get all the goodies for free, but the users of your library get to basically choose which traversal they want to have. As a library author, you're not forced to pick ahead of time and sort of choose; this is the one I'm going to have. You sort of bring your own traversal by providing an enumerator, and then everything else just kind of falls into place. STEPHANIE: Bring Your Own Traversal (BYOT) [laughter]. I like it. Yeah, that's cool. I can see how that would be really handy. I have not yet encountered a situation where I needed to get that deep into how my iteration is traversed, but that's really interesting. And, I mean, I can start even imagining, like, having an each method defined in these different ways, and then all of that being able to be composed with some of the other...just other methods. And now you have, like, so many different ways to perhaps, like, help, you know, different performance use cases. JOËL: Yeah, it can be performance. I often tend to think of enumerator as a performance thing because of its sort of lazy properties because; it allows you to sort of stream or chunk data that you're working with. But in the case of this mental model of the Bring Your Own Traversal, it actually is more about flexibility and having sort of the beauty of Ruby without having to compromise on, oh, I have to pick a single way to traverse a collection. STEPHANIE: But I really appreciate kind of this discussion about enumerator because this was previously, like, I don't think I have really ever used the class itself to solve a problem, but now I feel a lot more equipped to do so with a couple of the different kind of perspectives. And I think what they helped me do is just prime myself. If I see a problem that might benefit from something being iterated in a lazy way, like, being like, oh, I remember this thing, this mental model. Now I can go kind of look at the documentation for how to use it. And yeah, like, I don't know how I would have stumbled across, like, reaching for it otherwise. JOËL: That's a really interesting thing to notice because we've been talking a lot about how mental models can be a tool for understanding. But once you build an understanding, even though it's somewhat fuzzy, they're also a great tool for sort of recall. So, not only are you thinking, okay, well, this mental model says enumerators are kind of like this, or they function in this way. On the flip side of it, you can say, "Well, lazy evaluation problems are often enumerator problems. Like, streaming or chunked data problems are often enumerator problems. Multiple traversals are enumerator problems." So, now, even though you don't, like, fully understand it in your mind, you've got that recall where you can enter it, where you can come across that problem, and immediately you're like, oh, I'm dealing with multiple traversals here. I don't remember exactly how, but somehow, in my mind, I've got a connection that says, "Enumerators are a solution for this. Let me dig into that." STEPHANIE: Yeah, especially as an alternative to where I would normally reach for something...a more kind of common enumerable method. Because I definitely know that feeling of like, oh, like, I wish it could just, like, do this a little bit differently, you know. And it turns out that, you know, something like that probably exists already. I just needed to know what it was [laughs]. JOËL: On that theme of I wish that I could have something that behaved just a little bit more...like, I'm doing something slightly weird, and I wish they would behave more, like, just plain Ruby does normally with my, like, collections I'm familiar with. I'm going to pitch a talk that I gave at RubyConf Mini called "Teaching Ruby to Count." Some of these mental models actually showed up there. But the whole idea is like, oh, if you're bringing in sort of more custom objects and all of that, how can you just tweak them a little bit so that they're just as joyful to use and interact with as arrays, and numbers, and ranges? And they just sort of fit into that beauty of Ruby that we get out of the box. STEPHANIE: Awesome. On that note, shall we wrap up? JOËL: Let's wrap up. STEPHANIE: Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeee!!!!!!! AD: Did you know thoughtbot has a referral program? If you introduce us to someone looking for a design or development partner, we will compensate you if they decide to work with us. More info on our website at: tbot.io/referral. Or you can email us at: referrals@thoughtbot.com with any questions.

The Bike Shed
427: RailsConf Recap and Conversing About Coupling

The Bike Shed

Play Episode Listen Later May 28, 2024 37:03


Joël and Stephanie talk RailsConf! (https://railsconf.org/). Joël shares how he performed as a D&D character, Glittersense the gnome, to make his Turbo features talk entertaining and interactive. Stephanie's talk focused on addressing test pain by connecting it to code coupling, offering practical insights and solutions. They agree on the importance of continuous improvement as speakers and developers and trying new approaches in talks and code design, and recommend Jared Norman's RailsConf talk on design patterns, too! That One Thing: Reduce Coupling for More Scalable and Sustainable Software (https://www.informit.com/articles/article.aspx?p=2222816) Connascence.io (https://connascence.io/) [Connascence as a vocabulary to discuss coupling](https://thoughtbot.com/blog/connascence-as-a-vocabulary-to-discuss-coupling](https://thoughtbot.com/blog/connascence-as-a-vocabulary-to-discuss-coupling) The value of specialized vocabulary (https://bikeshed.thoughtbot.com/356?t=0) Transcript: We're excited to announce a new workshop series for helping you get that startup idea you have out of your head and into the world. It's called Vision to Value. Over a series of 90-minute working sessions, you'll work with a thoughtbot product strategist and a handful of other founders to start testing your idea in the market and make a plan for building an MVP. Join for all seven of the weekly sessions or pick and choose the ones that address your biggest challenge right now. Learn more and sign up at tbot.io/visionvalue.  JOËL: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Joël Quenneville. STEPHANIE: And I'm Stephanie Minn. And together, we're here to share a bit of what we've learned along the way. JOËL: So, Stephanie, what's new in your world? STEPHANIE: So, I think I can speak for both of us and say what's new in our world is that you and I just came back from RailsConf in Detroit. JOËL: Yeah, we were there for, I guess, it's a three-day conference. Both of us were giving talks. STEPHANIE: Yeah. I don't think we've both spoken at a conference for at least a little over a year, so that was really fun kind of to catch up in person. And there was a whole crew of thoughtboters who were there. Yeah, I feel like we were hanging out, like, a lot [chuckles] all of last week, just seeing each other, talking about, you know, rehearsing our talks and spending time together on...there was, like, a hack day, and we were sitting at the table together. So, I feel like I'm totally caught up on everything that's new in your world, and that's it. That's the end of the show [laughs]. JOËL: On that note, shall we wrap up? STEPHANIE: [laughs] That would not be very fair to our listeners. [laughter] JOËL: Yeah. So, how was the conference speaking experience for you? STEPHANIE: Ooh, it was really great this year. I have not spoken at a RailsConf before, so this was actually, I think, a bigger stage than I had experienced before, and I had a great time. I met Ruby friends, new and old, and, yeah, I left feeling very gooeyed, and very energized, and just so grateful for the Rails community [laughs]. Yeah, I had a very lovely time, kind of being a little bit outside my normal life for a few days. And I think my favorite part about these things is just like, anywhere you go, you can kind of just have a shared interest with someone, and you can start a conversation with them. JOËL: That's really interesting. Do you find yourself just reaching out to strangers at conferences like this? Or do you tend to just hang out with the people that you know? STEPHANIE: Oh, I think a little bit of both. I like to get meals with people I know. But if I'm just hanging out in, like, the lobby or if I happen to get a seat for a talk and I'm sitting next to someone that I don't know, I find it quite easy to just be like, "Hi, like, I'm Stephanie. Are you excited for this talk?" Or, like, "What good talks have you seen recently?" There's an aspect of, like, the social butterfly that comes out of me when I'm at these things. Because I just don't get to have, like, easy access to, I don't know, people with, like, that shared interest or people who are willing to just have a conversation with you normally, I think. JOËL: Yeah, would you describe yourself more as an introvert or an extrovert? STEPHANIE: I am an extroverted introvert [laughter]. I feel like maybe that might be interpreted as a non-answer, but I think I lean more on the introvert side. But you know when you're with a group of people, and there's not, like, a very clear extrovert in that conversation, and then you're like, oh, I have to do the heavy [chuckles] lifting of the social lubrication [laughs] in this conversation, I can step into that role, reluctantly [laughs]. JOËL: Okay. I like the label that you used, the extrovert introvert, in that I enjoy social situations. I do well in social situations. But they also consume a lot of energy for me. I don't necessarily get sort of recharged by doing social events. So, people will be surprised when they find out that I tend to talk about myself as an introvert because, like, "Oh, but you're, like, you know, you're not awkward. You engage very well in different group situations." STEPHANIE: You have a podcast [laughs]. JOËL: And the truth is I enjoy those things, right? I really like social interaction, but it does, after a while, wear me out. STEPHANIE: Yeah, that makes sense. I did want to spend a little bit of time talking about the talk you gave at RailsConf this year: "Dungeons & Dragons & Rails." JOËL: I got to have a lot of fun with the theme. The actual content was introducing people to Turbo by building an interactive Dungeons & Dragons character sheet using vanilla Rails and a little bit of Turbo. So, we're not even writing any JavaScript. We're just using the Turbo helpers, a little bit of Action Cable to mimic something a little bit like...people who are in the know might be familiar with the site D&D Beyond, which is kind of the official D&D online character sheet website. Of course, it wasn't anywhere near as fancy because it's a 30-minute talk and showcasing different features, but that's what we were aiming for. STEPHANIE: Yeah, you know, you've talked a bit about giving talks on the show before, but I wanted to get into what made this one different because I think it could be fun for our listeners. [laughter] JOËL: The way I structured this talk so it has a theme. It's about Dungeons & Dragons, and we're building a character sheet. The way I wrote the talk was it's broken up into chapters. Each chapter is teaching a new feature in Turbo that I want to show off. In order to motivate learning each of these features...because I don't like to just say, "Oh, here's a thing that technology can do. Oh, here's a thing that technology can do." That's boring. You need a reason to learn that. So, I needed a reason to say, "We need to add this to a character sheet." So, every sort of chapter of the talk opens up with a little narrative portion. We're following this character, Glittersense, the gnome, and he's on adventures. And at different points in the adventures, he's going to do different types of roles or need different stats and things. And so, when we reach the point in the adventure where we need that, we sort of freeze frame and then say, "Okay, let's add that as a feature to the character sheet." And then, oh no, it turns out that this feature is a little bit more complicated. We're going to have to learn a new Turbo feature to do that. Who would have guessed? And then, we learn a new Turbo feature together. And then, we go back to the narrative portion. The adventures of Glittersense continue. And then, oh no, we're going to need to add another feature to the character sheet. And that's sort of how the talk is structured. STEPHANIE: Yeah. And you did a really cool thing with the narrative portions, which was you basically performed as Glittersense, the gnome, voice and posture, and a lot of really great acting from you [laughs], in my opinion. JOËL: That is something that came out pretty late in the talk preparation. So, I knew I wanted this kind of alternating story and code structure. Then, like, the weekend before RailsConf, I'm running through my slide deck, and I realized, you know what? What if instead of narrating Glittersense's adventures, what if I went first person for those sections? Glittersense tells his own story. And then, from there, it wasn't a big jump to say, you know what? This is D&D. If I'm going first person and narrating, I really should do a voice. And this is a conversation I had with a couple of people at the speaker dinner. And, of course, everyone's like, "You should 100% do the voice." And I was really not feeling confident in my ability to pull it off. So, for the next two nights, because I was speaking on the third day, the next two nights at the conference, in the evenings, I'm in the hotel room in front of the mirror just practicing my gnome voice to try to get something that got the persona of Glitterense, the gnome, across to the audience. STEPHANIE: How would you describe the persona? JOËL: Very extra. STEPHANIE: [laughs] JOËL: Very high energy. STEPHANIE: Yes. The name Glittersense is very extra, after all. JOËL: [laughs]. I punctuated a lot of the things that he says with just high-pitched laughter. He's also...so, the framing device for all of this is that you're in a tavern listening to him tell his adventures. I wanted a little bit of the sense that Glittersense is maybe embellishing a little bit. I think it may be too much to say he's full of himself, but he's definitely making himself to be the hero of the story, and maybe making himself to be slightly cooler than he really was. STEPHANIE: Yeah. I definitely got, like, a little bit of eccentricity, too, from the persona. And you know when you just, I don't know, meet an older person who has, like, a lot of life experience, and they want to tell you about it [laughter], but you do kind of maybe have a little bit of suspicion around how much they're exaggerating [laughs]. But it was really fun. Everyone I talked to afterwards, like, loved it. And I got to share the little nugget that, like, oh yeah, and Joël only, like, started doing the voice, like, decided that he was going to do it two days ago. And they were just all really, like, blown away because it seemed so well practiced, and it was really fun. JOËL: I got to do something really fun, also, with physical space because Glittersense narrates his portion, sort of the story portions, but then the code portions where we're talking about Turbo, I'm talking in my own voice. And so, when I'm talking about Turbo, I'm standing at the lectern. And when I'm Glittersense, I'm kind of off to the side on the stage and doing the voice. And so, there's this almost, like, two worlds that are inhabited: one by Joël, the speaker, and one by Glittersense, the gnome. And it got to the point where I don't say or do anything. I only move from the lectern to the, like, portion of the stage where Glittersense lives. And the audience starts chuckling and, like, nothing has happened yet, like, no jokes have been told. No voice has happened. No slides have changed. But the anticipation, people know what's coming. STEPHANIE: Yeah. And I think the best part, what I really found just really fun and, I don't know, every time it happened, I just really enjoyed it, when you transitioned out of Glittersense, the gnome, and back to Joël because you were so nonchalant about it. You kind of, like, straighten up rather than having your little kind of crouchy gnome posture, and then just walk across back to the podium. And then, in your normal voice, go back to just, you know, sharing very...not necessarily dry, but just, like, straight to the point. "And this is, like, how you, you know, create a frame in [laughs] Turbo," as if nothing happened [laughs] when even just, like, you know, 20 seconds ago, you were just enthusing about, like, slaying the bandit, chieftain [laughter] known as Glittersense. JOËL: Uh-huh. I think, especially when I open, so I get introduced. I'm off stage. I walk onto the stage, and I'm immediately Glittersense. And I'm telling a story, and the intro goes on for, like, quite a while. It's a big story chunk. And then, at some point, I just walk over to the lectern, drop the voice, hit next slide, and it's my title slide. I'm just like, "Okay, now welcome to Dungeons & Dragons on Rails. We're going to build a character sheet together." STEPHANIE: Yeah, that's exactly the moment I'm thinking of. JOËL: The walking in as Glittersense and just immediately going to the voice caught everyone by surprise. And then, the, like, oh, he keeps going for this. Is the whole talk going to be like this? And then, the, like, just when you think, oh, he's really going for it, the, like, dropping it and going to the podium and title slide. It wasn't intended to be a funny moment, but I think the contrast and the fact that I just switched over was one of the biggest laughs I got. STEPHANIE: Yeah, I mean, I think that attests to how good the delivery of it was because that contrast was very felt. So, props to you. JOËL: I love the idea of, you know, the thought that you put into building a talk and, like, the narrative structure and the pedagogy of the stuff. And, I think, in this particular case, this is almost like a narrative approach called in media res, where you start kind of in the middle. You open your book, or your movie, or whatever in the middle of the story. And then, you kind of come back to the beginning at some point later. So, it starts with some kind of action scene that grabs your attention. So, in this case, my title slide is 10, 15 slides into the talk. We get immediately started with Glittersense and his adventures. And then, once we're sort of all bought into this world, then we move to the title slide and talk about, okay, we're here to build a character sheet and all that stuff. And I think that it wouldn't have had the same impact if I'd, like, opened with that and then gone into Glittersense's adventures. And that's something that was not the case at the beginning. I really reworked the talk to make it in that order. And I think that the talk had a lot more impact for doing that. STEPHANIE: Yeah, definitely. I guess I also just wanted to point out that this is very different from all your other talks. And I think it's really cool that, you know, you are a veteran speaker, but you still find ways to do something new and try something that you've never done before, and yeah, find ways, new ways to, like, speak and engage people and teach. I don't know, do you have just any thoughts about why or how you got into a position to be like, "Oh, you know, I'm going to do something super different this time around" [laughs]? JOËL: So, every talk I give, I try to do something new, something different, to push myself as a speaker to get better. That might be in the writing of the talk; that might be in the delivery. More recently, I've been trying to do more with dynamic presence on stage. So, when I spoke at RubyConf San Diego, I was trying to not just stand at the lectern but to learn to be able to give my talk while also, you know, walking around the stage, looking at the audience, making pauses where it's necessary, not to just be so into the delivery of the talk by just standing at the podium and, like, going through my deck, which is a small thing but I think is an area I wanted to improve in. This time, I was playing around with some more narrative framing and ended up, yeah, like, pushing it to an extreme. And it works with the theme because inhabiting a character and role-playing is the core part of D&D. Not everybody plays a D&D character by doing a voice. You are a little bit extra if you do that. But it's not uncommon for people to do a voice. And so, it kind of fit perfectly with my theme. I just needed to get the self-confidence to do it. So, thank you to everyone at the speaker dinner that was like, "No, you totally got this. You should do this," because I was feeling very unsure. STEPHANIE: It really paid off, so... JOËL: I'd like to circle back to your talk, though. So, you gave, basically, the first talk of the conference. You were the first session after the keynote. A theme that came up multiple times in your talk was this idea of coupling and how it affects different parts of our code and, particularly the way that we structure tests or the way that we feel test pain. How did you, when you were prepping this talk, discover that theme and decide to lift it up? Was that something that you knew ahead of time you wanted to talk about, or did it just sort of emerge as part of the talk preparation process? STEPHANIE: That's a really great question, and I'm glad you picked up on that. So, my talk was called: "So, Writing Tests Feels Painful. What Now?" Originally, when I came up with this idea, it actually started with coupling. I realized that I wanted to give a talk about coupling because it's just something that I was struggling with or, like, had seen other people struggle with and really wanting kind of a discrete resource, wanting to provide that. But as I was just thinking about it, I was like, oh, like, there are so many different ways that this could go. On one hand, it was a very like important topic to me, but also maybe too big of a topic. And so, I actually, like, kind of put that on the back burner. And it wasn't until later when I connected it to another...it wasn't necessarily different at all, but just, like, an extension of this idea is, oh, like, people are struggling with coupling in tests or, like, it manifests in tests. And so, I thought maybe that could be the angle that I took on this topic that kind of gave me a little bit more focus. And I didn't even end up saying like, "Yeah, this talk was, like, born out of just, you know, wrestling with coupling or anything like that." So, it's cool, to me, that you picked up on it as a theme because it was...I had, you know, ended up not being super explicit about it, but it was certainly, like, a thing that was driving the content from my perspective. JOËL: Interesting. So, it started as a coupling talk and then got sort of focused through the lens of testing. STEPHANIE: Yeah. And I think there was a part of me that was like, you know, I don't know if I could just teach the concept of coupling, like, by itself without the framing of testing for people who this is, like, a new concept for them. I realized that maybe it would be more effective to be like, "Hey, like, have you experienced test pain? You know, have you had to mock out a billion objects or changed, you know, made one change and then had to fix, like, a million tests subsequently? Then this talk is for you." And then weave in the idea of coupling in it to kind of start to help people feel familiar with it or just, like, identify it without as much, like, jargon as kind of I've seen when I've tried to figure out, like, how to manage it. JOËL: It's interesting because I think it gives you a, like, concrete, valuable thing to optimize for as opposed to, like, hey, let's lower coupling because then you're writing, you know, quote, unquote, "better code." And you get to feel better about yourself as a programmer because you're doing things the, quote, unquote, "right way." That's very kind of hand-wavy, and I think sometimes leads people down a bad path where they're optimizing things that they shouldn't be. But the tests give you this very concrete way to say, "Hey, we're not just trying to reach the, like, low score record for the app in terms of coupling. We're trying to reduce test pain. Tests are painful. And that pain is telling us something. It's telling us that we've crossed some sort of threshold for coupling. Let's find ways to reduce it, not so that we can feel good about ourselves, but so that our tests are actually manageable." STEPHANIE: Yeah, I am really glad you picked up on that, too, because I feel the exact same way when someone just tells me to decouple something or, like, makes a note that, like, oh, this feels really coupled. I don't know what that means necessarily. And it's not very convincing to just be like, "Oh, you should write loosely coupled code [laughs]," at least for me. What you said just now, it's like, it's not to feel good about ourselves, you know, to write code that way, but, actually, to just feel good about our code, period [laughs]. And, yeah, finding that validation through just, like, actually working with code that is easier to change that is the goal, not necessarily to, yeah, kind of pursue some totally subjective, like, metric. JOËL: So, one of the kinds of coupling that you called out, I think, was where you hardcode a class name of some other class in your object. And that feels, like, really sort of innocuous. Like, of course, my objects can talk to other objects. And maybe I want to, like, refer to a class somewhere. Why is that such a like tricky piece of coupling to work with? STEPHANIE: It's not necessarily intentional sometimes. Like, you just do it because you're like, well, I need access to this class somewhere, and I happen to already be in this file. So, why not just hard-code it here? I do think it's a little tricky because the file that you're writing might be, like, very far down in, like, your code flow or, like, your code path, like, very far from, like, a controller or any kind of entry point into your system, at least based on what I've seen in a lot of modern Rails apps. And so, I think that coupling gets really, really obscured. I have found that, like, if I have to kind of write a more, like, a higher level test, like, maybe a request spec or something, there are times when I'm, like, having to deal with a lot of classes just to set stuff up in a test like that that I didn't think I would have to [chuckles] when I first went about trying to just be like, oh, like, let's just figure out how to get a 200 response [laughs] from this request. So, you're really burying perhaps the things that are needed to set up, like, that full path of execution. And sometimes, it only comes out when you're writing a test for it. JOËL: And you mentioned briefly, in passing, the idea that oftentimes this sort of coupling manifests as a lot of extra test setup because your object that you're trying to test now also needs all these other things that are related in order to be tested. But sometimes even when you hard code a class, though, you can't even just say, "Oh, I want this particular user or something returned." So, you have to then do something like allow this class to receive class method and return, and now you're stubbing. And I don't know how you feel about stubs in RSpec. I always treat them a little bit like a code smell in the like classic sense of it's not necessarily bad, but maybe pause, take a look, and ask yourself, "Why is that there, and should I do things differently?" STEPHANIE: Yeah. I ended up having, like, a lot of examples of stubbing in my example because the code had just been set up where that was the only way that you could access those collaborators, essentially, to, like, make an assertion on them, or have them do something different because you actually needed to go into a different path, right? And I was like, yeah, this should feel weird. You should feel a little bad [laughs] or at least, you know, kind of just pay attention to that feeling, even if you can't really do anything about it in that particular instance. But on the flip side, you know, it's like, yes, it feels a bit strange, you know, but it's not all bad, right? Like, you're kind of learning like, oh, hey, like, I am coupled to this hard-coded class because I am needing to stub, like, a class method that returns it, or that constructs it. And at least you've exposed that, you know, for yourself. One thing that I was running into a lot in my example, too, was that those things, like, weren't obvious when you were just reading maybe, like, the public methods and trying to figure out what was happening in them because they were wrapped in private methods. I was a little bit conflicted about this because there were times when it was already just a single method call, but then it was just kind of wrapped in a private method that actually hid [laughs] the things, like all the dependencies that were passed as arguments. And I found that to be, sure, it looks kind of cleaner. But then all you need to do is scroll down [laughs], and then you're like, oh, actually, there's all these other things involved, but it was kind of hidden away for me. And I found that, actually, like, at least when I actually needed to change things, less helpful than I imagine what the, you know, code author intended. Do you have any thoughts about hiding details like that? JOËL: I'm kind of a big fan. STEPHANIE: Hmmm. JOËL: The general idea, I think, is called the single level of abstraction principle. Whatever sort of public method that you're calling is often implemented in terms of...let's say it does a few different things. It's implemented in terms of, like, these sort of high-level concepts. So, whoever is reading the public method doesn't need to like care about the details of how each step is implemented. So, maybe you're fetching something from an API, and then you're making a database call, and then you're doing some transformation and creating some new objects from it. Having all of the, like, HTTP calls and the ActiveRecord stuff and the, like, transformation all in the public method, yes, there's a lot of complexity happening there, and it makes that obvious. But it also makes it really hard to get a sense of what is happening. So, I like to say, "Hey, there are four steps. Let's wrap them all each in a private method then you can call all of those in the public method." The public method now sort of reads like a very simple sort of script. First, fetch data from the HTTP API, then fetch some data from the database, then apply this transformation, then create this object. And if I'm mostly caring about what this object does and not the how let's say I'm building some other objects that interact with this, that is the information I want to know. Where I care about the actual implementation of, oh, well, exactly how is the ActiveRecord stuff done when I'm doing internal changes to the object, that's when I care about those private methods. I think where it gets tricky, and I think that's the point that you were bringing up, is that if you write code in that way, it has to change the heuristics of how you read code to detect complexity. Because, oftentimes, I think a very classic heuristic for code complexity is just line length. If you have a 50-line method, probably there's a lot of complexity there. Maybe there's a lot of coupling. If it's a four-line method that is written at a high level of abstraction that just calls out to private methods, you scan over. You're like, oh, nice and clean. Nothing to see here. Move on. And so, that heuristic doesn't really hold up in a codebase where you're applying this single level of abstraction. Do you think that lines up with your experience? STEPHANIE: Hmm. As I was listening to you, I was like, yeah, like, that makes total sense to me. But then I also clearly disagreed a little bit [laughs] in my initial...kind of what I was saying initially. And I think it's because that single layer of abstraction was not very well defined. JOËL: Hmm. That's fair. STEPHANIE: Yeah. Where, in fact, it was actually misleading. Like, it wanted to be at that level of abstraction, but it really wasn't. Like, it was operating on things at, like, a lower level and wasn't designed with that kind of readability in mind. So, it was more, like, it was just hiding stuff a little bit, at least for me. And, I think, it certainly would have taken, like, more work to figure out what that code, like, really was meant to convey. It might have taken some refactoring to coalesce at that single level. And that was essentially kind of what I was showing in my talk as, like, how to get to saying, like, "Hey, we actually are operating in the lower level, but I don't think we need to." There was some amount of, like, looking at all of the how to figure out, like, oh, maybe these things we don't even need to expose in this class. And we kind of got to a place where those details weren't, like, needed in that class at all. So, it's one of those things where it's harder than it sounds [laughs]. JOËL: It's definitely an art. STEPHANIE: Yeah. JOËL: And I think what you're saying about some of the coupling being, like, scattered throughout the class, it's something that I see a lot with situations where you're coupled, not so much to, like, a single class, but to something side effectful. So, you're building some kind of integration with a third-party API, and you're going to have to make a lot of HTTP calls. And each of those might be individually simple, and they're all sort of maybe in different private methods or whatever, or they're interspersed among a larger chunk of logic. And that makes your tests really complicated. But there's no, like, one place you can point at and be like, ooh, that's the one place where there's a lot of complexity. What's happening here, though, is that your business object that's doing stuff is coupled to the network, and that coupling is going to force you to do some stubbing. It's going to force you to deal with a bunch of side effects that are non-deterministic in your code. And you used the word coalesce earlier that I really liked because I think that's often a situation where you do have to stand back and say, "Look, there's a lot of HTTP going on here. What if I coalesced it all into an object? Now I have two objects: one that's responsible for business logic, and one that's responsible for just the HTTP calls." And, all of a sudden, the tests just totally simplify. And we've removed some coupling, but that's not something that you would have seen just from reading the code. Because, as you were saying, it's sort of scattered in little bits and pieces throughout your file that don't necessarily catch your eye. STEPHANIE: Yeah. Which brings me to a blog post that I had found a lot of inspiration from in the talk that I'll link. It's called "That One Thing: Reduce Coupling for More Scalable and Sustainable Software." But it's actually about tests [laughs], even though it doesn't make an appearance in the title of the blog post at all. But this is where I kind of got the idea of necessary versus unnecessary coupling in test. Because I had never thought about how, yeah, like, when you write a test, you are very correctly coupling yourself to at least the method and class under test [laughs], if not also the arguments, right? Or anything else needed to construct what you're testing. And literally having that listed out for me in this blog post I think it's a...they use some examples in Java. And so, there's, like, a little bit more [laughs] setup involved. But I think they're like, yeah, these are six things that, like, it's mostly fine if you're coupled to these because that's kind of what needs to happen in a test. But, like, even having something to compare a test I wrote to just, like, okay, these are the things I know I need. And then, you can start to see when you've diverged from that list, when you are finding yourself coupled to some internals of your class. I really...that was actually, like, really helpful for me because, as we talked about earlier, like, it can be kind of communicated so abstractly. But here is, like, a very clear heuristic for when you should at least, like, start to pay attention or be like, oh, this is something that was needed to get the test to run but is now starting to feel a little unnecessary because it's not on this list. JOËL: That list reminds me, or the idea of a list of things to check out for when thinking about coupling, reminds me of the concept of connascence, which is a fancy word for almost a, like, categorization of different types of coupling because coupling comes in different flavors, some of which are tighter forms of coupling than others. And so, having that vocabulary has been really helpful for me when I'm looking at PRs and code review, or even when I'm refactoring my own code. Kind of like that list that you mentioned that you have, now I have some heuristics to look at that and say, "Oh, can I go from a connascence of position to a connascence of naming, and does that help me?" STEPHANIE: Yeah, I like that you mentioned the positional connascence because I also came across a really great metaphor for kind of things that need to change together, like, when that makes sense. And it was basically the idea of a dishwasher and a laundry machine [laughs]. I wish I could recall, like, what book this was from. But it was basically like, oh yeah, like, in theory, you're washing two things. So, maybe they are similar, but then you're like, no, actually, you want these to be a little bit separate because, you know, you don't want to wash your dishes and your clothes in the same machine. I don't know, maybe that exists [laughs], but I don't think it would do a very good job for either goal. And I think that was really helpful, for me, in imagining, like, the difference between kind of coupling and cohesion, like things that...even just imagining, like, kind of where I'm doing those things in the house, right? It's like, okay, that lives in a separate room. And, like, the kitchen is for the dishes, and that could be like, you know, a module if you will. And, like, laundry happens in the laundry room, and how to kind of just separate those things, even though they also do share some qualities, too. Like, they're both appliances, right? And so, that's the way that they are similar, but they're not the same. JOËL: You just mentioned the sort of keyword cohesion. And for our listeners who are not familiar with that term, it refers to an object sort of having one thing that it does well. Like, everything in that class sort of works towards the same goal, kind of similar to the idea of the single responsibility principle. So, in my earlier example, where we're sort of interspersing some business logic, a lot of HTTP requests, and pulling out an object that's focused on HTTP, like everything is based around that, now that object has higher cohesion because it's all doing one thing. So, if you read classic object-oriented literature, the recommendations that you'll typically see are that objects should have high cohesion and low coupling. STEPHANIE: Yeah. Think of a dishwasher and a washing machine next time [laughs] you come across something like that. Because I feel like those are really great, like, real-life examples of that separation. JOËL: Did you go to Jared Norman's talk on the third day: "Undervalued: The Most Useful Design Pattern"? STEPHANIE: No, I didn't. Can you tell me about it? JOËL: It felt like he was addressing a lot of the same themes as you were but from more of a code perspective than a test perspective. Talking a lot about, again, forms of coupling, dependencies, and then, specifically, one of the tools that he focused on to reduce the coupling that we see is value objects and factory methods to construct those. So, for any of our listeners who, when the talks come out, watch Stephanie's talk and are like, "Wow, I would love to learn more about this," a great follow-up, Jared Norman's talk: "Undervalued: The Most Useful Design Pattern." STEPHANIE: Yeah, that's neat because I can see that being a solution to the hard code did class names that we were talking about earlier. And I like how that is kind of, like, a progressive lesson in coupling a little bit. I'm really glad you shared that talk with me because now I'm excited to watch it when it comes out. And in general, I just love learning new vocabulary or finding new ways to speak about this topic with clarity. So, if any of our listeners have just additional mental models for coupling [laughs] different metaphors, different household appliances [laughs], or something like that, I would love to know. JOËL: You would like that, given that our first episode together was about "The Value Of Specialized Vocabulary." STEPHANIE: Yeah, it's clearly undervalued. JOËL: Haha, I see what you did there. STEPHANIE: Thank you. Thank you very much [laughs]. JOËL: On that terrible/wonderful pun, shall we wrap up? STEPHANIE: Let's wrap up. Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeee!!!!! AD: Did you know thoughtbot has a referral program? If you introduce us to someone looking for a design or development partner, we will compensate you if they decide to work with us. More info on our website at: tbot.io/referral. Or you can email us at: referrals@thoughtbot.com with any questions.

vision detroit mvp dragons tests dungeons api turbo java javascript rails prs mandy moore coupling conversing d beyond quenneville railsconf activerecord rspec stephanie you stephanie how stephanie yeah stephanie it stephanie thank stephanie no stephanie oh action cable
The Bike Shed
423: Cognitive Strategies for Coders

The Bike Shed

Play Episode Listen Later Apr 16, 2024 39:52


Stephanie is back with a book recommendation: "Thinking in Systems" by Donella Meadows. This book has helped to bolster her understanding of complex systems in environmental, organizational, and software contexts, particularly through user interactions and system changes. Joël describes his transformative experience watching last week's total solar eclipse. Together, they explore how systems thinking influences software development and team dynamics by delving into practical applications in writing and reading code, suggesting that understanding complex systems can aid developers in navigating and optimizing codebases and team interactions. Transcript:  JOËL: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Joël Quenneville. STEPHANIE: And I'm Stephanie Minn, and together, we're here to share a bit of what we've learned along the way. JOËL: So, Stephanie, what's new in your world? STEPHANIE: I have a book recommendation today [laughs]. JOËL: Oh, I love book recommendations. STEPHANIE: It's been a little while, so I wanted to share what I've been reading that I think might be interesting to this audience. I'm reading Thinking in Systems by Donella Meadows. Joël, are you familiar with systems thinking theory at all? JOËL: Very superficially. Hearing people talk about it on, I guess, X, now Twitter. STEPHANIE: Yeah. Well, what I like about this book is the subtitle is A Primer on Thinking in Systems [chuckles], which is perfect for me as someone who also just kind of understood it very loosely, as just like, oh, like, I dunno, you look at things holistically and look at the stuff, not just its parts but from a higher perspective. JOËL: Yeah. Is that accurate sort of your pre-book reading overview? Or do you think there's a bigger thing, a bigger idea there that the book unpacks? STEPHANIE: Yeah. I think I'm only, like, a third of the way through so far. But what I have enjoyed about it is that, you know, in some ways, like, intuitively, that makes a lot of sense about, like, oh yeah, you want to make sure that you see the forest for the trees, right? But one thing I've been surprised by is how it's also teaching me more technical language to talk about complex systems. And, in this case, she is talking about, essentially, living systems or systems that change over time where things are happening. I think that can be a little bit confusing when we also are, you know, talking about computer systems, but, in this case, you know, systems like environments, or communities, or even, you know, companies or organizations, which is actually where I'm finding a lot of the content really valuable. But some of the language that I've learned that I am now trying to integrate a little bit more into how I view a lot of just, like, daily problems or experiences involve things like feedback loops that might be reinforcing or balancing and different, like, inputs and output flows and what is driving those things. So, I've appreciated just having more precise language for things that I think I kind of intuited but didn't exactly know how to, like, wrap up in a way to communicate to someone. JOËL: Do you think the idea of thinking in terms of things like self-balancing versus sort of diverging input loops is something that's useful when actually writing code? Or do you think of it a little bit more in terms of, like, teams and how they organize general problem-solving approaches, things like that? STEPHANIE: I think the answer is both. I actually gave this quite a bit of thought because I was trying to wrap my head around her definition of a system and how we talk about systems sometimes, like, a codebase, for example. And the conclusion I came to is that, really, it's not just the code static by itself that we care about. It's how it gets exercised, how users use it, how developers change it, how we interact with it when we, like, run tests, for example. So, that was really helpful in kind of thinking about some of the problems we see in engineering organizations as a result of software being a thing that is used and written by humans, as opposed to it just existing in memories [chuckles] or, like, it's in a storage system somewhere. Like, that means it's kind of lifeless, and it's not changing anymore. But the point of kind of this framework is trying to understand it as it changes. JOËL: So, kind of that blurry line between humans and computers and where those two overlap is where a lot of that systems thinking almost, like, mental model or vocabulary has been most helpful for you. STEPHANIE: Yeah, I would say so. So, Joël, what's new in your world? JOËL: So, I did the thing. I traveled to see the total solar eclipse this past weekend. It was mind-blowing. It was incredibly cool. I really loved it. For any of our listeners who have never seen a solar eclipse, in the coming years, have an opportunity to see one. I'd say it's worth traveling to see because it is really impressive. STEPHANIE: Cool. What did it look like when it happened, when it was 100% eclipsed? JOËL: So, what really impressed me was the fact that, like, most of the cool stuff happens in that, like, last half a percent. So, like, 95% eclipsed, still not that impressive. If that's all I'd seen, I would be disappointed. And then, in that last little bit, all of a sudden, everything goes dark. It's sort of, like, that twilight past sunset. You've got a glow on the horizon. The stars are out. STEPHANIE: Wow. JOËL: The animals are behaving like it's past sunset. They're getting ready to go to sleep. STEPHANIE: Whoa. JOËL: The sun itself is just a black dot with this, like, big fiery ring around it. Like all those pictures, icons, photos you see online, or drawings that look over the top, those things are real. That's what it looks like. STEPHANIE: Wow, that's really neat. Could you see it without looking through the eclipse viewers? JOËL: So, when you hit totality, you can look at it with a naked eye, and it is, yeah, magnificent. STEPHANIE: Oh, that's so cool. How long did it last? JOËL: So, it depends where you are in the path of totality. I was pretty much dead center. And it lasts, I think, three and a half minutes is what we had. STEPHANIE: That's so cool. So, for me, here in Chicago, we did not have complete totality. It was about, like, 95%. So, I was watching it, just from that perspective. And I would say, yeah, it was not nearly as cool as what you described. It kind of just was like, oh, it got dark. It almost looked like I was viewing the world through sunglasses. I did have one of those viewers that I used to, like, look at the sun and see how much of it had been covered. But yeah, it was cool. But what you said, I think now I feel like, wow, I really should have [laughter] traveled. I could have traveled just a few hours, you know, to, like, Indianapolis or something to have been on the path. That would have been really neat. And I don't think the next one will be until 2044 or something like that. JOËL: Yeah. And that's the thing, right? I think if you're within a few hours of the path of a total eclipse, it is absolutely worth traveling to totality. The downside of that is that everybody else has the same idea. And so, you will be fighting traffic and a lot of things, especially if it goes through some, like, populated areas, like it did this time. STEPHANIE: Yeah. Well, that's really neat that you got to see that. That's, I don't know, it sounds like not exactly once in a lifetime, but definitely very rare. JOËL: For sure. I think with this experience now; I would definitely consider traveling again if there's one, like, anywhere near where I live, or, you know, maybe even, like, planning a vacation around going somewhere else to see one because it's short. You know, you're there for three minutes, and you see something cool. But that was really impressive. So, something that really struck me when you were talking earlier about systems thinking is that you mentioned that it gave you a sort of a new vocabulary to talk about things. It almost gave you a sort of different way of thinking or some other mental models that you could use to apply when you are interacting in that sort of fussy boundary between people and code. And I think that this idea of having language and having mental models is something that is incredibly valuable for us as programmers in a few different areas. And I'd be curious to see particularly for when we're reading other code, reading code that someone else has written or, you know, yourself from six months ago, do you have any sort of mental models that you like to reach for or techniques that you like to use to sort of give yourself that almost vocabulary to understand what somebody else is trying to do with their code? STEPHANIE: Yeah, I would say so. You know, as you were talking about, like, how do you read code? I was thinking about how I read code is different from how I would read a book [laughs]. I almost rarely just read everything line by line and, like, file by file, you know, in some order that has been presented to me. I am usually a lot more involved. It's almost, like, more like a choose your own adventure kind of book [chuckles], where it's like, oh, go to this page to check if you want to check out what happened down this code path [chuckles]. JOËL: Right, right. Oh, if you're reading a novel, are you the kind of person that will read the ending first? STEPHANIE: Absolutely not. [laughter] JOËL: You have strong opinions here. STEPHANIE: Even when I, like, really want to... okay, sometimes I will, like, maybe just kind of flip to the back and just see, like, oh, how many more pages or chapters do I have [laughs] left? If I am itching to know what might happen. But I definitely don't start a book by reading the end. I think there are people who do that, and maybe that works for them, but I don't understand it. [laughter] JOËL: But maybe that's the thing that you do with your code. STEPHANIE: Yeah. When I read code, it's almost always with some kind of intention to understand a particular behavior, usually kind of kicked off by some action, like, done by the user or something automated. And I want to understand that process from start to finish. So, I'm less likely to read a whole class file [chuckles], as opposed to just following method and the messages that are sent along the way in a process. JOËL: That makes sense. Do you tend to sort of go from kind of the origin point and then follow it down, or sort of the opposite, find some, like, terminal node and then work your way back? STEPHANIE: Oh. JOËL: And I could imagine this in a more concrete sense in a Rails app. You find, like, the route that you're going to hit because you know it's a URL, and then you find the controller, and then you read through the action. And then, you maybe follow a service and something like that or look into the view. Or maybe the opposite: there's a particular page that gets rendered. You look at a method, a helper method that gets called in a view, and then you sort of, like, follow a backtrace from there. STEPHANIE: Yeah, I think both. It depends on what information I have available to me, I think. I can think of, recently, I was trying to figure out the process for which, like, a user in this application I'm working on can downgrade the tier of their account, and I didn't know what to grep for. And so, I asked, like, "Hey, like, what are the entry points for a user being able to do this?" And someone gave me a couple of routes, and that was great because then I got to see, oh, that this is possible in multiple ways. Like, the user can do it themselves, or the admin can do it, and that was really helpful. Other times, I think I have been able to find a keyword on a page and start from, like, a view or a component, or something like that, and then work upwards. JOËL: I love that question that you asked, "What are the entry points for this thing?" I feel like that's a fantastic question to sort of ask yourself when you're feeling stuck, but it's also a great question to ask other people that might know. Do you find that you read code differently when you're just trying to, like, maybe understand a broader subsystem? Maybe you're sort of new to this area and you have to add a feature, as opposed to maybe you're debugging something and trying to understand why things went wrong. Are those two different kinds of reading? STEPHANIE: Yeah, that's also a great point because I do think there's another time when I've just scanned the file structure of an app and looked at the model's directory and just kind of been like, okay, like, maybe some things are namespaced. And that helps me just know what the main concepts that I have to be dealing with or that I will be dealing with are. But I find that sometimes less fruitful because of kind of what I mentioned earlier about thinking in systems, where I'm not sure how important those things will be yet because I don't know how they're used. They could not be used at all [laughs]. And then, I think I'm potentially, like, storing information that is not actually relevant in my brain. JOËL: That's tough, right? Because systems are so big, we can't hold them entirely in our brain. So, sometimes, selectively deciding what will not be loaded in there is just as important as what will. STEPHANIE: Yes. And I think that is actually advice that I would give to devs who are trying to get better at reading code. And this one's hard because when I am working with more early-career developers, it's hard to figure out, like, what are they seeing? How are they interpreting the code on the page? Because oftentimes, I see that they are getting stuck on the details, whereas I would like to encourage them to just be like, you don't really need to know what's going on in that method right now. Does the method name kind of communicate enough to you, like, what this thing is doing without having to understand all of the details? But my advice would be to start figuring out what to ignore [laughs] because, like you said, it's impossible to, like, hold all of that information at one time. What do you think about that advice and, like, how do you teach that to someone? JOËL: I think you're sort of hinting at two different ways of reducing the amount you have to load in your mind. The way I think about it, I think of it sort of spatially, so you can reduce the breadth of things you have to load into your head, so, realize, wait, there's all of these methods, and I don't need to know all of the methods in the file. There's only this one entry point I care about and everything downstream of that, and you just sort of prune everything off to the side, ignore it. That's not relevant right now. But there's also sort of a depth. How deep of implementation do you really need to have? Maybe you only need to know about the high-level concepts. And then, you sort of, like, do this pruning where you say, "I'm not going to go deeper than this level," because the implementation is not really relevant to what I'm trying to understand right now. I mostly need to know what are these classes and how do they interact with each other? Or something along those lines. And, ideally, you're may be doing a little bit of both. You probably don't need to go all the way to the deep implementation of every method, but you also don't necessarily need to know all of the high-level concepts and all of the objects in the system that interact. So, being able to prune in sort of both dimensions, breadth and depth, helps you to, I think, narrow the window of what you need to learn. STEPHANIE: Yeah, that's a really great point. I have a couple more strategies that I just thought about as you were talking about that. One is kind of on the journey to let go of some things that I can't understand in the moment. If they seem important, I will write them down and, like, put them somewhere in a list to come back to later and be like, "This is a thing I don't fully understand yet," and just be okay with that. I think, for me, there is some anxiety of like, oh, like, what if I'll need to know about it later? And at least putting it down somewhere as like, okay, like, I've done something with that anxious [laughs] energy of, like, recognizing that I don't understand this right now, and that's okay. But I can revisit it later. And then, another one is almost the opposite, where it's like, what are my landmarks as I'm navigating through a codebase? Like, what are the files that I'm consistently opening? Because so many of the roads lead to this object. Even when I'm kind of going through different paths, it's like, I can hook into, like, the behavior that I'm looking for from these landmark objects or models because they are really important in this domain. So, it's like, I don't necessarily need to remember every step of the way, but if I can recall some of the more important methods, then I can kind of find my way back. JOËL: Do you just try to, like, memorize those, or do you write them down? Like, how do you make a method or an object a landmark for you? STEPHANIE: That has felt a little more, like, it becomes more, like, muscle memory, I think, because I'm revisiting them pretty frequently. I don't know, it's somehow the act of repeating, like, going through those files just gets encoded somewhere in my brain [laughs], and I don't have to worry as much about forgetting them. JOËL: Strengthening that neural pathway. STEPHANIE: Yeah, exactly. JOËL: Or whatever is happening in the brain there. STEPHANIE: [laughs] JOËL: I like what you were saying earlier, though, about taking notes and sort of almost, like, a breadcrumbs approach. We did an episode almost two years ago where we talked about note-taking for various purposes and note-taking as an exploration exercise, and then note-taking when debugging, where we went deeper into that topic. And I think that would be really relevant to any of our listeners. We'll link that in the show notes. STEPHANIE: Yeah. Leaving breadcrumbs. That's a great metaphor or just a way to describe it. Because I have a little shorthand for if I am leaving myself notes in a codebase as I'm trying to understand what's happening, and it's just, like, putting my initials in a comment and, like, including some observation or commentary about what I'm seeing or a question. JOËL: Also, just a kind of meta observation here, but in the last, you know, 10-15 minutes we've been talking about this, we're already creating our own set of metaphors, and language, and mental models around understanding code. We're talking about breadcrumbs, and landmarks, and looking at code through a broad versus deep lens. That's exactly what we're talking about. STEPHANIE: Joël, do you have any mental models that you use that we haven't really gotten into yet? JOËL: I don't know if they're mental models per se, but I lean very heavily into diagramming as a form of understanding code. And maybe that's a way of sort of reducing the number of concepts because instead of now sort of thinking in terms of, like, lines of code, I'm thinking in terms of maybe some boxes and arrows, and that's a much higher-level way of looking at a system and can give me some really interesting insights. And there are a ton of different diagrams you can use for different things, and I guess all of them are based on a different maybe mental model of what a system is. So, for example, I might actually write out the method call graph starting from some endpoint and just sort of saying, "Hey, when I call this method, what are all of the methods downstream that get called? And is there anything interesting at any of those steps?" Variation on that if you're looking at, let's say, some kind of performance thing would be, like, a flame graph where you have sort of that but then it also shows you the amount of time spent in each of the methods. And that can give you a sense of where your bottlenecks are. Another one that I really like is thinking in terms of a finite state machine. So, sort of following data, how does it change in response to different events that can come into the system? And I'm not talking about, oh, you're using one of the, like, state machine gems out there for your Rails app. This is more of a way of thinking about programs and how they act. You can have just a plain, old Rails app, and you're thinking about, okay, well, how does a cart turn into an order, turn into a fulfillment request at the warehouse, turns into a tracking number for shipping? Modeling that as a state machine. And also, you know, can it move back along that path, or is it only linear move forward? Any kind of multi-state form a wizard often has paths where you move back. It's not linear. That very easily can be drawn out as a state machine. So, that is something that I really like to pull out when I'm trying to understand a, like, complex workflow. STEPHANIE: Yeah, I think we've talked about this before a little bit, or maybe not even a little bit, a lot [laughs]. But I know that you're a big fan of Mermaid.js for creating diagrams in markdown that can be embedded in a pull request description or even in a commit message. When I was hearing you talk about state machines and just all the different paths that can lead to different states, I was like, I bet that's something that you would create using a diagram and stick for yourself and others when sharing code. JOËL: Yes, Mermaid does support state machines as a graph type, which is really cool. Another thing that you can do is embed those in tools like Obsidian, which is my current note-taking tool. So, if I'm doing some sort of notes as a sort of exploratory tool, I will often start writing a Mermaid graph directly in line, and it will render and everything. That's really nice. If I'm not in Obsidian and I just need some sort of one-off graph, I'll often lean on Mermaid.live, which just gives you an editor where you can write up some Mermaid code. It will render it, and then you can copy the PNG into somewhere else and share that with other people. So, if I just need a one-off thing to share in Slack or something like that, I like to lean on that. Another type of diagram that I use pretty frequently is an entity-relationship diagram, so sort of what database tables are related to what others. On larger apps, there's just so many tables, and maybe a bunch of JOINS and things like that, and it's sometimes difficult to get the picture of what is happening, so I'll often draw out a graph of those. Now, it's not worth doing the entire database because that will be huge and overwhelming. So, I'll find, like, five or six tables that are relevant to me and then try to answer the question: How are they related to each other? STEPHANIE: Yeah, I like that. I was going to ask if you do it manually or if you use a tool because I've worked in various apps that have used the Rails ERD gem that will generate an entity-relationship diagram for you every time the schema changes. But there's something very compelling, to me, about the idea of trying to just figure out if you know the relationships, if you could draw them out, as opposed to having a tool do it for you. JOËL: Exactly. STEPHANIE: And I think, like, also, you do have information that might not be encoded in the system. Like, you actually know, oh, these two tables are related, even if no one has defined an association on them. I think that is important in understanding actually how the system is working in real life, I guess. JOËL: Agreed. So, we've been talking a lot about how we can use different tools, different mental models to take code that somebody else has written and kind of, like, almost read it from disk and load it into our brains. But what about the opposite? We're faced with a business problem, and we want to sort of write it to disk, turn it into code that somebody else will then read or that a machine will execute. I hear that happens occasionally. Are there sort of mental models or ways of approaching tackling a more, like, amorphous problem in the real world and turning that into code? Like, are they just the inverse of what we do when we read code, or are they, like, totally different set of skills? STEPHANIE: For me personally, I don't follow this framework very strictly, but I think more intuitively how I like to go about it is more behavior-driven where...because that is the language of maybe our cross-functional partners. They're saying like, "Hey, like, when this happens, I want to be able to do this," and I kind of start there. Maybe I'll pick up some of the keywords that they're repeating pretty frequently as like, oh, like, this is a concept. Actually, lately, the past couple of weeks, I've been test-driving almost all of my code as I work on a totally, like, greenfield feature. And that has been working really well for me, I think, because we did explore more granular, both, like, granular and abstract concepts when we were spiking this feature. And so, we had come up with some domain models. I had kind of thought about, like, how they might interact with each other. But when you then have to actually, like, code that, there are so many little nuances and things to keep track of that I found test driving things from, like, behavior and user stories. Those are really helpful in keeping me, like, on track to making sure that I didn't just have all these little pieces of domain concepts that then didn't really interact in a meaningful way. JOËL: Yeah, the sort of very, like, user or customer-centric approach to thinking about what is this app doing? Is a great way to think about it. And I guess the sort of translation of that, that first step of translation into code is some sort of, like, system spec. STEPHANIE: Yeah, exactly. JOËL: I like that because, you know, we have all these other abstractions that we use as developers. But at the end of the day, our customers and even, you know, our product people aren't thinking in terms of, like, objects and classes and all these other fun abstractions that we have. They're thinking in terms of behaviors and, you know, maybe subsystems, workflows, things like that. And then it's up to us to translate that into whatever paradigm of our language that we're using. STEPHANIE: Do you do things differently from me? JOËL: I don't think that I do it necessarily differently. I think it's one of several tools I have in my tool belt. Something that is similar but from a slightly different angle is inspiring myself with a lot of the ideas from domain-driven design. You know, we've been talking a lot about this idea of, like, mental models and having a vocabulary, things like that, about sort of the way that we work, but that exists at the product level as well. And what if we could encode a lot of that into our application itself? So, is there a distinction between a subscriber and a payer in our system? Is there specialized vocabulary around different other concepts in the app? Maybe instead of just having those be things that product people talk about, what if we made them actual named entities in the system and have maybe our object graph, at least in some way, reflect the sort of idealized model of what our business actually does? That often means that you're thinking of things at a higher level because you're thinking of things at the level that our product people are thinking about them. You might be thinking of things in terms of user journeys, or product workflows, or things like that, because you say, "Oh, well, a new payer has been added to this group account. And that has started a subscription, which then means that a user has access to these corporate features that they didn't have when they were in a solo account." Like, I've just thrown ten different sort of product terms out there that, you know, if there are concepts in our code can help us think about less of the implementation. What does the app do, or how does the app do it? And more in terms of, like, product terms, what does the app do? How do people experience the behavior, or maybe how does data change over the life cycle of the app? So, those perspectives, I think, have helped me distill down sort of more vague product ideas into things that I can then start turning into code. STEPHANIE: Absolutely. I think one way that this framework ends up falling short, at least for me a little bit sometimes, is making connections between behaviors that are similar but not exactly the same. Or when you think about them in more isolated ways, like, it's easy to miss that, like, they are the same idea and that there is, like, something a bit higher level that you can connect them, that you can create a more abstract class for, even though that's not actually how people talk about the things. One example I can think of is things like concerns that are both related to domain language but then also, like, kind of specific to how things work in the code as a system because you might not necessarily call something a subscribable from a product perspective. Do you have any thoughts about identifying those pieces? JOËL: So, what's interesting is I think there's a little bit of, like, layers above and below, the sort of domain layer where you're talking in terms of, like, what the product team would use. When you're doing a lot of the implementation, there will be things that are just, like, that's how we implemented them. They're in the nitty gritty, and they're not terms that the product team would necessarily use. Things like array and string they're low-level details. We have to use them. That's not really relevant to the world of payers, and subscribers, and things like that. So, they're sort of lower layer. And I think that's totally fine to have things where we sort of have things that are sort of programmer only, as long as they're sort of contained within this higher-level layer because that allows people new to the app to sort of see what are the different things in the application to think about things in a higher level. It also allows for smoother communication with the product team. So, ideally, you don't have a concept in the app that is the same as something that the product team, but you just both gave it different names, and then that's really annoying. Or maybe the dev team created something that's, like, almost exactly the same as what the product team talks about, but with some, like, slight variations. Now, you're just going to be talking past each other in every planning meeting, and that will be incredibly annoying. STEPHANIE: Yeah. At one point, when I was trying to communicate, like, async about how a feature works, and there was like the product word for it and then the dev word for it, I would have to type out both [chuckles] because I wanted to make sure that no one was confused about what we were talking about, which was the same thing that just had two names. And yeah, I don't know how many seconds of my life I'll never get back as a result [chuckles]. JOËL: Were these concepts that were identical and had just different names, or was this like, oh, well, our internal subscribed user is almost the same as when product talks about and, I don't know, employee, but our subscribed user has a couple of other extra behaviors that employees don't have, and now there's, like, this weird, like, overlap? STEPHANIE: Yeah, both situations I have found myself in, but I think this one they were virtually identical. Like, they could be used interchangeably to mean the same thing by people who understand both of those definitions, but the problem was that we still had two words [laughs]. JOËL: Yeah, yeah. I'm a big fan of, where possible, converging on the product team's definition. Although because code forces you to be more precise, sometimes that can then force some conversations with the product team about, like, "Hey, so we've been hand waving around this concept of a subscriber. Turns out we think there's actually two different kinds of concepts at work here: the person who's consuming the content and the person who's paying for it. And are they really the same thing, or should we sort of think about these as two different entities? And, in that case, what should the name be?" And that can force a really, I think, healthy conversation between development and product. STEPHANIE: Yeah, I like that. You mentioned there was, like, a higher level and a lower level, but I don't think we've gotten to the higher one yet. JOËL: Yeah. Sometimes, you want to build abstraction sort of over. You're talking about the idea of, like, subscribable things. I think that's where I'm a lot fuzzier. It's much more case-by-case. Where possible, I'd like to introduce some of those things as domain vocabulary so that we'd say, "Well, look, we have a, like, family of products, and they're all subscribable." And maybe, like, the adjective doesn't matter quite as much to our product people, but, you know, because we're using a module in Ruby, we want to lean into the adjective form, and that's fine. But I would at least want some loose connection there. STEPHANIE: Yeah, that makes sense because I think that ultimately makes for a better product. If we're thinking about, like, how to present a hierarchy of information to a user, like a navigation menu, we would want to group those things that are under that family together, ideally, so that they know how to interact with it. JOËL: Another thing that I think falls maybe under, like, this higher-level umbrella are things like design patterns. So, maybe because we want to be able to sort of, like, swap things in and out, we're using some form of strategy pattern. That feels like maybe it's a little bit higher level. It interacts with a lot of the domain concepts, but our product team doesn't really need to think in terms of, like, oh, strategies, and swappable things, and, like, flex points in your architecture. So, those would not necessarily be domain vocabulary. Although I could see, like, maybe there's a way where they do get a domain name, and that's great. STEPHANIE: Oh, I think maybe this is where I disagree with you a little bit. Well, actually, I agreed with what you said at the end [laughs] in terms of how maybe they should be part of the domain vocabulary because I think...I've seen product not fully understand the complexity of the application as it grows over time. And that can lead to sometimes, like, not as great product experience or experience for the user, like, interacting with this product. And maybe that is something we want to, as developers, if we're starting to see and feel and have maybe even introduced a pattern for...I can't claim to have done this too much, but it's definitely a skill I want to hone in on. But, like, how do I communicate to product folks so that we understand, oh, like, where is it possible for these different types of a subscriber to diverge? Because that is important, I think, in determining the future of a product and, like, where we want to invest in it and where we should focus, like, new features. JOËL: And oftentimes, when there is that kind of divergence, there probably will be some sort of product-level thinking that needs to happen there. Are we saying, "Hey, we have one of three types of subscribers, and we want to think about that"? Or maybe we want to say, "We have three different ways of processing an application." Maybe it's derived automatically. Maybe it's a dropdown that you have to pick. But let's say it's a dropdown. What do we name that dropdown with the, like, kind of processing that we want to do to an application? The thing that we want to name that dropdown that's probably a good name for that, like, group of strategies, assuming we implement with a strategy pattern. Maybe we're doing it differently. STEPHANIE: Yeah. The more you talk about that, the more I'm convinced that that's, like, the way I want to be working at least, because you have to know what's there in order to, like, name it. You know, you have to face it, essentially [laughs]. Whereas I think a lot of applications I've worked on fall into the trap of all of those things are obscured way down in the depths of the user flow, where it's like, oh, suddenly, for some reason, you can, like, have a dropdown here that totally changes the behavior, even though you've gotten this far in either the stack trace or even just, like the user journey, as I know you like to branch early in your code. JOËL: [laughs]. STEPHANIE: But you should also branch early from a user's experience [laughs]. JOËL: In general, I'm just a big fan of having a communication loop between development and product, not only sort of receiving a lot of useful information from the product team about what we want to build. But then because we're encountering this more, like, technical spec that we're writing, have those conversations bubble back to product and say, "Hey, so we talked about a dropdown where there are sort of three different ways of processing an application. Let's talk a little bit more about what it means to have three different ways of processing. And what do we want to name that? Is that accessible to everyone, or are they sort of one-to-one tied with a type of user?" And all of a sudden, that has just generated probably a lot of questions that product never even thought to ask because they're working on an infinite canvas of possibilities. And it's really helped you as a developer to have better names to write your code and sort of better sketch out the boundaries of the problem you're trying to solve. So, I think it's a really healthy loop to have. I strongly encourage it. So, we've spent a lot of time talking about thinking about behavior and things like the domain-driven design movement. But a few other things I want to shout out as being really helpful, one is an exercise where you take a problem statement and just underline all of the nouns. That is a great way to get a sense of, like, what is going on here. More generally, I think a lot of what we're talking about falls under the umbrella of what you might call analysis. And so, digging into different analytic techniques can be a great way to better understand the problem that you're working through. One such tool would be decision tables. So, you have a problem, and you say, "Well, given these inputs, what should the outputs be?" STEPHANIE: Cool. If there were any techniques or tools that we missed in terms of how you load code in your brain or generate code from your brain [laughs], we would love to know. You can write in to us at hosts@bikeshed.fm. JOËL: On that note, shall we wrap up? STEPHANIE: Let's wrap up. STEPHANIE: Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeee!!!!!!! AD: Did you know thoughtbot has a referral program? If you introduce us to someone looking for a design or development partner, we will compensate you if they decide to work with us. More info on our website at: tbot.io/referral. Or you can email us at: referrals@thoughtbot.com with any questions.

The Bike Shed
422: Listener Topics Grab Bag

The Bike Shed

Play Episode Listen Later Apr 9, 2024 35:23


Joël conducted a thoughtbot mini-workshop on query plans, which Stephanie found highly effective due to its interactive format. They then discuss the broader value of interactive workshops over traditional talks for deeper learning. Addressing listener questions, Stephanie and Joël explore the strategic use of if and else in programming for clearer code, the importance of thorough documentation in identifying bugs, and the use of Postgres' EXPLAIN ANALYZE, highlighting the need for environment-specific considerations in query optimization. Episode mentioning query plans (https://bikeshed.thoughtbot.com/418) Query plan visualizer (https://explain.dalibo.com/) RailsConf 2024 (https://railsconf.org/) Episode 349: Unpopular Opinions (https://bikeshed.thoughtbot.com/349) Squint test (https://www.youtube.com/watch?v=8bZh5LMaSmE) Episode 405: Retro on Sandi Metz rules (https://bikeshed.thoughtbot.com/405) Structuring conditionals in a wizard (https://thoughtbot.com/blog/structuring-conditionals-in-a-wizard) Episode 417: Module docs (https://bikeshed.thoughtbot.com/417) Episode 416: Multidimensional numbers (https://bikeshed.thoughtbot.com/416) ruby-units gem (https://github.com/olbrich/ruby-units) Solargraph (https://marketplace.visualstudio.com/items?itemName=castwide.solargraph) parity (https://github.com/thoughtbot/parity) Transcript: STEPHANIE:  Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Stephanie Minn. JOËL: And I'm Joël Quenneville, and together, we're here to share a bit of what we've learned along the way. STEPHANIE: So, Joël, what's new in your world? JOËL: Just recently, I ran a sort of mini workshop for some colleagues here at thoughtbot to dig into the idea of query plans and, how to read them, how to use them. And, initially, this was going to be more of a kind of presentation style. And a colleague and I who were sharing this decided to go for a more interactive format where, you know, this is a, like, 45-minute slot. And so, we set it up so that we did a sort of intro to query plans in about 10 minutes then 15 minutes of breakout rooms, where people got a chance to have a query plan. And they had some sort of comprehension questions to answer about it. And then, 15 minutes together to have each group share a little bit about what they had discovered in their query plan back with the rest of the group, so trying to balance some understanding, some application, some group discussion, trying to keep it engaging. It was a pretty fun approach to sharing information like that. STEPHANIE: Yeah. I wholeheartedly agree. I got to attend that workshop, and it was really great. Now that I'm hearing you kind of talk about the three different components and what you wanted people attending to get out of it, I am impressed because [laughs] there is, like, a lot more thought, I think, that went into just participant engagement that reflecting on it now I'm like, oh yeah, like, I think that was really effective as opposed to just a presentation. Because you had, you know, sent us out into breakout rooms, and each group had a different query that they were analyzing. You had kind of set up links that had the query set up in the query analyzer. I forget what the tool was called that you used. JOËL: I forget the name of it, but we will link it in the show notes. STEPHANIE: Yeah. It was helpful for me, though, because, you know, I think if I were just to have learned about it in a presentation or even just looked at, you know, screenshots of it on a slide, that's different still from interacting with it and feeling more confident to use it next time I find myself in a situation where it might be helpful. JOËL: It's really interesting because that was sort of the goal of it was to make it a bit more interactive and then, hopefully, helping people to retain more information than just a straight up, like, presentation would be. I don't know how you feel, I find that often when I go to a place like, let's say, RailsConf, I tend to stay away from more of the workshop-y style events and focus more on the talks. Is that something that you do as well? STEPHANIE: Yeah. I have to confess that I've never attended a workshop [laughs] at a conference. I think it's partly my learning style and also partly just honestly, like, my energy level when I'm at the conference. I kind of just want to sit back. It's on my to-do list. Like, I definitely want to attend one just to see what it's like. And maybe that might even inspire me to want to create my own workshop. But it's like, once I'm in it, and, you know, like, everyone else is also participating, I'm very easily peer pressured [laughs]. So, in a group setting, I will find myself enjoying it a lot more. And I felt that kind of same way with the workshop you ran for our team. Though, I will say a funny thing that happened was that when I went out into my breakout group with another co-worker, and we were trying to grok this query that you gave us, we found out that we got the hardest one, the most complicated one [laughs] because there were so many things going on. There was, like, multiple, like, you know, unions, some that were, like, nested, and then just, like, a lot of duplication as well, like, some conditions that were redundant because of a different condition happening inside of, like, an inner statement. And yeah, we were definitely scratching our heads for a bit and were very grateful that we got to come back together as a group and be like, "Can someone please help? [laughs] Let's figure out what's going on here." JOËL: Sort of close that loop and like, "Hey, here's what we saw. What does everybody else see?" STEPHANIE: Yeah, and I appreciated that you took queries from actual client projects that you were working on. JOËL: Yeah, that was the really fun part of it was that these were not sort of made-up queries to illustrate a point. These were actual queries that I had spent some time trying to optimize and where I had had to spend a lot of time digging into the query plans to understand what was going on. And it sounds like, for you, workshops are something that is...they're generally more engaging, and you get more value out of them. But there's higher activation energy to get started. Does that sound right? STEPHANIE: Yeah, that sounds right. I think, like, I've watched so many talks now, both in person and on YouTube, that a lot of them are easily forgettable [laughs], whereas I think a workshop would be a lot more memorable because of that interactivity and, you know, you get out of it what you put in a little bit. JOËL: Yeah, that's true. Have you looked at the schedule for RailsConf 2024 yet? And are there any workshops on there that you're maybe considering or that maybe have piqued your interest? STEPHANIE: I have, in fact, and maybe I will check off attending a workshop [laughs] off my bucket list this year. There are two that I'm excited about. Unfortunately, they're both at the same time slot, so I -- JOËL: Oh no. You're going to have to choose. STEPHANIE: I know. I imagine I'll have to choose. But I'm interested in the Let's Extend Rails With A Gem by Noel Rappin and Vision For Inclusion Workshop run by Todd Sedano. The Rails gem one I'm excited about because it's just something that I haven't had to do really in my dev career so far, and I think I would really appreciate having that guidance. And also, I think that would be motivation to just get that, like, hands-on experience with it. Otherwise, you know, this is something that I could say that I would want to do and then never get [chuckles] around to it. JOËL: Right, right. And building a gem is the sort of thing that I think probably fits better in a workshop format than in a talk format. STEPHANIE: Yeah. And I've really appreciated all of Noel's content out there. I've found it always really practical, so I imagine that the workshop would be the same. JOËL: So, other than poring over the RailsConf schedule and planning your time there, what has been new for you this week? STEPHANIE: I have a really silly one [laughs]. JOËL: Okay. STEPHANIE: Which is, yesterday I went out to eat dinner to celebrate my partner's birthday, and I experienced, for the first time, robots [laughter] at this restaurant. So, we went out to Hot Pot, and I guess they just have these, like, robot, you know, little, small dish delivery things. They were, like, as tall as me, almost, at least, like, four feet. They were cat-themed. JOËL: [laughs] STEPHANIE: So, they had, like...shaped like cat...they had cat ears, and then there was a screen, and on the screen, there was, like, a little face, and the face would, like, wink at you and smile. JOËL: Aww. STEPHANIE: And I guess how this works is we ordered our food on an iPad, and if you ordered some, like, side dishes and stuff, it would come out to you on this robot cat with wheels. JOËL: Very fun. STEPHANIE: This robot tower cat. I'm doing a poor job describing it because I'm still apparently bewildered [laughs]. But yeah, I was just so surprised, and I was not as...I think I was more, like, shocked than delighted. I imagine other people would find this, like, very fun. But I was a little bit bewildered [laughs]. The other thing that was very funny about this experience is that these robots were kind of going down the aisle between tables, and the aisles were not quite big enough for, like, two-way traffic. And so, there were times where I would be, you know, walking up to go use the restroom, and I would turn the corner and find myself, like, face to face with one of these cat robot things, and, like, it's starting to go at me. I don't know if it will stop [laughs], and I'm the kind of person who doesn't want to find out. JOËL: [laughs] STEPHANIE: So, to avoid colliding with this, you know, food delivery robot, I just, like, ran away from it [laughs]. JOËL: You don't know if they're, like, programmed to yield or something like that. STEPHANIE: Listen, it did not seem like it was going to stop. JOËL: [laughs] STEPHANIE: It got, like, I was, you know, kind of standing there frozen in paralysis [laughs] for a little while. And then, once it got, I don't know, maybe two or three feet away from me, I was like, okay, like, this is too close for comfort [laughs]. So, that was my, I don't know, my experience at this robot restaurant. Definitely starting to feel like I'm in the, I don't know, is this the future? Someone, please let me know [laughs]. JOËL: Is this a future that you're excited or happy about, or does this future seem a little bit dystopian to you? STEPHANIE: I was definitely alarmed [laughter]. But I'm not, like, a super early adopter of new technology. These kinds of innovations, if you will, always surprise me, and I'm like, oh, I guess this is happening now [laughs]. And I will say that the one thing I did not enjoy about it is that there was not enough room to go around this robot. It definitely created just pedestrian traffic issues. So, perhaps this could be very cool and revolutionary, but also, maybe design robots for humans first. JOËL: Or design your dining room to accommodate your vision for the robots. I'm sure that flying cars and robots will solve all of this, for sure. STEPHANIE: Oh yeah [laughter]. Then I'll just have to worry about things colliding above my head. JOËL: And for the listeners who cannot see my face right now, that was absolutely sarcasm [laughs]. Speaking of our listeners, today we're going to look at a group of different listener questions. And if you didn't know that, you could send in a question to have Stephanie and I discuss, you can do that. Just send us an email at hosts@bikeshed.fm. And sometimes, we put it into a regular episode. Sometimes, we combine a few and sort of make a listener question episode, which is what we're doing today. STEPHANIE: Yeah. It's a little bit of a grab bag. JOËL: Our first question comes from Yuri, and Yuri actually has a few different questions. But the first one is asking about Episode 349, which is pretty far back. It was my first episode when I was coming on with Chris and Steph, and they were sort of handing the baton to me as a host of the show. And we talked about a variety of hot takes or unpopular opinions. Yuri mentions, you know, a few that stood out to him: one about SPAs being not so great, one about how you shouldn't need to have a side project to progress in your career as a developer, one about developer title inflation, one about DRY and how it can be dangerous for a mid-level dev, avoiding let in RSpec specs, the idea that every if should come with an else, and the idea that developers shouldn't be included in design and planning. And Yuri's question is specifically the question about if statements, that every if should come with an else. Is that still an opinion that we still have, and why do we feel that way? STEPHANIE: Yeah, I'm excited to get into this because I was not a part of that episode. I was a listener back then when it was still Steph and Chris. So, I am hopefully coming in with a different, like, additional perspective to add as well while we kind of do a little bit of a throwback. So, the one about every if should come with an else, that was an unpopular opinion of yours. Do you mind kind of explaining what that means for you? JOËL: Yeah. So, in general, Ruby is an expression-oriented language. So, if you have an if that does not include an else, it will implicitly return nil, which can burn you. There may be some super expert programmers out there that have never run into undefined method for nil nil class, but I'm still the kind of programmer who runs into that every now and then. And so, implicit nils popping up in my code is not something I generally like. I also generally like having explicit else for control flow purposes, making it a little bit clearer where flow of control goes and what are the actual paths through a particular method. And then, finally, doing ifs and elses instead of doing them sort of inline or as trailing conditionals or things like that, by having them sort of all on each lines and balancing out. The indentation itself helps to scan the code a little bit more. So, deeper indentation tells you, okay, we're, like, nesting multiple conditions, or something like that. And so, it makes it a little bit easier to spot complexity in the code. You can apply, and I want to say this is from Sandi Metz, the squint test. STEPHANIE: Yeah, it is. JOËL: Where you just kind of, like, squint at your code so you're not looking at the actual characters, and more of the structure, and the indentation is actually a friend there rather than something to fight. So, that was sort of the original, I think, idea behind that. I'm curious, in your experience, if you would like to balance your conditionals, ifs with something else, or if you would like to do sort of hanging ifs. STEPHANIE: Hanging ifs, I like that phrase that you just coined there. I agree with your opinion, and I think it's especially true if you're returning values, right? I mean, in Ruby, you kind of always are. But if you are caring about return values, like you said, to avoid that implicit nil situation, I find, especially if you're writing tests for that code, it's really easy, you know, if you spot that condition, you're like, okay, great. Like, this is a path I need to test. But then, oftentimes, you don't test that implicit path, and if you don't enter the condition, then what happens, right? So, I think that's kind of what you're referring to when you talk about both. It's, like, easier to spot in terms of control flow, like, all the different paths of execution, as well as, yeah, like, saving you the headaches of some bugs down the line. One thing that I thought about when I was kind of revisiting that opinion of yours is the idea of like, what are you trying to communicate is different or special about this condition when you are writing an if statement? And, in my head, I kind of came up with a few different situations you might find yourself in, which is, one, where you truly just have, like, a special case, and you're treating that completely differently. Another when you have more of a, like, binary situation, where it's you want to kind of highlight either...more of a dichotomy, right? It's not necessarily that there is a default but that these are two opposite things. And then, a third situation in which you have multiple conditions, but you only happen to have two right now. JOËL: Interesting. And do you think that, like, breaking down those situations would lead you to pick different structures for writing your conditionals? STEPHANIE: I think so. JOËL: Which of those scenarios do you think you might be more likely to reach for an if that doesn't have an else that goes with it? STEPHANIE: I think that first one, the special case one. And in Yuri's email, he actually asked, as a follow-up, "Do we avoid guard clauses as a result of this kind of heuristic or rule?" And I think that special case situation is where a guard clause would shine because you are highlighting it by putting it at the top of a method, and then saying like, you know, "Bail out of this" or, like, "Return this particular thing, and then don't even bother about the rest of this code." JOËL: I like that. And I think guard clauses they're not the first thing I reach for, but they're not something I absolutely avoid. I think they need to be used with care. Like you said, they have to be in the top of your method. If you're adding returns and things that break out of your method, deep inside a conditional somewhere, 20 lines into your method, you don't get to call that a guard clause anymore. That's something else entirely. I think, ideally, guard clauses are also things that will break out of the method, so they're maybe raising exception. Maybe they're returning a value. But they are things that very quickly check edge cases and bail so that the body of the method can focus on expecting data in the correct shape. STEPHANIE: I have a couple more thoughts about this; one is I'm reminded of back when we did that episode on kind of retroing Sandi Metz's Rules For Developers. I think one of the rules was: methods should only be five lines of code. And I recall we'd realized, at least I had realized for the first time, that if you write an if-else condition in Ruby, that's exactly five lines [laughs]. And so, now that I'm thinking about this topic, it's cool to see that a couple of these rules converge a little bit, where there's a bit of explicitness in saying, like, you know, if you're starting to have more conditions that can't just be captured in a five-line if-else statement, then maybe you need something else there, right? Something perhaps like polymorphic or just some way to have branched earlier. JOËL: That's true. And so, even, like, you were talking about the exceptional edge cases where you might want to bail. That could be a sign that your method is doing too much, trying to like, validate inputs and also run some sort of algorithm. Maybe this needs to be some sort of, like, two-step thing, where there's almost, like, a parsing phase that's handled by a different object or a different method that will attempt to standardize your inputs and raise the appropriate errors and everything. And then, your method that has the actual algorithm or code that you're trying to run can just assume that its inputs are in the correct shape, kind of that pushing the uncertainty to the edges. And, you know, if you've only got one edge case to check, maybe it's not worth to, like, build this in layers, or separate out the responsibilities, or whatever. But if you're having a lot, then maybe it does make sense to say, "Let's break those two responsibilities out into two places." STEPHANIE: Yeah. And then, the one last kind of situation I've observed, and I think you all talked about this in the Unpopular Opinions episode, but I'm kind of curious how you would handle it, is side effects that only need to be applied under a certain condition. Because I think that's when, if we're focusing less on return values and more just on behavior, that's when I will usually see, like, an if something, then do this that doesn't need to happen for the other path. JOËL: Yes. I guess if you're doing some sort of side effect, like, I don't know, making a request to an API or writing to a file or something, having, like, else return nil or some other sentinel value feels a little bit weird because now you're caring about side effects rather than return values, something that you need to keep thinking of. And that's something where I think my thing has evolved since that episode is, once you start having multiple of these, how do they compose together? So, if you've got if condition, write to a file, no else, keep going. New if condition, make a request to an API endpoint, no else, continue. What I've started calling independent conditions now, you have to think about all the different ways that they can combine, and what you end up having is a bit of a combinatorial explosion. So, here we've got two potential actions: writing to a file, making a request to an API. And we could have one or the other, or both, or neither could happen, depending on the inputs to your method, and maybe you actually want that, and that's cool. Oftentimes, you didn't necessarily want all of those, especially once you start going to three, four, five. And now you've got that, you know, explosion, like, two to the five. That's a lot of paths through your method. And you probably didn't really need that many. And so, that can get really messy. And so, sometimes the way that an if and an else work where those two paths are mutually exclusive actually cuts down on the total number of paths through your method. STEPHANIE: Hmm, I like that. That makes a lot of sense to me. I have definitely seen a lot of, like, procedural code, where it becomes really hard to tell how to even start relating some of these concepts together. So, if you happen to need to run a side effect, like writing to a file or, I don't know, one common one I can think of is notifying something or someone in a particular case, and maybe you put that in a condition. But then there's a different branching path that you also need to kind of notify someone for a similar reason, maybe even the same reason. It starts to become hard to connect, like, those two reasons. It's not something that, like, you can really scan for or, like, necessarily make that connection because, at that point, you're going down different paths, right? And there might be other signals that are kind of confusing things along the way. And it makes it a lot harder, I think, to find a shared abstraction, which could ultimately make those really complicated nested conditions a little more manageable or just, like, easier to understand at a certain complexity. I definitely think there is a threshold. JOËL: Right. And now you're talking about nested versus non-nested because when conditions are sort of siblings of each other, an if-else behaves differently from two ifs without an else. I think a classic situation where this pops up is when you're structuring code for a wizard, a multi-step form. And, oftentimes, people will have a bunch of checks. They're like, oh, if this field is present, do these things. If this field is present, do these things. And then, it becomes very tricky to know what the flow of control is, what you can expect at what moment, and especially which actions might get shared across multiple steps. Is it safe to refactor in one place if you don't want to break step three? And so, learning to think about the different paths through your code and how different conditional structures will impact that, I think, was a big breakthrough for me in terms of taking the next logical step in terms of thinking, when do I want to balance my ifs and when do I not want to? I wrote a whole article on the topic. We'll link it in the show notes. So, Yuri, thanks for a great question, bringing us back into a classic developer discussion. Yuri also asks or gives us a bit of a suggestion: What about revisiting this topic and doing an episode on hot takes or unpopular topics? Is that something that you'd be interested in, Stephanie? STEPHANIE: Oh yeah, definitely, because I didn't get to, you know, share my hot topics the last episode [laughs]. [inaudible 24:23] JOËL: You just got them queued up and ready to go. STEPHANIE: Yeah, exactly. So, yeah, I will definitely be brainstorming some spicy takes for the show. JOËL: So, Yuri, thanks for the questions and for the episode suggestion. STEPHANIE: So, another listener, Kevin, wrote in to us following up from our episode on Module Docs and about a different episode about Multi-dimensional Numbers. And he mentioned a gem that he maintains. It's called Ruby Units. And it basically handles the nitty gritty of unit conversions for you, which I thought was really neat. He mentioned that it has a numeric class, and it knows how to do math [laughs], which I would find really convenient because that is something that I have been grateful not to have to really do since college [laughs], at least those unit conversions and all the things that I'd probably learned in math and physics courses [laughs]. So, I thought that was really cool, definitely is one to check out if you frequently work with units. It seemed like it would be something that would make sense for a domain that is more science or deals in that kind of domain. JOËL: I'm always a huge fan of anything that tags raw numbers that you're working with with a quantity rather than just floating raw numbers around. It's so easy to make a mistake to either treat a number as a quantity you didn't think of, or make some sort of invalid operation on it, or even to think you have a value in a different size than you do. You think you're dealing with...you know you have a time value, but you think it's in seconds. It's actually in milliseconds. And then, you get off by some big factor. These are all mistakes that I have personally made in my career, so leaning on a library to help avoid those mistakes, have better information hiding for the things that really aren't relevant to the work that I'm trying to do, and also, kind of reify these ideas so that they have sort of a name, and they're, like, their own object, their own thing that we can interact with in the app rather than just numbers floating around, those are all big wins from my perspective. STEPHANIE: I also just thought of a really silly use case for this that is, I don't know, maybe I'll have to experiment with this. But every now and then, I find the need to have to convert a unit, and I just pop into Google, and I'm like, please give me, you know, I'll search for 10 kilometers in miles or something [laughs]. But then I have to...sometimes Google will figure it out for me, and sometimes it will just list me with a bunch of weird conversion websites that all have really old-school UI [laughs]. Do you know what I'm talking about here? Anyway, I would be curious to see if I could use this gem as a command-line interface [laughs] for me without having to go to my browser and roll the dice with freecalculator.com or something like that [laughs]. JOËL: One thing that's really cool with this library that I saw is the ability to define your own units, and that's a thing that you'll often encounter having to deal with values that are maybe not one of the most commonly used units that are out there, dealing with numbers that might mean a thing that's very particular to your domain. So, that's great that the library supports that. I couldn't see if it supports multi-dimensional units. That was the episode that inspired the comment. But either way, this is a really cool library. And thank you, Kevin, for sharing this with us. STEPHANIE: Kevin also mentions that he really enjoys using YARD docs. And we had done that whole episode on Module Docs and your experience writing them. So, you know, your people are out there [laughs]. JOËL: Yay. STEPHANIE: And we talked about this a little bit; I think that writing the docs, you know, on one hand, is great for future readers, but, also, I think has the benefit of forcing the author to really think about their inputs and outputs, as Kevin mentions. He's found bugs by simply just going through that process in designing his code, and also recommends Solargraph and Solargraph's VSCode extension, which I suspect really kind of makes it easy to navigate a complex codebase and kind of highlight just what you need to know when working with different APIs for your classes. So, I recently kind of switched to the Ruby LSP, build with Shopify, but I'm currently regretting it because nothing is working for me right now. So, that might be the push that I need [laughs] to go back to using Solargraph. JOËL: It's interesting that Kevin mentions finding bugs while writing docs because that has absolutely been my experience. And even in this most recent round, I was documenting some code that was just sort of there. It wasn't new code that I was writing. And so, I had given myself the rule that this would be documentation-only PRs, no code changes. And I found some weird code, and I found some code that I'm 98% sure is broken. And I had to have the discipline to just put a notice in the documentation to be like, "By the way, this is how the method should work. I'm pretty sure it's broken," and then, maybe come back to it later to fix it. But it's amazing how trying to document code, especially code that you didn't write yourself, really forces you to read it in a different way, interact with it in a different way, and really, like, understand it in a deep way that surprised me a little bit the first time I did it. STEPHANIE: That's cool. I imagine it probably didn't feel good to be like, "Hey, I know that this is broken, and I can't fix it right now," but I'm glad you did. That takes a lot of, I don't know, I think, courage, in my opinion [laughs], to be like, "Yeah, I found this, and I'm going to, you know, like, raise my hand acknowledging that this is how it is," as supposed to just hiding behind a broken functionality that no one [laughs] has paid attention to. JOËL: And it's a thing where if somebody else uses this method and it breaks in a way, and they're like, "Well, the docs say it should behave like this," that would be really frustrating. If the docs say, "Hey, it should behave like this, but it looks like it's broken," then, you know, I don't know, I would feel a little bit vindicated as a person who's annoyed at the code right now. STEPHANIE: For sure. JOËL: Finally, we have a message from Tim about using Postgres' EXPLAIN ANALYZE. Tim says, "Hey, Joël, in the last episode, you talked a bit about PG EXPLAIN ANALYZE. As you stated, it's a great tool to help figure out what's going on with your queries, but there is a caveat you need to keep in mind. The query planner uses statistics gathered on the database when making decisions about how to fetch records. If there's a big difference between your dev or staging database and production, the query may make different decisions. For example, if a table has a low number of records in it, then the query planner may just do a table scan, but in production, it might use an index. Also, keep in mind that after a schema changes, it may not know about new indexes or whatever unless an explicit ANALYZE is done on the table." So, this is really interesting because, as Tim mentions, EXPLAIN ANALYZE doesn't behave exactly the same in production versus in your local development environment. STEPHANIE: When you were trying to optimize some slow queries, where were you running the ANALYZE command? JOËL: I used a combination. I mostly worked off of production data. I did a little bit on a staging database that had not the same amount of records and things. That was pretty significant. And so, I had to switch to production to get realistic results. So, yes, I encountered this kind of firsthand. STEPHANIE: Nice. For some reason, this comment also made me think of..., and I wanted to plug a thoughtbot shell command that we have called Parity, which lets you basically download your production database into your local dev database if you use Heroku. And that has come in handy for me, obviously, in regular development, but would be really great in this use case. JOËL: With all of the regular caveats around security, and PII, and all this stuff that come with dealing with production data. But if you're running real productions on production, you should be cleared and, like, trained for access to all of that. I also want to note that the queries that you all worked with on Friday are also from the production database. STEPHANIE: Really? JOËL: So, you got to see what it actually does, what the actual timings were. STEPHANIE: I'm surprised by that because we were using, like, a web-based tool to visualize the query plans. Like, what were you kind of plugging into the tool for it to know? JOËL: So, the tool accepts a query plan, which is a text output from running a SQL query. STEPHANIE: Okay. So, it's just visualizing it. JOËL: Correct. Yeah. So, you've got this query plan, which comes back as this very intimidating block of, like, text, and arrows, and things like that. And you plug it into this web UI, and now you've got something that is kind of interactive, and visual, and you can expand or collapse nodes. And it gives you tooltips on different types of information and where you're spending the most time. So, yeah, it's just a nicer way to visualize that data that comes from the query plan. STEPHANIE: Gotcha. That makes sense. JOËL: So, that's a very important caveat. I don't think that's something that we mentioned on the episode. So, thank you, Tim, for highlighting that. And for all of our listeners who were intrigued by leaning into EXPLAIN ANALYZE and query plan viewers to debug your slow queries, make sure you try it out in production because you might get different results otherwise. STEPHANIE: So, yeah, that about wraps up our listener topics in recent months. On that note, Joël, shall we wrap up? JOËL: Let's wrap up. STEPHANIE: Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeeee!!!!!!! AD: Did you know thoughtbot has a referral program? If you introduce us to someone looking for a design or development partner, we will compensate you if they decide to work with us. More info on our website at: tbot.io/referral. Or you can email us at: referrals@thoughtbot.com with any questions.

The Bike Shed
420: Test Database Woes

The Bike Shed

Play Episode Listen Later Mar 26, 2024 28:16


Joël shares his recent project challenge with Tailwind CSS, where classes weren't generating as expected due to the dynamic nature of Tailwind's CSS generation and pruning. Stephanie introduces a personal productivity tool, a "thinking cap," to signal her thought process during meetings, which also serves as a physical boundary to separate work from personal life. The conversation shifts to testing methodologies within Rails applications, leading to an exploration of testing philosophies, including developers' assumptions about database cleanliness and their impact on writing tests. Avdi's classic post on how to use database cleaner (https://avdi.codes/configuring-database_cleaner-with-rails-rspec-capybara-and-selenium/) RSpec change matcher (https://rubydoc.info/gems/rspec-expectations/RSpec%2FMatchers:change) Command/Query separation (https://martinfowler.com/bliki/CommandQuerySeparation.html) When not to use factories (https://thoughtbot.com/blog/speed-up-tests-by-selectively-avoiding-factory-bot) Why Factories? (https://thoughtbot.com/blog/why-factories) Transcript:  STEPHANIE: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Stephanie Minn. JOËL: And I'm Joël Quenneville. And together, we're here to share a bit of what we've learned along the way. STEPHANIE: So, Joël, what's new in your world? JOËL: I'm working on a new project, and this is a project that uses Tailwind CSS for its styling. And I ran into a bit of an annoying problem with it just getting started, where I was making changes and adding classes. And they were not changing the things I thought they would change in the UI. And so, I looked up the class in the documentation, and then I realized, oh, we're on an older version of the Tailwind Rails gem. So, maybe we're using...like, I'm looking at the most recent docs for Tailwind, but it's not relevant for the version I'm using. Turned out that was not the problem. Then I decided to use the Web Inspector and actually look at the element in my browser to see is it being overwritten somehow by something else? And the class is there in the element, but when I look at the CSS panel, it does not show up there at all or having any effects. And that got me scratching my head. And then, eventually, I figured it out, and it's a bit of a facepalm moment [laughs]. STEPHANIE: Oh, okay. JOËL: Because Tailwind has to, effectively, generate all of these, and it will sort of generate and prune the things you don't need and all of that. They're not all, like, statically present. And so, if I was using a class that no one else in the app had used yet, it hadn't gotten generated. And so, it's just not there. There's a class on the element, but there's no CSS definition tied to it, so the class does nothing. What you need to do is there's a rake task or some sort of task that you can run that will generate things. There's also, I believe, a watcher that you can run, some sort of, like, server that will auto-generate these for you in dev mode. I did not have that set up. So, I was not seeing that new class have any effect. Once I ran the task to generate things, sure enough, it worked. And Tailwind works exactly how the docs say they do. But that was a couple of hours of my life that I'm not getting back. STEPHANIE: Yeah, that's rough. Sorry to hear. I've also definitely gone down that route of like, oh, it's not in the docs. The docs are wrong. Like, do they even know what they're talking about? I'm going to fix this for everyone. And similarly have been humbled by a facepalm solution when I'm like, oh, did I yarn [laughs]? No, I didn't [laughs]. JOËL: Uh-huh. I'm curious, for you, when you have sort of moments where it's like the library is not behaving the way you think it is, is your default to blame yourself, or is it to blame the library? STEPHANIE: [laughs]. Oh, good question. JOËL: And the follow-up to that is, are you generally correct? STEPHANIE: Yeah. Yep, yep, yep. Hmm, I will say I externalize the blame, but I will try to at least do, like, the basic troubleshooting steps of restarting my server [laughter], and then if...that's as far as I'll go. And then, I'll be like, oh, like, something must be wrong, you know, with this library, and I turn to Google. And if I'm not finding any fruitful results, again, you know, one path could be, oh, maybe I'm not Googling correctly, but the other path could be, maybe I've discovered something that no one else has before. But to your follow-up question, I'm almost, like, always wrong [laughter]. I'm still waiting for the day when I, like, discover something that is an actual real problem, and I can go and open an issue [chuckles] and, hopefully, be validated by the library author. JOËL: I think part of what I heard is that your debugging strategy is basic, but it's not as basic as Joël's because you remember to restart the server [chuckles]. STEPHANIE: We all have our days [laughter]. JOËL: Next time. So, Stephanie, what is new in your world? STEPHANIE: I'm very excited to share this with you. And I recognize that this is an audio medium, so I will also describe the thing I'm about to show you [laughs]. JOËL: Oh, this is an object. STEPHANIE: It is an object. I got a hat [laughs]. JOËL: Okay. STEPHANIE: I'm going to put it on now. It's a cap that says "Thinking" on it [laughs] in, like, you know, fun sans serif font with a little bit of edge because the thinking is kind of slanted. So, it is designy, if you will. It's my thinking cap. And I've been wearing it at work all week, and I love it. As a person who, in meetings and, you know, when I talk to people, I have to process before I respond a lot of the time, but that has been interpreted as, you know, maybe me not having anything to say or, you know, people aren't sure if I'm, you know, still thinking or if it's time to move on. And sometimes I [chuckles], you know, take a long time. My brain is just spinning. I think another funny hat design would be, like, the beach ball, macOS beach ball. JOËL: That would be hilarious. STEPHANIE: Yeah. Maybe I need to, like, stitch that on the back of this thinking cap. Anyway, I've been wearing it at work in meetings. And then, when I'm just silently processing, I'll just point to my hat and signal to everyone what's [laughs] going on. And it's also been really great for the end of my work day because then I take off the hat, and because I've taken it off, that's, like, my signal, you know, I have this physical totem that, like, now I'm done thinking about work, and that has been working. JOËL: Oh, I love that. STEPHANIE: Yeah, that's been working surprisingly well to kind of create a bit more of a boundary to separate work thoughts and life thoughts. JOËL: Because you are working from home and so that boundary between professional life and personal life can get a little bit blurry. STEPHANIE: Yeah. I will say I take it off and throw it on the floor kind of dramatically [laughter] at the end of my work day. So, that's what's new. It had a positive impact on my work-life balance. And yeah, if anyone else has the problem of people being confused about whether you're still thinking or not, recommend looking into a physical thinking cap. JOËL: So, you are speaking at RailsConf this spring in Detroit. Do you plan to bring the thinking cap to the conference? STEPHANIE: Oh yeah, absolutely. That's a great idea. If anyone else is going to RailsConf, find me in my thinking cap [laughs]. JOËL: So, this is how people can recognize Bikeshed co-host Stephanie Minn. See someone walking around with a thinking cap. STEPHANIE: Ooh. thinkingbot? JOËL: Ooh. STEPHANIE: Have I just designed new thoughtbot swag [laughter]? We'll see if this catches on. JOËL: So, we were talking recently, and you'd mentioned that you were facing some really interesting dilemmas when it came to writing tests and particularly how tests interact with your test database. STEPHANIE: Yeah. So, I recently, a few weeks ago, joined a new client project and, you know, one of the first things that I do is start to run those tests [laughs] in their codebase to get a sense of what's what. And I noticed that they were taking quite a long time to get set up before I even saw any progress in terms of successes or failures. So, I was kind of curious what was going on before the examples were even run. And when I tailed the logs for the tests, I noticed that every time that you were running the test suite, it would truncate all of the tables in the test database. And that was a surprise to me because that's not a thing that I had really seen before. And so, basically, what happens is all of the data in the test database gets deleted using this truncation strategy. And this is one way of ensuring a clean slate when you run your tests. JOËL: Was this happening once at the beginning of the test suite or before every test? STEPHANIE: It was good that it was only running once before the test suite, but since, you know, in my local development, I'm running, like, a file at a time or sometimes even just targeting a specific line, this would happen on every run in that situation and was just adding a little bit of extra time to that feedback loop in terms of just making sure your code was working if that's part of your workflow. JOËL: Do you know what version of Rails this project was in? Because I know this was popular in some older versions of Rails as a strategy. STEPHANIE: Yeah. So, it is Rails 7 now, recently upgraded to Rails 7. It was on Rails 6 for a little while. JOËL: Very nice. I want to say that truncation is generally not necessary as of Rails...I forget if it's 5 or 6. But back in the day, specifically for what are now called system tests, the sort of, like, Capybara UI-driven browser tests, you had, effectively, like, two threads that were trying to access the database. And so, you couldn't have your test data wrapped in a transaction the way you would for unit tests because then the UI thread would not have access to the data that had been created in a transaction just for the test thread. And so, people would use tools like Database Cleaner to use a truncation strategy to clear out everything between tests to allow a sort of clean slate for these UI-driven feature specs. And then, I want to say it's Rails 5, it may have been Rails 6 when system tests were added. And one of the big things there was that they now could, like, share data in a transaction instead of having to do two separate threads and one didn't have access to it. And all of a sudden, now you could go back to transactional fixtures the way that you could with unit tests and really take advantage of something that's really nice and built into Rails. STEPHANIE: That's cool. I didn't know that about system tests and that kind of shift happening. I do think that, in this case, it was one of those situations where, in the past, the database truncation, in this case, particular using the Database Cleaner gem was necessary, and that just never got reassessed as the years went by. JOËL: That's one of the classic things, right? When you upgrade a Rails app over multiple versions, and sometimes you sort of get a new feature that comes in for free with the new version, and you might not be aware of it. And some of the patterns in the app just kind of keep going. And you don't realize, hey, this part of the app could actually be modernized. STEPHANIE: So, another interesting thing about this testing situation is that I learned that, you know, if you ran these tests, you would experience this truncation strategy. But the engineering team had also kind of played around with having a different test setup that didn't clean the database at all unless you opted into it. JOËL: So, your test database would just...each test would just keep writing to the database, but they're not wrapped in transactions. Or they are wrapped in transactions, but you may or may not have some additional data. STEPHANIE: The latter. So, I think they were also using the transaction strategy there. But, you know, there are some reasons that you would still have some data persisted across test runs. I had actually learned that the use transactional fixtures config for RSpec doesn't roll back any data that might have been created in a before context hook. JOËL: Yep, or a before all. Yeah, the transaction wraps the actual example, but not anything that happens outside of it. STEPHANIE: Yeah, I thought that was an interesting little gotcha. So, you know, now we had these, like, two different ways to run tests. And I was chatting with a client developer about how that came to be. And we then got into an interesting conversation about, like, whether or not we each expect a clean database in the first place when we write our tests or when we run our tests, and that was an area that we disagreed. And that was cool because I had not really, like, thought about like, oh, how did I even arrive at this assumption that my database would always be clean? I think it was just, you know, from experience having only worked in Rails apps of a certain age that really got onto the Database [laughs] Cleaner train. But it was interesting because I think that is a really big assumption to make that shapes how you then approach writing tests. JOËL: And there's kind of a couple of variations on that. I think the sort of base camp approach of writing Rails with fixtures, you just sort of have, for the most part, an existing set of data that's there that you maybe layer on a few extra things on. But there's base level; you just expect a bunch of data to exist in your test database. So, it's almost going off the opposite assumption, where you can always assume that certain things are already there. Then there's the other extreme of, like, you always assume that it's empty. And it sounds like maybe there's a position in the middle of, like, you never know. There may be something. There may not be something, you know, spin the wheel. STEPHANIE: Yeah. I guess I was surprised that it, you know, that was just a question that I never really asked myself prior to this conversation, but it could feel like different testing philosophies. But yeah, I was very interested in this, you know, kind of opinion that was a little bit different from mine about if you assume that your database, your test database, is not clean, that kind of perhaps nudges you in the direction of writing tests that are less coupled to the database if they don't need to be. JOËL: What does coupling to the database mean in this situation? STEPHANIE: So, I'm thinking about Rails tests that might be asserting on a change in database behavior, so the change matcher in RSpec is one that I see maybe sometimes used when it doesn't need to be used. And we're expecting, like, account to have changed the count of the number of records on it for a model have changed after doing some work, right? JOËL: And the change matcher from RSpec is one that allows you to not care whether there are existing records or not. It sort of insulates you from that. STEPHANIE: That's true. Though I guess I was thinking almost like, what if there was some return value to assert on instead? And would that kind of help you separate some side effects from methods that might be doing too much? And kind of when I start to see tests that have both or are asserting on something being returned, and then also something happening, that's one way of, like, figuring out what kind of coupling is going on inside this test. JOËL: It's the classic command-query separation principle from object-oriented design. STEPHANIE: I think another one that came to mind, another example, especially when you're talking about system tests, is when you might be using Capybara and you end up...maybe you're going through a flow that creates a record. But from the user perspective, they don't actually know what's going on at the database level. But you could assert that something was created, right? But it might be more realistic at that level of abstraction to be asserting some kind of visual element that had happened as a result of the flow that you're testing. JOËL: Yeah. I would, in fact, go so far as to say that asserting on the state of your database in a system test is an anti-pattern. System tests are sort of, by design, meant to be all about user behavior trying to mimic the experience of a user. And a user of a website is not going to be able to...you hope they're not able to SSH into [chuckles] your database and check the records that have been created. If they can, you've got another problem. STEPHANIE: I wonder if you could take this idea to the extreme, though. And do you think there is a world where you don't really test database-level concerns at all if you kind of believe this idea that it doesn't really matter what the state of it should be? JOËL: I guess there's a few different things on, like, what it matters about the state of it because you are asserting on its state sort of indirectly in a sort of higher level integration test. You're asserting that you see certain things show up on the screen in a system test. And maybe you want to say, "I do certain tasks, and then I expect to see three items in an unordered list." Those three items probably come from the database, although, you know, you could have it where they come from an API or something like that. So, the database is an implementation level. But if you had random data in your database, you might, in some tests, have four items in the list, some tests have five. And that's just going to be a flaky test, and that's going to be incredibly painful. So, while you're not asserting on the database, having control over it during sort of test setup, I think, does impact the way you assert. STEPHANIE: Yeah, that makes sense. I was suddenly just thinking about, like, how that exercise can actually tell you perhaps, like, when it is important to, in your test setup, be persisting real records as opposed to how much you can get away with, like, not interacting with it because, like, you aren't testing at that integration level. JOËL: That brings up a good point because a lot of tests probably you might need models, but you might not need persisted models to interact with them, if you're testing a method on a model that just does things based off its internal state and not any of the ActiveRecord database queries, or if you have some other service or something that consumes a model that doesn't necessarily need to query. There's a classic blog post on the thoughtbot blog about when you should not reuse. There's a classic blog post on the thoughtbot blog about when not to use FactoryBot. And, you know, we are the makers of FactoryBot. It helps set up records in your database for testing. And people love to use it all the time. And we wrote an article about why, in many cases, you don't need to create something into the database. All you need is just something in memory, and that's going to be much faster than using FactoryBot because talking to the database is expensive. STEPHANIE: Yeah, and I think we can see that in the shift from even, like, fixtures to factories as well, where test data was only persisted as needed and as needed in individual tests, rather than seeding it and having all of those records your entire test run. And it's cool to see that continuing, you know, that idea further of like, okay, now we have this new, popular tool that reduce some of that. But also, in most cases, we still don't need...it's still too much. JOËL: And from a performance perspective, it's a bit of a see-saw in that fixtures are a lot faster because they get inserted once at the beginning of your test run. So, a SQL execution at the beginning of a test run and then every test after that is just doing its thing: maybe creating a record inside of a transaction, maybe not creating any records at all. And so, it can be a lot faster as opposed to using FactoryBot where you're creating records one at a time. Every create call in a test is a round trip to the database, and those are expensive. So, FactoryBot tests tend to be more expensive than those that rely on fixtures. But you have the advantage of more control over what data is present and sort of more locality because you can see what has been created at the test level. But then, if you decide, hey, this is a test where I can just create records in memory, that's probably the best of all worlds in that you don't need anything created ahead with fixtures. You also don't need anything to be inserted using FactoryBot because you don't even need the database for this test. STEPHANIE: I'm curious, is that the assumption that you start with, that you don't need a persisted object when you're writing a basic unit test? JOËL: I think I will as much as possible try not to need to persist and only if necessary use persist records. There are strategies with FactoryBot that will allow you to also, like, build stubbed or just build in memory. So, there's a few different variations that will, like, partially do things for you. But oftentimes, you can just new up an object, and that's what I will often start with. In many cases, I will already know what I'm trying to do. And so, I might not go through the steps of, oh, new up an object. Oh no, I'm getting a I can't do the thing I need to do. Now, I need to write to the database. So, if I'm testing, let's say, an ActiveRecord scope that's filtering down a series of records, I know that's a wrapper around a database query. I'm not going to start by newing up some records and then sort of accidentally discovering, oh yeah, it does write to the database because that was pretty clear to me from the beginning. STEPHANIE: Yeah. Like, you have your mental shortcuts that you do. I guess I asked that question because I wonder if that is a good heuristic to share with maybe developers who are trying to figure out, like, should they create persisted records or, you know, use just regular instance in memory or, I don't know, even [laughs] use, like, a double [laughs]? JOËL: Yeah, I've done that quite a bit as well. I would say maybe my heuristic is, is the method under test going to need to talk to the database? And, you know, I may or may not know that upfront because if I'm test driving, I'm writing the test first. So, sometimes, maybe I don't know, and I'll start with something in memory and then realize, oh, you know, I do need to talk to the database for this. And this is for unit tests, in particular. For something more like an integration test or a system test that might require data in the database, system tests almost always do. You're not interacting with instances in memory when you're writing a system test, right? You're saying, "Given the database state is this when I visit this URL and do these things, this page reacts in such and such a way." So, system tests always write to the database to start with. So, maybe that's my heuristic there. But for unit tests, maybe think a little bit about does your method actually need to talk to the database? And maybe even almost give yourself a challenge. Can I get away with not talking to the database here? STEPHANIE: Yeah, I like that because I've certainly seen a lot of unit tests that are integration tests in disguise [laughs]. JOËL: Isn't that the truth? So, we kind of opened up this conversation with the idea of there are different ways to manage your database in terms of, do you clean or not clean before a test run? Where did you end up on this particular project? STEPHANIE: So, I ended up with a currently open PR to remove the need to truncate the database on each run of the test suite and just stick with the transaction for each example strategy. And I do think that this will work for us as long as we decide we don't want to introduce something like fixtures, even though that is actually also a discussion that's still in the works. But I'm hoping with this change, like, right now, I can help people start running faster tests [chuckles]. And should we ever introduce fixtures down the line, then we can revisit that. But it's one of those things that I think we've been living with this for too long [laughs]. And no one ever questioned, like, "Oh, why are we doing this?" Or, you know, maybe that was a need, however many years ago, that just got overlooked. And as a person new to the project, I saw it, and now I'm doing something about it [laughs]. JOËL: I love that new person energy on a project and like, "Hey, we've got this config thing. Did you know that we didn't need this as of Rails 6?" And they're like, "Oh, I didn't even realize that." And then you add that, and it just moves you into the future a little bit. So, if I understand the proposed change, then you're removing the truncation strategy, but you're still going to be in a situation where you have a clean database before each test because you're wrapping tests in transactions, which I think is the default Rails behavior. STEPHANIE: Yeah, that's where we're at right now. So, yeah, I'm not sure, like, how things came to be this way, but it seemed obvious to me that we were kind of doing this whole extra step that wasn't really necessary, at least at this point in time. Because, at least to my knowledge [laughs], there's no data being seeded in any other place. JOËL: It's interesting, right? When you have a situation where this was sort of a very popular practice for a long time, a lot of guides mentioned that. And so, even though Rails has made changes that mean that this is no longer necessary, there's still a long tail of apps that will still have this that may be upgraded later, and then didn't drop this, or maybe even new apps that got created but didn't quite realize that the guide they were following was outdated, or that a best practice that was in their head was also outdated. And so, you have a lot of apps that will still have these sort of, like, relics of the past. And you're like, "Oh yeah, that's how we used to do things." STEPHANIE: So yeah, thanks, Joël, for going on this journey with me in terms of, you know, reassessing my assumptions about test databases. I'm wondering, like, if this is common, how other people, you know, approach what they expect from the test database, whether it be totally clean or have, you know, any required data for common flows and use cases of your system. But it does seem that little in between of, like, maybe it is using transactions to reset for each example, but then there's also some persistence that's happening somewhere else that could be a little tricky to manage. JOËL: On that note, shall we wrap up? STEPHANIE: Let's wrap up. Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeeeeeee!!!!!! AD: Did you know thoughtbot has a referral program? If you introduce us to someone looking for a design or development partner, we will compensate you if they decide to work with us. More info on our website at: tbot.io/referral. Or you can email us at: referrals@thoughtbot.com with any questions.

The Bike Shed
418: Mental Models For Reduce Functions

The Bike Shed

Play Episode Listen Later Mar 12, 2024 42:50


Joël talks about his difficulties optimizing queries in ActiveRecord, especially with complex scopes and unions, resulting in slow queries. He emphasizes the importance of optimizing subqueries in unions to boost performance despite challenges such as query duplication and difficulty reusing scopes. Stephanie discusses upgrading a client's app to Rails 7, highlighting the importance of patience, detailed attention, and the benefits of collaborative work with a fellow developer. The conversation shifts to Ruby's reduce method (inject), exploring its complexity and various mental models to understand it. They discuss when it's preferable to use reduce over other methods like each, map, or loops and the importance of understanding the underlying operation you wish to apply to two elements before scaling up with reduce. The episode also touches on monoids and how they relate to reduce, suggesting that a deep understanding of functional programming concepts can help simplify reduce expressions. Rails 7 EXPLAIN ANALYZE (https://www.bigbinary.com/blog/rails-7-1-adds-options-to-activerecord-relation-explain) Blocks, symbol to proc, and symbols arguments for reduce (https://thoughtbot.com/blog/blocks-procs-and-enumerable) Ruby tally (https://medium.com/@baweaver/ruby-2-7-enumerable-tally-a706a5fb11ea) Performance considerations for reduce in JavaScript (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce#when_to_not_use_reduce) Persistant data structures (https://www.youtube.com/watch?v=gTClDj9Zl1g) Avoid passing a block to map and reduce (https://thoughtbot.com/blog/avoid-putting-logic-in-map-blocks) Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire (https://ris.utwente.nl/ws/portalfiles/portal/6142049/meijer91functional.pdf) monoids (https://blog.ploeh.dk/2017/10/06/monoids/) iteration anti-patterns (https://thoughtbot.com/blog/iteration-as-an-anti-pattern) Joël's talk on “constructor replacement” (https://www.youtube.com/watch?v=dSMB3rsufC8) Transcript:  STEPHANIE: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Stephanie Minn. JOËL: And I'm Joël Quenneville. And together, we're here to share a bit of what we've learned along the way. STEPHANIE: So, Joël, what's new in your world? JOËL: I've been doing a bunch of fiddling with query optimization this week, and I've sort of run across an interesting...but maybe it's more of an interesting realization because it's interesting in the sort of annoying way. And that is that, using ActiveRecord scopes with certain more complex query pieces, particularly unions, can lead to queries that are really slow, and you have to rewrite them differently in a way that's not reusable in order to make them fast. In particular, if you have sort of two other scopes that involve joins and then you combine them using a union, you're unioning two sort of joins. Later on, you want to change some other scope that does some wares or something like that. That can end up being really expensive, particularly if some of the underlying tables being joined are huge. Because your database, in my case, Postgres, will pull a lot of this data into the giant sort of in-memory table as it's, like, building all these things together and to filter them out. And it doesn't have the ability to optimize the way it would on a more traditional relation. A solution to this is to make sure that the sort of subqueries that are getting unioned are optimized individually. And that can mean moving conditions that are outside the union inside. So, if I'm chaining, I don't know, where active is true on the outer query; on the union itself, I might need to move that inside each of the subqueries. So, now, in the two or three subqueries that I'm unioning, each of them needs to have a 'where active true' chained on it. STEPHANIE: Interesting. I have heard this about using ActiveRecord scopes before, that if the scopes are quite complex, chaining them might not lead to the most performant query. That is interesting. By optimizing the subqueries, did you kind of change the meaning of them? Was that something that ended up happening? JOËL: So, the annoying thing is that I have a scope that has the union in it, and it does some things sort of on its own. And it's used in some places. There are also other places that will try to take that scope that has the union on it, chain some other scopes that do other joins and some more filters, and that is horribly inefficient. So, I need to sort of rewrite the sort of subqueries that get union to include all these new conditions that only happen in this one use case and not in the, like, three or four others that rely on that union. So, now I end up with some, like, awkward query duplication in different call sites that I'm not super comfortable about, but, unfortunately, I've not found a good way to make this sort of nicely reusable. Because when you want to chain sort of more things onto the union, you need to shove them in, and there's no clean way of doing that. STEPHANIE: Yeah. I think another way I've seen this resolved is just writing it in SQL if it's really complex and it becoming just a bespoke query. We're no longer trying to use the scope that could be reusable. JOËL: Right. Right. In this case, I guess, I'm, like, halfway in between in that I'm using the ActiveRecord DSL, but I am not reusing scopes and things. So, I sort of have the, I don't know, naive union implementation that can be fine in all of the simpler use cases that are using it. And then the query that tries to combine the union with some other fancy stuff it just gets its own separate implementation different than the others that it has optimized. So, there are sort of two separate paths, two separate implementations. I did not drop down to writing raw SQL because I could use the ActiveRecord DSL. So, that's what I've been working with. What's new in your world this week? STEPHANIE: So, a couple of weeks ago, I think, I mentioned that I was working on a Rails 7 upgrade, and we have gotten it out the door. So, now the client application I'm working on is on Rails 7, which is exciting for the team. But in an effort to make the upgrade as incremental as possible, we did, like, back out of a few of the new application config changes that would have led us down a path of more work. And now we're kind of following up a little bit to try to turn some of those configs on to enable them. And it was very exciting to kind of, like, officially be on Rails 7. But I do feel like we tried to go for, like, the minimal amount of work possible in that initial big change. And now we're having to kind of backfill a little bit on some of the work that was a little bit more like, oh, I'm not really sure, like, how big this will end up being. And it's been really interesting work, I think, because it requires, like, two different mindsets. Like, one of them is being really patient and focused on tedious work. Like, okay, what happens when we enable this config option? Like, what changes? What errors do we see? And then having to turn it back off and then go in and fix them. But then another, I think, like, headspace that we have to be in is making decisions about what to do when we come to a crossroads around, like, okay, now that we are starting to see all the changes that are coming about from enabling this config, is this even what we want to do? And it can be really hard to switch between those two modes of thinking. JOËL: Yeah. How do you try to balance between the two? STEPHANIE: So, I luckily have been pairing with another dev, and I've actually found that to be really effective because he has, I guess, just, like, a little bit more of that patience to do the more tedious, mundane [laughs] aspects of, like, driving the code changes. And I have been riding along. But then I can sense, like, once he gets to the point of like, "Oh, I'm not sure if we should keep going down this road," I can step in a little bit more and be like, "Okay, like, you know, I've seen us do this, like, five times now, and maybe we don't want to do that." Or maybe being like, "Okay, we don't have a really clear answer, but, like, who can we talk to to find out a little bit more or get their input?" And that's been working really well for me because I've not had a lot of energy to do more of that, like, more manual or tedious labor [chuckles] that comes with working on that low level of stuff. So yeah, I've just been pleasantly surprised by how well we are aligning our superpowers. JOËL: To use some classic business speech, how does it feel to be in the future on Rails 7? STEPHANIE: Well, we're not quite up, you know, up to modern days yet, but it does feel like we're getting close. And, like, I think now we're starting to entertain the idea of, like, hmm, like, could we be even on main? I don't think it's really going to happen, but it feels a little bit more possible. And, in general, like, the team thinks that that could be, like, really exciting. Or it's easier, I think, once you're a little bit more on top of it. Like, the worst is when you get quite behind, and you end up just feeling like you're constantly playing catch up. It just feels a little bit more manageable now, which is good. JOËL: I learned this week a fun fact about Rails 7.1, in particular, which is that the analyze method on ActiveRecord queries, which allowed you to sort of get SQL EXPLAIN statements, now has the ability to pass in a couple of extra parameters. So, there are symbols, and you can pass in things like analyze or verbose, which allows you to get sort of more data out of your EXPLAIN query, which can be quite nice when you're debugging for performance. So, if you're in the future and you're on Rails 7.1 and you want sort of the in-depth query plans, you don't need to copy the SQL into a Postgres console to get access to the sort of fully developed EXPLAIN plan. You can now do it by passing arguments to EXPLAIN, which I'm very happy for. STEPHANIE: That's really nice. JOËL: So, we've mentioned before that we have a developers' channel on Slack here at thoughtbot, and there's all sorts of fun conversations that happen there. And there was one recently that really got me interested, where people were talking about Ruby's reduce method, also known as inject. And it's one of those methods that's kind of complicated, or it can be really confusing. And there was a whole thread where people were talking about different mental models that they had around the reduce method and how they sort of understand the way it works. And I'd be curious to sort of dig into each other's mental models of that today. To kick us off, like, how comfortable do you feel with Ruby's reduce method? And do you have any mental models to kind of hold it in your head? STEPHANIE: Yeah, I think reduce is so hard to wrap your head around, or it might be one of the most difficult, I guess, like, functions a new developer encounters, you know, in trying to understand the tools available to them. I always have to look up the order of the arguments [laughs] for reduce. JOËL: Every time. STEPHANIE: Yep. But I feel like I finally have a more intuitive sense of when to use it. And my mental model for it is collapsing a collection into one value, and, actually, that's why I prefer calling it reduce rather than the inject alias because reduce kind of signals to me this idea of going from many things to one canonical thing, I suppose. JOËL: Yeah, that's a very common use case for reducing, and I guess the name itself, reducing, kind of has almost that connotation. You're taking many things, and you're going to reduce that down to a single thing. STEPHANIE: What was really interesting to me about that conversation was that some people kind of had the opposite mental model where it made a bit more sense for them to think about injecting and, specifically, like, the idea of the accumulator being injected with values, I suppose. And I kind of realized that, in some ways, they're kind of antonyms [chuckles] a little bit because if you're focused on the accumulator, you're kind of thinking about something getting bigger. And that kind of blew my mind a little bit when I realized that, in some ways, they can be considered opposites. JOËL: That's really fascinating. It is really interesting, I think, the way that we can take the name of a method and then almost, like, tell ourselves a story about what it does that then becomes our way of remembering how this method works. And the story we tell for the same method name, or in this case, maybe there's a few different method names that are aliases, can be different from person to person. I know I tend to think of inject less in terms of injecting things into the accumulator and more in terms of injecting some kind of operator between every item in the collection. So, if we have an array of numbers and we're injecting plus, in my mind, I'm like, oh yeah, in between each of the numbers in the collection, just inject a little plus sign, and then do the math. We're summing all the items in the collection. STEPHANIE: Does that still hold up when the operator becomes a little more complex than just, you know, like, a mathematical operator, like, say, a function? JOËL: Well, when you start passing a block and doing custom logic, no, that mental model kind of falls apart. In order for it to work, it also has to be something that you can visualize as some form of infix operator, something that goes between two values rather than, like, a method name, which is typically in prefix position. I do want to get at this idea, though: the difference between sort of the block version versus passing. There are ways where you can just do a symbol, and that will call a method on each of the items. Because I have a bit of a hot take when it comes to writing reduce blocks or inject blocks that are more accessible, easier to understand. And that is, generally, that you shouldn't, or more specifically, you should not have a big block body. In general, you should be either using the symbol version or just calling a method within the block, and it's a one-liner. Which means that if you have some complex behavior, you need to find a way to move that out of this sort of collection operation and into instance methods on the objects being iterated. STEPHANIE: Hmm, interesting. By one-liner do you mean passing the name of the method as a proc or actually, like, having your block that then calls the method? Because I can see it becoming even simpler if you have already extracted a method. JOËL: Yeah, if you can do symbol to proc, that's amazing, or even if you can use just the straight-up symbol way of invoking reduce or inject. That typically means you have to start thinking about the types of objects that you are working with and what methods can be moved onto them. And sometimes, if you're working with hashes or something like that that don't have domain methods for what you want, that gets really awkward. And so, then maybe that becomes maybe a hint that you've got some primitive obsession happening and that this hash that sort of wants a domain object or some kind of domain method probably should be extracted to its own object. STEPHANIE: I'll do you with another kind of spicy take. I think, in that case, maybe you don't want a reduce at all. If you're starting to find that...well, okay, I think it maybe could depend because there could be some very, like, domain-specific logic. But I have seen reduce end up being used to transform the structure of the initial collection when either a different higher-order function can be used or, I don't know, maybe you're just better off writing it with a regular loop [laughs]. It could be clearer that way. JOËL: Well, that's really interesting because...so, you mentioned the idea that we could use a different higher-order function, and, you know, higher-order function is that fancy term, just a method that accepts another method as an argument. In Ruby, that just means your method accepts a block. Reduce can be used to implement pretty much the entirety of enumerable. Under the hood, enumerable is built in terms of each. You could implement it in terms of reduce. So, sometimes it's easy to re-implement one of the enumerable methods yourself, accidentally, using reduce. So, you've written this, like, complex reduce block, and then somebody in review comes and looks at it and is like, "Hey, you realize that's just map. You've just recreated map. What if we used map here?" STEPHANIE: Yeah. Another one I've seen a lot in JavaScript land where there are, you know, fewer utility functions is what we now have in Ruby, tally. I feel like that was a common one I would see a lot when you're trying to count instances of something, and I've seen it done with reduce. I've seen it done with a for each. And, you know, I'm sure there are libraries that actually provide a tally-like function for you in JS. But I guess that actually makes me feel even more strongly about this idea that reduce is best used for collapsing something as opposed to just, like, transforming a data structure into something else. JOËL: There's an interesting other mental model for reduce that I think is hiding under what we're talking about here, and that is the idea that it is a sort of mid-level abstraction for dealing with collections, as opposed to something like map or select or some of those other enumerable helpers because those can all be implemented in terms of reduce. And so, in many cases, you don't need to write the reduce because the library maintainer has already used reduce or something equivalent to build these higher-level helpers for you. STEPHANIE: Yeah, it's kind of in that weird point between, like, very powerful [chuckles] so that people can start to do some funky things with it, but also sometimes just necessary because it can feel a little bit more concise that way. JOËL: I've done a fair amount of functional programming in languages like Elm. And there, if you're building a custom data structure, the sort of lowest-level way you have of looping is doing a recursion, and recursions are messy. And so, what you can do instead as a library developer is say, "You know what, I don't want to be writing recursions for all of these." I don't know; maybe I'm building a tree library. I don't want to write a recursion for every different function that goes over trees if I want to map or filter or whatever. I'm going to write reduce using recursion, and then everything else can be written in terms of reduce. And then, if people want to do custom things, they don't need to recurse over my tree. They can use this reduce function, which allows them to do most of the traversals they want on the tree without needing to touch manual recursion. So, there's almost, like, a low-level, mid-level, high-level in the library design, where, like, lowest level is recursion. Ideally, nobody touches that. Mid-level, you've got reducing that's built out on top of recursion. And then, on top of that, you've got all sorts of other helpers, like mapping, like filtering, things like that. STEPHANIE: Hmm. I'm wondering, do you know of any performance considerations when it comes to using reduce built off a recursion? JOËL: So, one of the things that can be really nice is that writing a recursion yourself is dangerous. It's so easy to, like, accidentally introduce Stack Overflow. You could also write a really inefficient one. So, ideally, what you do is that you write a reduce that is safe and that is fast. And then, everybody else can just use that to not have to worry about the sort of mechanics of traversing the collection. And then, just use this. It already has all of the safety and speed features built in. You do have to be careful, though, because reduce, by nature, traverses the entire collection. And if you want to break out early of something expensive, then reduce might not be the tool for you. STEPHANIE: I was also reading a little bit about how, in JavaScript, a lot of developers like to stick to that idea of a pure function and try to basically copy the entire accumulator for every iteration and creating a new object for that. And that has led to some memory issues as well. As opposed to just mutating the accumulator, having, especially when you, you know, are going through a collection, like, really large, making that copy every single time and creating, yeah [chuckles], just a lot of issues that way. So, that's kind of what prompted that question. JOËL: Yeah, that can vary a lot by language and by data structure. In more functional languages that try to not mutate, they often have this idea of what they call persistent data structures, where you can sort of create copies that have small modifications that don't force you to copy the whole object under the hood. They're just, like, pointers. So, like, hey, we, like, are the same as this other object, but with this extra element added, or something like that. So, if you're growing an array or something like that, you don't end up with 10,000 copies of the array with, like, a new element every time. STEPHANIE: Yeah, that is interesting. And I feel like trying to adopt different paradigms for different tools, you know, is not always as straightforward as some wish it were [laughs]. JOËL: I do want to give a shout-out to an academic paper that is...it is infamously dense. The title of it is Functional Programming with Bananas, Lenses, and Barbed Wire. STEPHANIE: It doesn't sound dense; it sounds fun. Well, I don't about barbed wire. JOËL: It sounds fun, right? STEPHANIE: Yeah, but certainly quirky [laughs]. JOËL: It is incredibly dense. And they've, like, created this custom math notation and all this stuff. But the idea that they pioneered there is really cool, this idea that kind of like I was talking about sort of building libraries in different levels. Their idea is that recursion is generally something that's unsafe and that library and language designers should take care of all of the recursion and instead provide some of these sort of mid-level helper methods to do things. Reducing is one of them, but their proposal is that it's not the only one. There's a whole sort of family of similar methods that are there that would be useful in different use cases. So, reduce allows you to sort of traverse the whole thing. It does not allow you to break out early. It does not allow you to keep sort of track of a sort of extra context element if you want to, like, be traversing a collection but have a sort of look forward, look back, something like that. So, there are other variations that could handle those. There are variations that are the opposite of reduce, where you're, like, inflating, starting from a few parameters and building a collection out of them. So, this whole concept is called recursion schemes, and you can get, like, really deep into some theory there. You'll hear fancy words like catamorphisms and anamorphisms. There's a whole world to explore in that area. But at its core, it's this idea that you can sort of slice up things into this sort of low-level recursion, mid-level helpers, and then, like, kind of userland helpers built on top of that. STEPHANIE: Wow. That is very intense; it sounds like [chuckles]. I'm happy not to ever have to write a recursion ever again, probably [laughs]. Have you ever, as just a web developer in your day-to-day programming, found a really good use case for dropping down to that level? Or are you kind of convinced that, like, you won't really ever need to? JOËL: I think it depends on the paradigm of the language you're working in. In Ruby, I've very rarely needed to write a recursion. In something like Elm, I've had to do that, eh, not infrequently. Again, it depends, like, if I'm doing more library-esque code versus more application code. If I'm writing application code and I'm using an existing, let's say, tree library, then I typically don't need to write a recursion because they've already written traversals for me. If I'm making my own and I have made my own tree libraries, then yes, I'm writing recursions myself and building those traversals so that other people don't have to. STEPHANIE: Yeah, that makes sense. I'd much rather someone who has read that paper [laughs] write some traversal methods for me. JOËL: And, you know, for those who are curious about it, we will put a link to this paper in the description. So, we've talked about a sort of very academic mental model way of thinking about reducing. I want to shift gears and talk about one that I have found is incredibly practical, and that is the idea that reduce is a way to scale an operation that works on two objects to an operation that works on sort of an unlimited number of objects. To make it more concrete, take something like addition. I can add two numbers. The plus operator allows me to take one number, add another, get a sum. But what if I want to not just add two numbers? I want to add an arbitrary number of numbers together. Reduce allows me to take that plus operator and then just scale it up to as many numbers as I want. I can just plug that into, you know, I have an array of numbers, and I just call dot reduce plus operator, and, boom, it can now scale to as many numbers as I want, and I can sum the whole thing. STEPHANIE: That dovetails quite nicely with your take earlier about how you shouldn't pass a block to reduce. You should extract that into a method. Don't you think? JOËL: I think it does, yes. And then maybe it's, like, sort of two sides of a coin because I think what this leads to is an approach that I really like for reducing because sometimes, you know, here, I'm starting with addition. I'm like, oh, I have addition. Now, I want to scale it up. How do I do that? I can use reduce. Oftentimes, I'm faced with sort of the opposite problem. I'm like, oh, I need to add all these numbers together. How do I do that? I'm like, probably with a reduce. But then I start writing the block, and, like, I get way too into my head about the accumulator and what's going to happen. So, my strategy for writing reduce expressions is to, instead of trying to figure out how to, like, do the whole thing together, first ask myself, how do I want to combine any two elements that are in the array? So, I've got an array of numbers, and I want to sum them all. What is the thing I need to do to combine just two of those? Forget the array. Figure that out. And then, once I have that figured out, maybe it's an existing method like plus. Maybe it's a method I need to define on it if it's a custom object. Maybe it's a method that I write somewhere. Then, once I have that, I can say, okay, I can do it for two items. Now, I'm going to scale it up to work for the whole array, and I can plug it into reduce. And, at that point, the work is already basically done, so I don't end up with a really complex block. I don't end up, like, almost ending in, like, a recursive infinite loop in my head because I do that. STEPHANIE: [laughs]. JOËL: So, that approach of saying, start by figuring out what is the operation you want to do to combine two elements, and then use reduce as a way to scale that to your whole array is a way that I've used to keep things simple in my mind. STEPHANIE: Yeah, I like that a lot as a supplement to the model I shared earlier because, for me, when I think about reducing as, like, collapsing into a value, you kind of are just like, well, okay, I start with the collection, and then somehow I get to my single value. But the challenge is figuring out how that happens [laughs], like, the magic that happens in between that. And I think another alias that we haven't mentioned yet for reduce that is used in a lot of other languages is fold. And I actually like that one a lot, and I think it relates to your mental model. Because when I think about folding, I'm picturing folding up a paper like an accordion. And you have to figure out, like, what is the first fold that I can make? And just repeating that over and over to get to your little stack of accordion paper [laughs]. And if you can figure out just that first step, then you pretty much, like, have the recipe for getting from your initial input to, like, your desired output. JOËL: Yeah. I think fold is interesting in that some languages will make a distinction between fold and reduce. They will have both. And typically, fold will require you to pass an initial value, like a starting accumulator, to start it off. Whereas reduce will sort of assume that your array can use the first element of the array as the first accumulator. STEPHANIE: Oh, I just came up with another visual metaphor for this, which is, like, folding butter into croissant pastry when the butter is your initial value [laughs]. JOËL: And then the crust is, I guess, the elements in the array. STEPHANIE: Yeah. Yeah. And then you get a croissant out of it [laughs]. Don't ask me how it gets to a perfectly baked, flaky, beautiful croissant, but somehow that happens [laughs]. JOËL: So, there's an interesting sort of subtlety here that I think happens because there are sort of two slightly different ways that you can interact with a reduce. Sometimes, your accumulator is of the same type as the elements in your array. So, you're summing an array of numbers, and your accumulator is the sum, but each of the elements in the array are also numbers. So, it's numbers all the way through. And sometimes, your accumulator has a different type than the items in the array. So, maybe you have an array of words, and you want to get the sum of all of the characters and all the words. And so, now your accumulator is a number, but each of the items in the array are strings. STEPHANIE: Yeah, that's an interesting distinction because I think that's where you start to see the complex blocks being passed and reduced. JOËL: The complex blocks, definitely; I think they tend to show up when your accumulator has a different type than the individual items. So, maybe that's, like, a slightly more complicated use case. Oftentimes, too, the accumulator ends up being some, like, more complex, like, hash or something that maybe would really benefit from being a custom object. STEPHANIE: I've never done that before, but I can see why that would be really useful. Do you have an example of when you used a custom object as the accumulator? JOËL: So, I've done it for situations where I'm working with objects that are doing tally-like operations, but I'm not doing just a generic tally. There's some domain-specific stuff happening. So, it's some sort of aggregate counter on multiple dimensions that you can use, and that can get really ugly. And you can either do it with a reduce or you can have some sort of, like, initial version of the hash outside and do an each and mutate the hash and stuff like that. All of these tend to be a little bit ugly. So, in those situations, I've often created some sort of custom object that has some instance methods that allow to sort of easily add new elements to it. STEPHANIE: That's really interesting because now I'm starting to think, what if the elements in the collection were also a custom object? [chuckles] And then things could, I feel like, could be really powerful [laughs]. JOËL: There's often a lot of value, right? Because if the items in the collection are also a custom object, you can then have methods on them. And then, again, the sort of complexity of the reduce can sort of, like, fade away because it doesn't own any of the logic. All it does is saying, hey, there's a thing you can do to combine two items. Let's scale it up to work on a collection of items. And now you've sort of, like, really simplified what logic is actually owned inside the reduce. I do want to shout out for those listeners who are theory nerds and want to dig into this. When you have a reduce, and you've got an operation where all the values are of the same type, including the accumulator, typically, what you've got here is some form of monoid. It may be a semigroup. So, if you want to dig into some theory, those are the words to Google and to go a deep dive on. The main thing about monoids, in particular, is that monoids are any objects that have both a sort of a base case, a sort of empty version of themselves, and they have some sort of combining method that allows you to combine two values of that type. If your object has these things and follows...there's a few rules that have to be true. You have a monoid. And they can then be sort of guaranteed to be folded nicely because you can plug in their base case as your initial accumulator. And you can plug in their combining method as just the value of the block, and everything else just falls into place. A classic here is addition for numbers. So, if you want to add two numbers, your combining operator is a plus. And your sort of empty value is a zero. So, you would say, reduce initial value is zero, array of numbers. And your block is just plus, and it won't sum all of the numbers. You could do something similar with strings, where you can combine strings together with plus, and, you know, your empty string is your base case. So, now you're doing sort of string concatenation over arbitrary number of strings. Turns out there's a lot of operations that fall into that, and you can even define some of those on your custom object. So, you're like, oh, I've got a custom object. Maybe I want some way of, like, combining two of them together. You might be heading in the direction of doing something that is monoidal, and if so, that's a really good hint to know that it can sort of, like, just drop into place with a fold or a reduce and that that is a tool that you have available to you. STEPHANIE: Yeah, well, I think my eyes, like, widened a little bit when you first dropped the term monoid [laughs]. I do want to spend the last bit of our time talking about when not to use reduce, and, you know, we did talk a lot about recursion. But when do you think a regular old loop will just be enough? JOËL: So, you're suggesting when would you want to use something like an each rather than a reduce? STEPHANIE: Yeah. In my mind, you know, you did offer, like, a lot of ways to make reduce simpler, a lot of strategies to end up with some really nice-looking syntax [chuckles], I think. But, oftentimes, I think it can be equally as clear storing your accumulator outside of the iteration and that, like, is enough for me to understand. And reduce takes a little bit of extra overhead to figure out what I'm looking at. Do you have any thoughts about when you would prefer to do that? Or do you think that you would usually reach for something else? JOËL: Personally, I generally don't like the pattern of using each to iterate over a collection and then mutate some external accumulator. That, to me, is a bit of a code smell. It's a sign that each is not quite powerful enough to do the thing that I want to do and that I'm probably needing some sort of more specialized form of iteration. Sometimes, that's reduce. Oftentimes, because each can suffer from the same problem you mentioned from reduce, where it's like, oh, you're doing this thing where you mutate an external accumulator. Turns out what you're really doing is just map. So, use map or use select or, you know, some of the other built-in iterators from the enumerable library. There's a blog post on the thoughtbot blog that I continually link to people. And when I see the pattern of, like, mutating an external variable with each, yeah, I tend to see that as a bit of a code smell. I don't know that I would never do it, but whenever I see that, it's a sign to me to, like, pause and be like, wait a minute, is there a better way to do this? STEPHANIE: Yeah, that's fair. I like the idea that, like, if there's already a method available to you that is more specific to go with that. But I also think that sometimes I'd rather, like, come across that pattern of mutating a variable outside of the iteration over, like, someone trying to do something clever with the reduce. JOËL: Yeah, I guess reduce, especially if it's got, like, a giant block and you've got then, like, things in there that break or call next to skip iterations and things like that, that gets really mind-bending really quickly. I think a case where I might consider using an each over a reduce, and that's maybe generally when I tend to use each, is when I'm doing side effects. If I'm using a reduce, it's because I care about the accumulated value at the end. If I'm using each, it's typically because I am trying to do some amount of side effects. STEPHANIE: Yeah, that's a really good call out. I had that written down in my notes, and I'm glad you brought it up because I've seen them get conflated a little bit, and perhaps maybe that's the source of the pain that I'm talking about. But I really like that heuristic of reduce as, you know, you're caring about the output, as opposed to what's going on inside. Like, you don't want any unexpected behavior. JOËL: And I think that applies to something like map as well. My sort of heuristic is, if I'm doing side effects, I want each. If I want transformed values that are sort of one-to-one in the collection, I want map. If I want a single sort of aggregate value, then I want reduce. STEPHANIE: I think that's the cool thing about mixing paradigms sometimes, where all the strategies you talked about in terms of, you know, using custom, like, objects for your accumulator, or the elements in your collection, like, that's something that we get because, you know, we're using an object-oriented language like Ruby. But then, like, you also are kind of bringing the functional programming lens to, like, when you would use reduce in the first place. And yeah, I am just really excited now [chuckles] to start looking for some places I can use reduce after this conversation and see what comes out of it. JOËL: I think I went on a bit of an interesting journey where, as a newer programmer, reduce was just, like, really intense. And I struggled to understand it. And I was like, ban it from code. I don't want to ever see it. And then, I got into functional programming. I was like, I'm going to do reduce everywhere. And, honestly, it was kind of messy. And then I, like, went really deep on a lot of functional theory, and I think understood some things that then I was able to take back to my code and actually write reduce expressions that are much simpler so that now my heuristic is like, I love reduce; I want to use it, but I want as little as possible in the reduce itself. And because I understand some of these other concepts, I have the ability to know what things can be extracted in a way that will feel very natural, in a way that myself from five years ago would have just been like, oh, I don't know. I've got this, you know, 30-line reduce expression that I know is complicated, but I don't know how to improve. And so, a little bit of the underlying theory, I don't think it's necessary to understand these simplified reduces, but as an author who's writing them, I think it helps me write reduces that are simpler. So, that's been my journey using reduce. STEPHANIE: Yeah. Well, thanks for sharing. And I'm really excited. I hope our listeners have learned some new things about reduce and can look at it from a different light. JOËL: There are so many different perspectives. And I think we keep discovering new mental models as we talk to different people. It's like, oh, this particular perspective. And there's one that we didn't really dig into but that I think makes more sense in a functional world that's around sort of deconstructing a structure and then rebuilding it with different components. The shorthand name of this mental model, which is a fairly common one, is constructor replacement. For anyone who's interested in digging into that, we'll link it in the show notes. I gave a talk at an Elm meetup where I sort of dug into some of that theory, which is really interesting and kind of mind-blowing. Not as relevant, I think, for Rubyists, but if you're in a language that particularly allows you to build custom structures out of recursive types or what are sometimes called algebraic data types, or tagged unions, or discriminated unions, this thing goes by a bajillion names, that is a really interesting other mental model to look at. And, again, I don't think the list that we've covered today is exhaustive. You know, I would love it for any of our listeners; if you have your own mental models for how to think about folding, injecting, reducing, send them in: hosts@bikeshed.fm. We'd love to hear them. STEPHANIE: And on that note, shall we wrap up? JOËL: Let's wrap up. STEPHANIE: Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeee!!!!!!! AD: Did you know thoughtbot has a referral program? If you introduce us to someone looking for a design or development partner, we will compensate you if they decide to work with us. More info on our website at: tbot.io/referral. Or you can email us at referrals@thoughtbot.com with any questions.

The Bike Shed
416: Multi-Dimensional Numbers

The Bike Shed

Play Episode Listen Later Feb 27, 2024 39:31


Joël discusses the challenges he encountered while optimizing slow SQL queries in a non-Rails application. Stephanie shares her experience with canary deploys in a Rails upgrade. Together, Stephanie and Joël address a listener's question about replacing the wkhtml2pdf tool, which is no longer maintained. The episode's main topic revolves around the concept of multidimensional numbers and their applications in software development. Joël introduces the idea of treating objects containing multiple numbers as single entities, using the example of 2D points in space to illustrate how custom classes can define mathematical operations like addition and subtraction for complex data types. They explore how this approach can simplify operations on data structures, such as inventories of T-shirt sizes, by treating them as mathematical objects. EXPLAIN ANALYZE visualizer (https://explain.dalibo.com/) Canary in a coal mine (https://en.wikipedia.org/wiki/Sentinel_species#Canaries) Episode 413: Developer Tales of Package Management (https://bikeshed.thoughtbot.com/413) Docs for media-specific CSS (https://developer.mozilla.org/en-US/docs/Web/CSS/@media) Episode 386: Value Objects Revisited: The Tally Edition (https://bikeshed.thoughtbot.com/386) Money gem (https://github.com/RubyMoney/money) Transcript: STEPHANIE: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Stephanie Minn. JOËL: And I'm Joël Quenneville. And together, we're here to share a bit of what we've learned along the way. STEPHANIE: So, Joël, what's new in your world? JOËL: I've recently been trying to do some performance enhancements to some very slow queries. This isn't a Rails app, so we're sort of combining together a bunch of different scopes. And the way they're composing together is turning out to be really slow. And I've reached for a tool that is just really fun. It's a visualizer for SQL query plans. You can put the SQL keywords in front of a query: 'EXPLAIN ANALYZE,' and it will then output a query plan, sort of how it's going to attempt to do the work. And that might be like, oh, we're going to use this index on this table to join on this other thing, and then we're going to...maybe this is a table that we think we're going to do a sequential scan through and, you know, it builds out a whole thing. It's a big block of text, and it's kind of intimidating to look at. So, there are a few websites out there that will do this. You just paste a query plan in, and they will build you a nice, little visualization, almost like a tree of, like, tasks to be done. Oftentimes, they'll also annotate it with metadata that they pulled from the query plan. So, oh, this particular node is the really expensive one because we're doing a sequential scan of this table that has 15 million rows in it. And so, it's really useful to then sort of pinpoint what are the areas that you could optimize. STEPHANIE: Nice. I have known that you could do that EXPLAIN ANALYZE on a SQL query, but I've never had to do it before. Is this your first time, or is it just your first time using the visualizer? JOËL: I've played around with EXPLAIN ANALYZE a little bit before. Pro tip: In Rails, if you've got a scope, you can just chain dot explain on the end, and instead of running the query, it will run the EXPLAIN version of it and return the query plan. So, you don't need to, like, turn into SQL then manually run it in your database system to get the EXPLAIN. You can just tack a dot explain on there to get the query plan. It's still kind of intimidating, especially if you've got a really complex query that's...this thing might be 50 lines long of EXPLAIN with all this indentation and other stuff. So, putting it into a sort of online visualizer was really helpful for the work that I was doing. So, it was my first time using an online visualizer. There are a few out there. I'll link to the one that I used in the show notes. But I would do that again, would recommend. STEPHANIE: Nice. JOËL: So, Stephanie, what's new in your world? STEPHANIE: So, I actually just stepped away from being in the middle of doing a Rails upgrade [chuckles] and releasing it to production just a few minutes before getting on to record with you on this podcast. And the reason I was able to do that, you know, without feeling like I had to just monitor to see how it was going is because I'm on a project where the client is using canary deploys. And I was so pleasantly surprised by how easy it made this experience where we had decided to send the canary release earlier this morning. And the way that they have it set up is that the canary goes to 10% of traffic. 10% of the users were on Rails 7 for their sessions. And we saw a couple of errors in our error monitoring service. And we are like, "Okay, like, let's take a look at this, see what's going on." And it turns out it was not too big of a deal because it had to do with, like, a specific page. And, for the most part, if a user did encounter this error, they probably wouldn't again after refreshing because they had, like, a 90% chance [chuckles] of being directed to the previous version where everything is working. And we were kind of making that trade-off of like, oh, we could hotfix this right now on the canary release. But then, as we were starting to debug a little bit, it was a bit hairier than we expected originally. And so, you know, I said, "I have to hop on to go record The Bike Shed. So, why don't we just take this canary down just for the time being to take that time pressure off? And it's Friday, so we're heading into the weekend. And maybe we can revisit the issue with some fresh eyes." So, I'm feeling really good, actually. And I'm glad that we were able to do something that seems scary, but there were guardrails in place to make it a lot more chill. JOËL: Yay for the ability to roll back. You used the term canary release. That's not one that I'm familiar with. Can you explain what a canary release is? STEPHANIE: Oh yeah. Have you heard of the phrase 'Canary in the coal mine'? JOËL: I have. STEPHANIE: Okay. So, I believe it's the same idea where you are, in this case, releasing a potentially risky change, but you don't want to immediately make it available to, like, all of your users. And so, you send this change to, like, a small reach, I suppose, and give it a little bit of a test and see [chuckles] what comes back. And that can help inform you of any issues or risks that might happen before kind of committing to deploying a potentially risky change with a bigger impact. JOËL: Is this handled with something like a feature flag framework? Or is this, like, at an infrastructure level where you're just like, "Hey, we've got the canary image in, like, one container on one server, and then we'll redirect 10% of traffic to that to be served by that one and the other 90% to be served by the old container or something like that"? STEPHANIE: Yeah, in this case, it was at the infrastructure level. And I have also seen something similar at a feature flag level, too, where you're able to have some more granularity around what percent of users are seeing a feature. But I think with something like a Rails upgrade, it was nice to be able to have that at that infrastructure level. It's not necessarily, like, a particular page or feature to show or not show. JOËL: Yeah, I think you would probably want that at a higher level when you're changing over the entire app. Is this something that you had to custom-build yourself or something that just sort of came out of the box with some of the infrastructure tools you're using? STEPHANIE: It came out of the box, actually. I just joined this client project this week and was very delighted to see just some really great deployment infrastructure and getting to meet the DevOps engineers, too, who built it. And they're really proud of it. They kind of walked us through our first release earlier this week. And he was telling me, the DevOps engineer, that this was actually his favorite part of the job, is walking people through their first release and being their buddy while they do it. Because I think he gets to also see users interact with the tool that he built, and he had a lot of pride in that, so it was a very delightful experience. JOËL: That's so wonderful. I've been on so many projects where the sort of infrastructure side of things is not the team's strong point, and releasing can be really scary. And it's great to hear the opposite of that. We recently received a question for Stephanie based on an earlier episode. So, the question asks, "In episode 413, Stephanie discussed a recent issue she encountered with wkhtml2pdf. The episode turned into a deeper discussion about package management, but I don't think it ever cycled back to the conclusion. I'm curious: how did Stephanie solve this dilemma? We're facing the same issue on a project that my team maintains. It's an old codebase, and there are bits of old code that use wkhtml2pdf to generate print views of our data in our application. The situation is fairly dire. wkhtml2pdf is no longer maintained. In fact, it won't even be available to install from our operating system's package repositories in June. We're on FreeBSD, but I assume the same will be eventually true for other operating systems. And so, unless you want to maintain some build step to check out and compile the source code for an application that will no longer receive security updates, just living with it isn't really an option. There are three options we're considering. One, eliminate the dependency entirely. Based on user feedback, it sounds like our old developers were using this library to generate PDFs when what users really wanted was an easy way to print. So, instead of downloading a PDF, just ensure the screen has a good print style sheet and register an onload handler to call window dot print. We're thinking we could implement this as an A/B test to the feature to test this theory. Or two, replace wkhtml2pdf with a call to Headless Chrome and use that to generate the PDF. Or, three, replace wkhtml2pdf with a language-level package. For us, that might be the dompdf library available via Composer because we're a PHP shop." Yeah, a lot to unpack here. Any high-level thoughts, Stephanie? STEPHANIE: My first thought while I was listening to you read that question is that wkhtml2pdf is such a mouthful [laughs]. And I was impressed how you managed to say it at least, like, five times. JOËL: So, I try to say that five times fast. STEPHANIE: And then, my second high-level thought was, I'm so sorry to Brian, our listener who wrote in, because I did not really solve this dilemma [chuckles] for my project and team. I kind of kicked the can down the road, and that's because this was during a support and maintenance rotation that I've talked a little bit about before on the show. I was only working on this project for about a week. And what we thought was a small bug to figure out why PDFs were a little bit broken turned out, as you mentioned, to be this kind of big, dire dilemma where I did not feel like I had enough information to make a good call about what to do. So, I kind of just shared my findings that, like, hey, there is kind of a risk and hoping that someone else [laughs] would be able to make a better determination. But I really was struck by the options that you were considering because it was actually a bit of a similar situation to the bug I was sharing where the PDF that was being generated that was slightly broken. I don't think it was, like, super valuable to our users that it be in the form of a PDF. It really was just a way for them to print something to have on handy as a reference from, you know, some data that was generated from the app. So, yeah, based on what you're sharing, I feel really excited about the first one. Joël, I'm sure you have some opinions about this as well. JOËL: I love sort of the bigger picture thinking that Brian is doing here, sort of stepping back and being like, wait, why do we even need PDF here, and how are our customers using it? I think those are the really good questions to ask before sinking a ton of time into coming up with something that might be, like, a bit of a technical wonder. Like, hey, we managed to, like, do this PDF generation thing that we had to, like, cobble together so many other things. And it's so cool technically, but does it actually solve the underlying problem? So, shout out to Brian for thinking about it in those terms. I love that. Second cool thing that I wanted to shout out, because I think this is a feature of browsers that not many people are aware of; you can have multiple style sheets for your page, and you can tag them to be for different media. So, you can have a style sheet that only gets applied when you print versus when you display on screen. And there are a couple of others. I don't remember exactly what they are. I'll link to the docs in the show notes. But taking advantage of this, like, this is old technology but making that available and saying, "Yeah, we'll make it so that it's nice when you print, and we'll maybe even, you know, a link or a button with JavaScript so that you could just Command-P or Control-P to print. But we'll have a button in there as well that will allow you to print to PDF," and that solves your problem right there. STEPHANIE: Yeah, that's really cool. I didn't know that about being able to tag style sheets for different media types. That's really fascinating. And I like that, yeah, we're just eliminating this dependency on something, like, potentially really complex with a, hopefully, kind of elegant and modern solution, maybe. JOËL: And your browser is already able to do so many of these things. Why do we sort of try to recreate it? Printing is a thing browsers have been able to do for a long time. Printing to PDF is a thing that you can do for a long time. I will sometimes use that on sites where I need to, let's say I'm purchasing something, and I need some sort of receipt to expense, but they won't give me a download, a PDF download that I can send to the accounting team, so I will print to PDF the, like, HTML view. And that works just fine. It's kind of a workaround hack. Sometimes, it doesn't work well because the HTML page is just not well set up to, like, show up on a PDF page. You get some, like, weird, like, pagination issues or things like that. But, you know, just a little bit of thought for a print style sheet, especially for something you know that people are likely going to want to print or to save to PDF, that's a nice touch. STEPHANIE: Yeah. So, good luck, Brian, and let us know how this goes and any outcomes you find successful. So, for today's longer topic, I was excited because I saw, Joël, you dropped something in our topic backlog: Multidimensional Numbers. I'm curious what prompted this idea and what you wanted to say about it. JOËL: We did an episode a while back where we talked about value objects, wrapping numbers, wrapping collections. This is Episode 386, and we were talking about tallying, specifically working with collections of T-shirt sizes and doing math on these sort of objects that might contain multiple numbers. And a sort of sidebar from that that we didn't really get into is the idea that objects that contain sort of multiple numbers can be treated as a number themselves. And I think a great example of this is something like a point in two-dimensional space. It's got an x coordinate, a y coordinate. It's two numbers, but you can treat sort of the combination of the two of them together as a single number. There's a whole set of coordinate math that you can do to do things like add coordinates together, subtract them, find the distance between them. There's a whole field of vector math that we can do on those. And I think learning to recognize that numbers are not just instances of the integer or the float class but that there could be these more complex things that are also numbers is maybe an important realization and something that, as developers, if we think of these sort of more complex values as numbers, or at least mathematical objects, then that will help us write better code. STEPHANIE: Cool. Yeah. When you were first talking about 2D points, I was thinking about if I have experience working with that before or, like, having to build something really heavily based off of, like, a canvas or, you know, a coordinate system. And I couldn't think of any really good examples until I thought about, like, geographic locations. JOËL: Oh yeah, like a latitude, longitude. STEPHANIE: Yeah, exactly. Like, that is a lot more common, I think, for various types of just, like, production applications than 2D points if you're not working on, like, a video game or something like that, I think. JOËL: Right, right. I think you're much more likely to be working with 2D points on some more sort of front-end-heavy application. I was talking with someone this week about managing a seat map for concerts and events like that and sort of creating a seat map and have it be really interactive, and you can, like, click on seats and things like that. And depending on the level of libraries you're using to build that, you may have to do a lot of 2D math to make it all come together. STEPHANIE: Yeah. So, I would love to get into, you know, maybe we've realized, okay, we have some kind of compound number. What are some good reasons for using them differently than you would a primitive? JOËL: So, you mentioned primitives, and I think this is where maybe I'm developing a reputation about, like, always wanting value objects for everything. But it would be really easy, let's say, for an xy point to be just an array of two numbers or maybe even a hash with an x key and a y key. What's tricky about that is that then you don't have the ability to do math on them. Arrays do define the plus operator, but they don't do what you want them to do with points. It's the set union. So, adding two points would not at all do what you want, or subtracting two points. So, instead, if you have a custom 2D point class and you can define plus and minus on there to do the right thing, now they're not pairs of numbers, two values; they're a single value, and you can treat them as if they are just a single number. STEPHANIE: You mentioned that arrays don't do the right thing when you try to add them up. What is the right thing that you're thinking of then? JOËL: It probably depends a little bit on the type of object you're working with. So, with 2D points, you're probably trying to do vector addition where you're effectively saying almost, like, "Shift this point in 2D space by the amount of this other point." Or if you're doing a subtraction, you might even be asking, like, "What is the distance between these two points?" Euclidean distance, I think, is the technical term for this. There's also a couple of different ways you can multiply values. You can multiply a 2D point by just a sort of, not by another point, but by just an integer. That's called scaling. So, you're just like, oh, take this point in 2D space, but make it bigger, make it five times bigger or five times further from the origin. Or you can do some stuff with other points. But what you don't want to do is turn this into, if you're starting with arrays, you don't want to turn this into an array of four points. When you add two points in 2D space, you're not trying to create a point in 4D space. STEPHANIE: Whoa, I mean [laughs], maybe you're not. JOËL: You could but -- [laughter] STEPHANIE: Yeah. While you were saying that, I guess that is what is really cool about wrapping, encapsulating them in objects is that you get to decide what that means for you and your application, and -- JOËL: Yeah. Well, plus can mean different things, right? STEPHANIE: Yeah. JOËL: On arrays, plus means combining two arrays together. On integers, it means you do integer math. And on points, it might be vector addition. STEPHANIE: Are there any other arithmetic operators you can think of that would be useful to implement if you were trying to create some functionality on a point? JOËL: That's a good question because I think realizing the inverse of that is also a really powerful thing. Just because you create a sort of new mathematical object, a point in 2D space, doesn't mean that necessarily every arithmetic operator makes sense on it. Does it make sense to divide a point by another point? Maybe not. And so, instead of going with the mindset of, oh, a point is a mathematical object, I now need to implement all of arithmetic on this, instead, think in terms of your domain. What are the operations that make sense? What are the operations you need for this point? And, you know, maybe the answer is look up what are the common sort of vector math operations and implement those on your 2D point. Some of them will map to arithmetic operators like plus and minus, and then some of them might just be some sort of custom method where maybe you say, "Oh, I want the Euclidean distance between these two points." That's just a thing. Maybe it's just a named instance method on there. But yeah, don't feel like you need to implement all of the math operators because that's a mistake that I have made and then have ended up, like, implementing nonsensical things. STEPHANIE: [laughs] Creating your own math. JOËL: Yes, creating my own math. I've done this even on where I've done value objects to wrap single values. I was doing a class to represent currency, and I was like, well, clearly, you need, like, methods to, like, add or subtract your currency, and that's another thing. If you have, let's say, a plus method, now you can plug it into, let's say, reduce plus. And you can just sum a list of these currency objects and get back a new currency. It's not even going to give you back an integer. You just get a sort of new currency object that is the sum of all the other ones, and that's really nice. STEPHANIE: Yeah, that's really cool. It reminds me of all the magic of enumerable that you had talked about in a previous conference talk, where, you know, you just get so much out of implementing those basic operators that, like, kind of scales in handiness. JOËL: Yes. Turns out Ruby is actually a pretty nice system. If you have objects that respond to some common methods and you plug them into enumerable, and it just all kind of works. STEPHANIE: So, one thing you had said earlier that I've felt kind of excited about and wanted to highlight was you mentioned all the different ways that you could represent a 2D point with more primitive data stores, so, you know, an array of two integers, a hash with xy keys. It got me thinking about how, yeah, like, maybe if your system has to talk to another system and you're importing data or exporting data, it might eventually need to take those forms. But what is cool about having an encapsulated object in your application is you can kind of control those boundaries a little bit and have more confidence in terms of the data types that you're using within your system by having various ways to construct that, like, domain object, even if the data coming in is in a different shape. JOËL: And I think that you're hitting on one of the real beauties of object-oriented programming, where the sort of users of your object don't need to know about the internal representation. Maybe you store an array internally. Maybe it's two separate instance variables. Maybe it's something else entirely. But all that the users of your, let's say, 2D point object really need to care about is, hey, the constructor wants values in this shape, and then I can call these domain methods on it, and then the rest just sort of happens. It's an implementation detail. It doesn't matter. And you alluded, I think, to the idea that you can sort of create multiple constructors. You called them constructors. I tend to call them that as well. But they're really just class methods that will kind of, like, add some sugar on top of the constructor. So, you might have, like, a from array pair or from hash or something like that that allows you to maybe do a little bit of massaging of the data before you pass it into your constructor that might want some underlying form. And I think that's a pattern that's really nice. STEPHANIE: Yeah, I agree. JOËL: Something that can be interesting there, too, is that mathematically, there are multiple ways you can think of a 2D point. An xy coordinate pair is a common one, but another sort of system for representing a point in 2D space is called the polar coordinate system. So, you have some sort of, like, origin point. You're 0,0. And then, instead of saying so many to the left and so many up from that origin point, you give an angle and a distance, and that's where your point is. So, an angle and distance point, I think, you know, theta and magnitude are the fancy terms for this. You could, instead of creating a separate, like, oh, I have a polar coordinate point and a Cartesian coordinate point, and those are separate things, you can say, no, I just have a point in 2D space. They can be constructed from either an xy coordinate pair or a magnitude angle pair. Internally, maybe you convert one to the other for internal representation because it makes the math easier or whatever. Your users never need to know that. They just pass in the values that they want, use the constructor that is most convenient for them, and it might be both. Maybe some parts of the app require polar coordinates; some require Cartesian coordinates. You could even construct one of each, and now you can do math with each other because they're just instances of the same class. STEPHANIE: Whoa. Yeah, I was trying to think about transforming between the two types as well. It's all possible [laughs]. JOËL: Yes. Because you could have reader-type methods on your object that say, oh, for this point, give me its x coordinate; give me its y coordinate. Give me its distance from the origin. Give me its angle from the origin. And those are all questions you can ask that object, and it can calculate them. And you don't need to care what its internal representation is to be able to get all four of those. So, we've been talking about a lot of these sort of composite numbers, not composite numbers, that's a separate mathematical thing, but numbers that are composed of sort of multiple sub-numbers. And what about situations where you have two things, and one of them is not a number? I'm thinking of all sorts of units of measure. So, I don't just have three. I have three, maybe...and we were talking about currency earlier, so maybe three U.S. dollars. Or I don't just have five; I have five, you know, let's say, meters of distance. Would you consider something like that to be one of these compound number things? STEPHANIE: Right. I think I was–when we were originally talking about this, conflating the two. But I realized that, you know, just because we're adding context to a number and potentially packaging it as a value object, it's still different from what we're talking about today where, you know, there's multiple components to the number that are integral or required for it to mean what we intended to mean, if that makes sense. JOËL: Yeah. STEPHANIE: So yeah, I guess we did want to kind of make a distinction between value objects that while the additional context is important and you can implement a lot of different functionality based on what it represents, at the end of the day, it only kind of has one magnitude or, like, one integer to kind of encapsulate it represented as a number. Does that sound right? JOËL: Yeah. You did throw out the words encapsulation and value object. So, in a situation maybe where I have three US dollars, would you create some kind of custom object to wrap that? Or is that a situation where you'd be more comfortable using some kind of primitive? Like, I don't know, maybe an array pair of three and the symbol USD or something like that. STEPHANIE: Oh, I would definitely not do that [laughter]. Yeah. Like I, you know, for the most part, I think I've seen that as a currency object, and that expands the world of what we can do with it, converting into a lot of different other currencies. And yeah, just making sure those things don't get divorced from each other because that context is what gives it meaning. But when it comes to our compound numbers, it's like, without all of the components, it doesn't make sense, or it doesn't even represent the same, like, numerical value that we were trying to convey. JOËL: Right. You need both, or, you know, it could be more than two. It could be three, four, or five numbers together to mean something. You mentioned conversions, which I think is something that's also interesting because a lot of units of measure have sort of multiple ways of measuring, and you often want to convert between them. And maybe that's another case where encapsulation is really nice where, you know, maybe you have a distance object. And you have five meters, and you put that into your distance object, but then somebody wants it in feet somewhere else or in centimeters, or something like that. And it can just do all the conversion math safely inside that object, and the user doesn't have to worry about it. STEPHANIE: Right. This is maybe a bit of a tangent, but as a Canadian living in the U.S., I don't know [laughs] if you have any opinions about converting meters and feet. JOËL: The one I actually do the most often is converting Celsius to Fahrenheit and vice versa. You know, I've been here, what, 11 years now? I don't have a great intuition for Fahrenheit temperatures. So, I'm converting in my head just [laughs] on a daily basis. STEPHANIE: Yeah, that makes sense. Conversions: they're important. They help out our friends who [laughs] are on different systems of measurement. JOËL: There's a classic story that I love about unit conversions. I think it's one of the NASA Mars missions. STEPHANIE: Oh yeah. JOËL: You've heard of this one. It was trying to land on Mars, and it burned up in the atmosphere because two different teams had been building different components and used different unit systems, both according to spec for their own module. But then, when the modules try to talk to each other, they're sending over numbers in meters instead of feet or something like that. And it just caused [laughs] this, like, multi-year, multi-billion dollar project to just burn up. STEPHANIE: That's right. So, lesson of the day is don't do that. I can think of another example where there might be a little bit of misconceptions in terms of how to represent it. And I'm thinking about time and when that has been represented in multiple parts, such as in hours and, minutes and seconds. Do you have any initial impressions about a piece of data like that? JOËL: So, that's really interesting, right? Because, at first glance, it looks like, oh, it's, like, a triplet of hour, minute, seconds. It's sort of another one of these sort of compound numbers, and I guess you could implement it that way. But in reality, you're tracking a single quantity, the amount of time elapsed, and that can be represented with a single number. So, if you're representing, let's say, time of day, what would show up on your clock? That could be, depending on the resolution, number of, let's say, seconds since midnight, and that's a single counter. And then, you can do some math on it to get hours, minutes, seconds for a particular moment. But really, it's a single quantity, and we can do that with time. We can't do that with a 2D point. Like, it has to have two components. STEPHANIE: So, do you have a recommendation for what unit of time time would best be stored? I'm just thinking of all the times that I've had to do that millisecond, you know, that conversion of, you know, however many thousands of milliseconds in my head into something that actually means [laughs] something to me as a human being who measures time in hours and minutes. JOËL: My recommendation is absolutely go for a single number that you store in your, let's say, time of day object. It makes the math so much easier. You don't have to worry about, like, overflowing from one number into another when you're doing math or anything like that. And then the number that you count should be at the whatever the smallest resolution you care at. So, is there ever any time where you want to distinguish between two different milliseconds in time? Or maybe you're like, you know what? These are, like, we're tracking time of day for appointments. We don't care about the difference between two milliseconds. We don't need to track them independently. We don't even care about seconds. The most granular we ever care about things is by the minute. And so, maybe then your internal number that you track is a counter of minutes since midnight. But if you need more precision, you can go down to seconds or milliseconds or nanoseconds. But yeah, find what is the sort of the least resolution you want to get away with and then make that the unit of measure for a single counter in your object. And then encapsulate that so that nobody else needs to care that, internally, your time of day object is doing milliseconds because nobody wants to do that math. Just give me a nice, like, hours and minutes method on your object, and I will use that. I don't need to know internally what it's using. Please don't just pass around integers; wrap it in an object, especially because integers, there's enough times where you're doing seconds versus milliseconds. And when I just have an integer, I never know if the person storing this integer means seconds or milliseconds. So, I'm just like, oh, I'm going to pass to this, like, user object, a, like, time integer. And unless there's a comment or a constant, you know, that's named something duration in milliseconds or something like that, you know, or sometimes even, like, one year in milliseconds, or there's no way of knowing. STEPHANIE: Yeah. That makes a lot of sense. When you kind of choose a standard of a standard unit, it's, like, possible to make it easier [laughs]. JOËL: So, circling back to sort of the initial thing that sparked this conversation, the previous episode about T-shirt inventories, there we were dealing with what started off as, like, a hash of different T-shirt sizes and quantities of T-shirts that we had in that size, so small (five), medium (three), large (four). And then, we eventually turned that into a value object that represented...I think we called it a tally, but maybe we called it inventory. And this may be wrong, so tell me if I'm wrong here, I think we can kind of treat that as a number, as, like, one of these compound numbers. It's a sort of multidimensional number where you say, well, we have sort of three dimensions where we can have numbers that sort of increase and decrease independently. We can do math on these because we can take inventories or tallies and add and subtract them. And that's what we ended up having to do. We created a value object. We implemented plus and minus on it. There are rules for how the math works. I think this is a multidimensional number with the definition we're working on this show. Am I wrong here? STEPHANIE: I wouldn't say that you're wrong. I think I would have to think a little [laughs] more to say definitively that you're right. But I know that this example came from, you know, an application I was actually working on. And one of the main things that we had to do with these representations [laughs], I'm hesitant to call them a number, especially, but we had to compare these representations frequently because an inventory, for example, in a warehouse, wanting to make sure that it is equal to or there's enough of the inventory if someone was placing an order, which would also contain, like, a representation of T-shirt size inventory. And that was kind of where some of that math happened because, you know, maybe we don't want to let someone place an order if the inventory at the warehouse is smaller than their order, right? So, there is something really compelling about the comparison operations that we were doing that kind of is leaning me in the direction of, like, yeah, like, it makes sense to me to use this in a way that I would compare, like, quantities or numbers of something. JOËL: I think one thing that was really compelling to me, and that kind of blew my mind, was that we were trying to, like, figure out some things like, oh, we've got so many people with these size preferences, and we've got so many T-shirts across different warehouses. And we're summing them up and we're trying to say like, "How many do we need to purchase if there is a deficit?" And we can come up with effectively a formula for this. We're like, sum these numbers, when we're talking about just before we introduce sizes when it's just like, oh, people have T-shirts. They all get the count of people and a count of T-shirts in our warehouse, and we find, you know, the difference between that. And there's a few extra math operations we do. Then you introduce size, and you break it down by, oh, we've got so many of each. And now the whole thing gets really kind of messy and complicated. And you're doing these reduces and everything. When we start treating the tally of T-shirts as an object, and now it's a number that responds to plus and minus, all of a sudden, you can just plug those back into the original formula, and it all just works. The original formula doesn't care whether the numbers you're doing this formula on are simple integers or these sort of multidimensional numbers. And that blew my mind, and it was so cool. STEPHANIE: Yeah, that is really neat. And you get a lot of added benefits, too. I think the other important piece in the T-shirt size example was kind of tracking the state change, and that's so much easier when you have an object. There's just a lot more you can do with it. And even if, you know, you're not persisting every single version of the representation, you know, because sometimes you don't want to, sometimes you're really just kind of only holding it in memory to figure out if you need to, you know, do something else. But other times, you do want to persist it. And it just plugs in really well with, like, the rest of object-oriented programming [laughs] in terms of interacting with the rest of your business needs, I think, in your app. JOËL: Yeah, turns out objects, they're kind of nice. And you can do math with them. Who knew? Math is not just about integers. STEPHANIE: And on that note, shall we wrap up? JOËL: Let's wrap up. STEPHANIE: Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeee!!!!!! AD: Did you know thoughtbot has a referral program? If you introduce us to someone looking for a design or development partner, we will compensate you if they decide to work with us. More info on our website at: tbot.io/referral. Or you can email us at referrals@thoughtbot.com with any questions.

The Bike Shed
414: Spike Tasks

The Bike Shed

Play Episode Listen Later Jan 30, 2024 31:46


Joël shares his recent experience with Turbo, a JavaScript framework that simplifies adding interactivity to websites without extensive JavaScript coding. Stephanie gives an update on her quest to work from her office more, and the birds have arrived—most notably, chickadees. Stephanie and Joël address a listener question from Edward about the concept of a "spike" in software development. They discuss the nature of spikes, emphasizing that they are typically throwaway work aimed at learning and de-risking rather than producing final code, and explore how spikes can lead to better decision-making and prioritization in software development, especially in complex codebases. Transcript: STEPHANIE:  Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Stephanie Minn. JOËL: And I'm Joël Quenneville. And together, we're here to share a bit of what we've learned along the way. STEPHANIE: So, Joël, what's new in your world? JOËL: I'm pretty excited because this week, I actually got to use a little bit of Turbo for the first time. Turbo is Rails'...I guess it's not technically just for Rails. It's a sort of unobtrusive JavaScript framework that allows you to build a lot of interactive functionality without actually having to write a lot of JavaScript yourself, just by writing some HTML in a certain way. And you can add a lot of functionality and interactivity to your site without having to drop to custom writing some JavaScript. STEPHANIE: Cool. Yeah, that is exciting. I personally have not gotten to use too much of it in a production/client setting; only played around with it a little bit on my own to keep up with what's new and just kind of reading about how other people are excited to use it. So, what are your first impressions so far? JOËL: It's pretty nice. It, you know, works as advertised. My situation, I was rendering a calendar view of a lot of events, and this is completely server-rendered. And I realized, wait a minute, there are some days where I've got, like, 20 events, and I really, like, I want my calendar squares to say sort of equally sized. So, I wanted to limit myself to only showing four or five events per calendar day. And so, I added a little link at the bottom of the calendar day that says, you know, "See more." And when you click that link, it does some Turbo stuff, and it pulls in other events so that you can now sort of expand it to get the whole day. So, it's just a little bit of interactivity that you kind of get for free with Turbo just by wrapping a particular HTML tag around it and having the Turbo library loaded. STEPHANIE: That's cool. I'm excited to try it out next time I'm working on a Rails project that just needs a little bit of that interactivity, you know, just to make that experience a little bit richer. And it seems like a really good, like, low-effort way to add some of those enhancements. Based on what you described, it sounds really easy. JOËL: Yeah, I was impressed with just how low effort it all was, which is what you want, right? It works out of the box. So, for anyone who's kind of curious about it, Turbo Frames is the little bit that I used, and it worked really well. Oh, something I'm actually excited about it as well; it plays nicely with clients that have disabled JavaScript. So, this link that I click to pull in the rest of the events, if somebody has JavaScript disabled, or if they command-click or control-click to open in a new tab, it doesn't just do nothing like it would often do in many sort of front-end framework-y places that have hijacked the URL click handler. Instead, it actually opens up the full list of items in a new page, just as if you'd clicked a normal link. So, it really gives you that progressive enhancement feel where I can click a link, and it goes to another page with a list of all the 30 events if I don't have JavaScript. But if I do, maybe I get a slightly better experience where, instead of taking me to a new page, it just expands the list, and I get to see the full list. So, it plays nicely on both sides. STEPHANIE: That's really cool. As someone who's just starting to dabble in some alternative browsers outside of the main popular ones [chuckles], I have noticed how many websites do not work for me anymore [laughs]. And that sounds, like, nice from a user perspective. JOËL: So, other than dabbling with the new browsers, what's new in your world? STEPHANIE: A few weeks ago, I talked about [laughs] sitting more at my desk and, you know, various incentives that I gave myself to do that. And I'd like to say that I've been doing a pretty good job [laughs]. So, what's new in my world is that I've followed up on my commitment to sit at my desk more, feel a little bit more organized in my workday. And that's especially true because the birds have finally discovered my bird feeder [laughs]. JOËL: Oh, that's really cool. STEPHANIE: There were a few weeks where I was not really getting any visitors, and, you know, I was just like, when are they going to come and eat this delicious birdseed that I've [laughs] put out for them? And it seems like a flock of chickadees that normally like to hang out on the apple tree in my backyard have figured out this new source of food, and they'll sometimes, five of them at a time, will come, and sometimes they even fight [laughs] to get on the ledge to hang out at the bird feeder. And yeah, it turns out that the six pounds of bird feed that I bought, I'll start to turn through [laughs] that a little bit quicker now, so I'm excited about that and just to also see other birds and species come and go as time goes on. So, that's been an exciting new development. JOËL: So, the six pounds of birdseed might not last you through the winter. STEPHANIE: I was debating between six pounds and, like, a 20-pound bag [laughs], which that would have been a lot. And so far, I think the six pounds has been serving me well. We'll see how long it lasts, but yeah, it's finally starting. I might have to refill it soon, so, you know, I was hopefully not going to have to store all that bird feed [laughs] just, like, in my house for a long time. JOËL: Any birds that have shown up that have been particularly fun to watch or that are maybe your favorites? STEPHANIE: I mentioned the chickadees because they seem to come as a group, and I really like watching them interact with each other. It's just kind of like bird TV, you know, it's not just a single bird. It's just watching these animals that are a collective do their thing. And I've been enjoying that a lot. JOËL: Now I'm just imagining a reality TV but the Chickadee edition. STEPHANIE: Oh yeah, definitely. I know some people put, like, cameras at their bird feeders to either live stream, which is funny because most of the time, there's nothing happening [laughs]. Usually, the birds are really in and out. Or they'll have, like, a really fancy camera to take, like, really beautiful up-close photos. There's a blog that I discovered recently where someone posts about the birds that visit them at their place in Michigan. I'll link to it in the show notes, but it's really cool to see these, like, up-close and personal photos of basically the bird's mouth. Sometimes, they're open [laughs], so you can see right in them. I don't know; maybe there's a time where I'll get so into it that I'll create my own bird feeder blog. JOËL: Well, if you do, you should definitely share it with the listeners on the podcast. Speaking of listeners on the podcast, we've recently had a listener question from Edward that I thought was a really interesting topic, and I wanted to take a whole episode to dig into. And Edward asks about the concept of a spike. Sometimes, we're asked to investigate a complex new feature, and you might want to do some evaluation on the feasibility and complexity and build out just enough of it to make a well-informed opinion. And ideally, you're doing that in a way that reduces risk of spending too much time with unproven impact. The problem is that in any reasonably complex codebase, that investigation work can be most of the work needed to build the feature. And Edward gives an example: if you're adding a system admin role, the core of the work is adding a new role with all of the abilities, but the real work is ensuring that it interacts with the entire system in the appropriate way. So, how do you manage making sure that you're doing spikes well? And Edward asks if this is something that we've experienced a sort of feeling that we're doing 90% of the work in the spike. He also asks, does this say something about the codebase that you're working on? If it's hard to spike in it, does that say something about the underlying codebase, or are we just all doing spikes wrong? So yeah, I'm curious, Stephanie: do you occasionally spike things out in code on your projects? STEPHANIE: Yeah, I do. I think one piece that was left a little bit unsaid is that I think spiking usually comes up when the team can't really estimate how long a task will take, you know, assuming that you use estimates on your team [chuckles]. That calls for a spike ticket, right? And someone will spend some time. And I think on some teams, this is usually time-boxed as well to maybe do a proof of concept or, yeah, do some of that initial exploration. JOËL: Before we go too deep, I think it's probably useful to define spike in that I think it's a little bit easy and probably varies from team to team and even from a developer to developer. I think, for me, when I think of a spike, it's throwaway work. The code that I write will not get shipped, and this is not code that will just get improved later. It is entirely throwaway work. And the purpose of it is to learn something about the project that's being done. Typically, it's in a sort of de-risking fashion, so to say, look, we've got a feature that's got a lot of unknowns in it. And if we commit to it right now or we start investing time into it, it could become a bit of a time pit. Let's try to answer some questions about it. Let's try to resolve some of those unknowns so that we can better make decisions around maybe estimation, but maybe even just prioritization. If this seems like something that would be really challenging to do, maybe we don't want to prioritize it this quarter. Is that similar to how you think of spikes, or do you have a different sort of definition of it? STEPHANIE: Yeah, I am glad you mentioned that it's throwaway work. I think I was a little hesitant to commit to that definition with conviction because even based off of what Edward was saying, there's kind of, like, maybe different ideas about that or different expectations. But I sometimes think that, depending, spiking doesn't even necessarily need to lead to code. Like, it could just be answering questions. And so, at the same time, I think it is, I like what you said, work that helps you learn more about the system, whether or not there's some code written as, like, a potential path at the end of it. JOËL: Interesting. So, you would put some things that don't involve code at all in the spike bucket. STEPHANIE: I think there have been times where I've done a spike, and I've not coded out anything, but I've answered some questions, and I've left comments about unearthing some of the uncertainty that led us to want to explore the idea in the first place. Then, again, I also have gone down the path of, like, trying out a solution and maybe even multiple and then evaluating afterwards which ones I think were more suitable. So, it could mean both. I think that is actually something that's within the power of whoever is assigned this work to determine whatever is valuable to them in order to get enough information to figure out how you want to move forward. JOËL: Another element of spikes that I think is often implied is that because this is throwaway work, you're not necessarily putting in all the work to make everything sort of clean, or well-structured, or reusable, or anything like that. So, it's quite possible that you would not even test this. You might not break this out into objects in the way that you would if this had to be reused. You might have duplication all over, and that's okay because the purpose of this code is not to be sort of production-grade; it's to answer some questions, and then you're going to throw it away and, using those answers, build something correctly. STEPHANIE: Yeah, I think that's true. And it's kind of an interesting distinction from, you know, what you might consider your regular work in which the expectation is that it will be shipped [chuckles]. And there's also some amount of conflating the two, I think because if, you know, you and I are saying like, yeah, like, this exploration should be standalone, and it is not going to be used to be built on top of necessarily, there is some amount of revisiting. And you're not starting from scratch because you have an idea, but you are starting fresh if you will. And so, you know, when you are doing that spiking, I think it allows you to move a little bit faster, but that doesn't mean that the work is, like, any X percent [laughs] done at the end of it. JOËL: The work is still kind of, I guess, 0% done, again, because this is throwaway code, in our definition of a spike anyway. Would you distinguish between the terms spike and prototype? STEPHANIE: Oh, interesting. My initial reaction is that a prototype would then be user-tested [laughs] in some way. Like, the point is to then show someone and then get them interacting with it, any initial reactions from that. Whereas a spike is really for the developer and maybe the team to discuss. JOËL: I like that distinction. I definitely think that a spike, for me, is purely technical. We're not spiking out a feature by putting a thing live in production behind a feature flag, showing it to 10% of users, and seeing how they respond to that. That's not a spike. So, I think something a little bit more like that, or where you're showing things maybe to users, or you're wanting to do maybe some user testing with something. And it can be throwaway code still. I think now you're starting to get something more that you would call a prototype. So, I like that distinction of, is this sort of internal or external? But in the way they're used, they can often be similar, and that oftentimes both will sort of...they're built to be as cheap as possible to answer the questions you're trying to get answered, whether that's from a user or just technical reasons. And so, the whole thing can be a little bit of smoke and mirrors, a little bit of duct tape and toothpicks, as long as you only have...like, the only solid parts you need are the parts that are going to help you answer your question. And so, any hack or cheat you can get to to bypass everything else is time you've saved, and that's a good thing. STEPHANIE: Oh, I'm very curious about this idea of time saved because I think sometimes an underappreciated outcome of a spike is what not to do or is choosing not to do something. And it can feel not great to have spent hours or even days exploring a path just to realize that it's not worth it. I'm curious, like, when you know to stop and also, how you get other people kind of onboard that even just figuring out an initial idea was not a viable solution, how that could be a valuable insight to the rest of the team. JOËL: Something that I think can be really useful is before you even start spiking out something, write a list of questions that you're trying to answer with this code, and then don't let yourself get distracted. Write the minimum amount of code that will allow you to answer those questions. So, maybe that is a question around, is it possible to connect this external API to our systems? There are some questions around, like, how credentials and things will work or how complex that will be. It might be a question around, like, maybe there's even, like, a performance thing. We want to talk to an external system and, you know, the responses back need to be within a certain amount of time. Otherwise, this whole approach where we're going to try to fetch data live is not feasible. So, the answer we need there is, can we do it live, or do we need to consider some sort of background fetching, or caching approach, or something like that? So, write the minimum amount of code that it would take to do that. And maybe the minimum amount of code, like you said, is not even really code. Maybe it's a script or even just trying out some curl commands and timing them at the command line. It could be a lot of things. But I think having a list of questions up front really helps you focus on the purpose of the spike. And I think it helps me a little bit as well with emotional attachment in that success is not necessarily coming to a yes on all of those questions. It is having an answer, going from question mark to some answer. So, if I can answer that question, if I can find even a clever way to answer that question faster, that is success. I have done a good job with my spike. STEPHANIE: I like that a lot. I think some people might struggle with spikes because they're so ambiguous. And if it's just, like, explore this potential feature, or, like, maybe not even that, but even saying, like, we want to build this admin role, to use Edward's example. And to constrain it to how should we do that, it already kind of guides the spike in a certain direction that may or may not be exactly what you're looking for. And so, there's some value in figuring out what questions to ask with the product team, even to get alignment on what the purpose of this task is. And, you know, this is true of regular feature work, too. When those decisions have kind of already been made about what we're working on without a lot of input from developers who will be working on it, it can be really hard to, like, go back and be like, "Oh, actually, that's not really possible." But if the questions are like, "Is this possible?" or like, what it costs to do this, I think it prevents some of that friction and misalignment that might be had when the outcome of a spike turns out to be maybe not what someone wants to hear. JOËL: And I think the questions you ask don't necessarily have to be yes or no questions. They could be some sort of list, right? It could be, look, we're looking at two different implementations or two general approaches, families of solutions for our super admin role. What are the trade-offs of each? And so, a spike might be exploring. Can we come up with a list of pros and cons for each approach? And maybe some of them we just know from experience at developing, but maybe some of them might involve actually doing a little bit of work to play out the pros and cons. Maybe that's in our app. Maybe that's even spinning up a little app on the side, right? If we're comparing maybe two gems or something like that to see how we feel about throwing a few different scenarios and exploring edge cases. So, the questions don't need to be straight-up yes or no. So, you mentioned earlier the idea that sometimes one developer might do the spike, and then another one might do the actual work, maybe inspired by the answers that were on that spike. And I think that can lead to some really interesting dynamics, especially if the developer who did the first spike has done kind of, like, what Edward describes, what feels like 90% of the feature. It may be not so great code quality. And then this is a branch on GitHub, and they're like, "Okay, do the rest. Make it good. I've already explored the possibilities here," and then you're the developer who has to pick that up. Have you ever experienced that? And if so, how do you feel picking up a ticket like that? STEPHANIE: Yeah, I have experienced it, and I think there is always something lost when that happens when you are not the person who did the research. And then having to just go from whatever was left in the notes or from the code and, you know, I don't know how feasible it is for whoever spiked to always be doing the implementing, but I certainly end up having a lot of questions, I think. Like, you can't document or even code out, like, every single thing you learned in that process, right? There's always from big to small decisions or alternatives considered that won't make it into however that communication or expression or knowledge transfer happens. And I think the two choices that I have as a developer picking that up is either to just trust [laughs] that the work the other person did is taking me down a good path or to spend more time rebuilding some of that context and making some of my own evaluations along the way and deciding for myself whether I'm like, oh yeah, this is a good idea, or maybe, like, I might change something here. So, I think that there is some time lost, too. And I think that's a really good thing to point out when someone might think like, oh, this is mostly done. That's kind of my first reaction in terms of the context loss in an exchange like that. JOËL: Do you feel like this is a situation where you would want to have the same developer do both the spike and the final implementation? Or is this maybe a situation where spikes aren't being done correctly, and maybe a branch with some code that's kind of half-written is maybe the wrong artifact to hand off from one developer to the other? STEPHANIE: Oh, that's really interesting about if that's the wrong artifact to hand off because it could be misleading. Maybe it's not always, and maybe there's some really great code that comes out of it if someone builds on top of a work-in-progress branch or a spike branch. Honestly, I think, and I haven't even really gotten to experience this all too much because maybe there is some perception that it's backtracking or, you know, it's more work or more time, but it would be really cool for whoever had spiked it to then bring someone along to pair on it and start fresh, like we mentioned, where they're kind of coming to each decision to be made with an idea, but it's not necessarily set in stone, right? There could be that discussion. It could be, like, a generative experience to either refine that code that had initially been spiked out or discover new things along the way. It's not like the outcome has already been decided because of the spike. It is information, and that's that. JOËL: And we on this podcast are very pro-discovering new things along the way. I think sometimes as a developer, if I get sort of a, you know, maybe a 90% branch done that's get passed on to me from somebody else who did a spike, it feels a little bit like the finish the rest of the owl meme, except that now I'm not even, like, just trying to follow a tutorial. Just somebody did the first couple of circles and then is like, "Oh yeah, you finish the rest of the owl. I did the hard work. You just need to polish it up." On the one hand, it's like, dude, if you're, like, doing 90%, you may as well finish it. I don't want to just be polishing somebody else's work. And, you know, oftentimes, it might feel like it's done 90% of the time, but it's actually, like, there's a lot of edge cases and nuance that have not been handled. And, you know, a spike is meant to be throwaway work to start with. So, I felt like those sorts of handoffs often, I don't know, they don't sit with me well. STEPHANIE: Yeah. You could also come in and be like, this doesn't even look like an owl at all [laughs]. JOËL: I feel like maybe in my ideal world, a branch with partly written code is, I guess, an intermediate artifact that might be useful to show. But what I really want from a spike is answers to questions that will allow me, when I build the thing from scratch to make intelligent decisions. So, probably what I want out of a spike is something that's closer to documentation, a list of questions that we were asking, and then the answers we came to by doing the spike work. And that might be maybe a list of trade-offs, or maybe we didn't really know the correct endpoints from this undocumented API, and we tried some stuff, and we, like, figured out what endpoints we needed, or what the shape of the JSON payload needed to be, things like that. Maybe we tried a couple of different implementations, or we did some exploration around, like, what gem we'd like to use, and we have a recommendation for a gem. Those are all, I think, very concrete outcomes from a spike that I can then use when I'm building it from scratch. And I'm not just, like, branching off your branch or having it open in another browser and copy-pasting snippets while trying to, like, add some testing and maybe modularizing it a little bit. I think that leads to probably a better outcome for the person who's doing the spike because they have a tighter scope and also a better outcome for me, who's then trying to build that feature correctly from the ground up. I think that would be my sort of ideal workflow. STEPHANIE: While you were saying that, I thought about how a lot of those points sounded like requirements for a feature. And that, I think, is also a good outcome when a spike then leads to more concrete requirements because those are all decisions that were thought through, right? And even better is if that also documents things that were tried and the trade-offs that came with them or, like, the reasons why they were less viable or not ideal for that added context because that is also work that happened [laughs] and should be captured so someone can know that that might not be time they need to spend on that. I am really interested in one piece that we haven't quite touched on is the complexity of the app and what it means for spiking to be a challenge because of the complexity of the app. JOËL: Yeah. And I think sort of inherent in there is that maybe the idea that if you have a really complex app, it sort of forces you to go to the 90% of the work done in order to successfully answer the questions you wanted to answer with your spike in a way that maybe a better-structured app would not. Do you think that's true? STEPHANIE: Well, I actually think that if the app is complex, you're actually seeing that affect all parts of feature development, not just spiking, where everything takes longer [laughs] because you maybe feel less confident. You're nervous about breaking something. Edward called the real work ensuring that it interacts with the entire system correctly, and that's true of, I think, just software development in general. And so, I wonder if, you know, spiking happens to be one way that it manifests, but if there are signals that it's affecting, you know, all parts of your workflow. JOËL: There definitely is a cost, right? Complex software imposes costs everywhere. In some way, I think maybe spiking is attempting to get around some of those, in that there are some decisions that we can just say, you know what? We'll build the feature, and we'll just kind of figure it out as we go along, and we'll, like, build the thing. Spiking attempts to say, look, let's not build the whole thing. Let's fake out a bunch of parts because, really, we have a big question that we want to answer about a thing that is three steps down, you know. And maybe the question is, look, we're trying to build the super admin role, and we know it's got all these, like, edge cases we need to deal with. Maybe we need a list of the edge cases, and maybe that's how we, like, try to drive them out. But maybe this is a, hey, do we want to go with more of a, like, a role hierarchy inheritance-based approach, or do we want to go with some sort of escalating defaults? Or whatever the couple of different strategies you might want to do. And the spike might be trying to answer the question, how can we, as cheaply as possible while doing the minimum amount of work, sort of explore which of these implementations works best? And in a complex system, is it possible to get to the answer to those questions without building out 90% of the feature itself? I think, going to what you said, you might have to do more work if it's a complex system. But I would also encourage everyone to go absolute minimalist, like, keep your goal in mind: what is the question you're trying to answer? And then ruthlessly cut everything you need to get to your point where you can answer that question. Do you need to hard code? Do you need to metaprogram? Do you need to do just, like, the worst, dirtiest code that you've ever written? That's okay because, like, the implementation does not matter. The fact that you're not exercising the full system does not matter, as long as the part that you're trying to exercise and answer your questions does get used. STEPHANIE: Yeah, I like that a lot. And I wonder if the impulse to want to spike something is coming out of nervousness about how complicated the ask is. And it's like, well, I don't want to tell you that it's going to take a long time because this app is extremely complex, and everything takes a long time. You know, it's like not wanting to face that hard question of either we need to just set our expectations that things take longer, or we need to make some kind of change to make that easier to work with. And that is a lot of thought and effort. And so, it's kind of an answer to be like, well, like, let me spike this out and then see [laughs]. And so it may be a way to appease someone making a request for a feature. I don't know; I'm perhaps projecting a little bit here [chuckles]. But it could also be an important question to ask yourself if you find your team, like, needing to lean on spikes a lot because you just don't know. JOËL: That's really interesting because I think that maybe connects to a recent episode we did on breaking features down into smaller chunks. Spikes can often manifest, or the need for a spike can often manifest when you've got a larger, less well-defined feature that you want to do. So, sometimes, breaking things into smaller pieces will help you have something that's a little bit more well-defined that you feel confident jumping into without doing a spike. Or maybe the act of trying to split this sort of large, undefined task into smaller pieces will reveal questions that need to be answered and say, look, I don't know where the seam should be, where to split this task because I don't know the answer to this one question. If I could know the answer to this one question, I would know where to split this feature. That's your spike right there. Do the minimum amount of code to answer that one question, and then you can split your feature and confidently work on the two smaller pieces. And I think that's a win for everyone. STEPHANIE: Yeah. And you can listen back to our vertical slice episode [laughs] for some inspiration on that. JOËL: On that note, shall we wrap up? STEPHANIE: Let's wrap up. Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeeee!!!!!!! AD: Did you know thoughtbot has a referral program? If you introduce us to someone looking for a design or development partner, we will compensate you if they decide to work with us. More info on our website at: tbot.io/referral. Or you can email us at referrals@thoughtbot.com with any questions.

The Bike Shed
413: Developer Tales of Package Management

The Bike Shed

Play Episode Listen Later Jan 23, 2024 33:33


Stephanie shares her task of retiring a small, internally-used link-shortening app. She describes the process as both celebratory and a bit mournful. Meanwhile, Joël discusses his deep dive into ActiveRecord, particularly in the context of debugging. He explores the complexities of ActiveRecord querying schemas and the additional latency this introduces. Together, the hosts discuss the nuances of package management systems and their implications for developers. They touch upon the differences between system packages and language packages, sharing personal experiences with tools like Homebrew, RubyGems, and Docker. Transcript: JOËL: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Joël Quenneville. STEPHANIE: And I'm Stephanie Minn. And together, we're here to share a bit of what we've learned along the way. JOËL: So, Stephanie, what's new in your world? STEPHANIE: So, this week, I got to have some fun working on some internal thoughtbot work. And what I focused on was retiring one of our just, like, small internal self-hosted on Heroku apps in favor of going with a third-party service for this functionality. We basically had a tiny, little app that we used as a link-shortening service. So, if you've ever seen a tbot.io short link out in the world, we were using our just, like, an in-house app to do that, you know, but for various reasons, we wanted to...just it wasn't worth maintaining anymore. So, we wanted to just use a purchased service. But today, I got to just, like, do the little bit of, like, tidying up, you know, in preparation to archive a repo and kind of delete the app from Heroku, and I hadn't done that before. So, it felt a little bit celebratory and a little bit mournful even [laughs] to, you know, retire something like that. And I was pairing with another thoughtbot developer, and we used a pairing app called Tuple. And you can just send, like, fun reactions to each other. Like, you could send, like, a fire emoji [laughs] or something if that's what you're feeling. And so, I sent some, like, confetti when we clicked the, "I understand what deleting this app means on GitHub." But I joked that "Actually, I feel like what I really needed was a, like, a salute kind of like thank you for your service [laughs] type of reaction." JOËL: I love those moments when you're kind of you're hitting those kind of milestone-y moments, and then you get to send a reaction. I should do that more often in Tuple. Those are fun. STEPHANIE: They are fun. There's also a, like, table flip reaction, too, is one that I really enjoy [laughs], you know, you just have to manifest that energy somehow. And then, after we kind of sent out an email to the company saying like, "Oh yeah, we're not using our app anymore for link shortening," someone had a great suggestion to make our archived repo public instead of private. I kind of liked it as a way of, like, memorializing this application and let community members see, you know, real code in a real...the application that we used here at thoughtbot. So, hopefully, if not me, then someone else will be able to do that and maybe publish a little blog post about that. JOËL: That's exciting. So, it's not currently public, the repo, but it might be at some point in the future. STEPHANIE: Yeah, that's right. JOËL: We'll definitely have to mention it on a future episode if that happens so that people following along with the story can go check out the code. STEPHANIE: So, Joël, what's new in your world? JOËL: I've been doing a deep dive into how ActiveRecord works. Particularly, I am debugging some pretty significant slowdowns in querying ActiveRecord models that are backed not by a regular Postgres database but instead a Snowflake data warehouse via an ODBC connection. So, there's a bunch of moving pieces going on here, and it would just take forever to make any queries. And sure, the actual reported query time is longer than for a local Postgres database, but then there's this sort of mystery extra waiting time, and I couldn't figure out why is it taking so much longer than the actual sort of recorded query time. And I started digging into all of this, and it turns out that in addition to executing queries to pull actual data in, ActiveRecord needs to, at various points, query the schema of your data store to pull things like names of tables and what are the indexes and primary keys and things like that. STEPHANIE: Wow. That sounds really cool and something that I have never needed to do before. I'm curious if you noticed...you said that it takes, I guess, longer to query Snowflake than it would a more common Postgres database. Were you noticing this performance slowness locally or on production? JOËL: Both places. So, the nice thing is I can reproduce it locally, and locally, I mean running the Rails app locally. I'm still talking to a remote Snowflake data warehouse, which is fine. I can reproduce that slowness locally, which has made it much easier to experiment and try things. And so, from there, it's really just been a bit of a detective case trying to, I guess, narrow the possibility space and try to understand what are the parts that trigger slowness. So, I'm printing timestamps in different places. I've got different things that get measured. I've not done, like, a profiling tool to generate a flame graph or anything like that. That might have been something cool to try. I just did old-school print statements in a couple of places where I, like, time before, time after, print the delta, and that's gotten me pretty far. STEPHANIE: That's pretty cool. What do you think will be an outcome of this? Because I remember you saying you're digging a little bit into ActiveRecord internals. So, based on, like, what you're exploring, what do you think you could do as a developer to increase some of the performance there? JOËL: I think probably what this ends up being is finding that the Snowflake adapter that I'm using for ActiveRecord maybe has some sort of small bug in it or some implementation that's a little bit too naive that needs to be fine-tuned. And so, probably what ends up happening here is that this finishes as, like, an open-source pull request to the Snowflake Adapter gem. STEPHANIE: Yeah, that's where I thought maybe that might go. And that's pretty cool, too, and to, you know, just be investigating something on your app and being able to make a contribution that it benefits the community. JOËL: And that's what's so great about open source because not only am I able to get the source to go source diving through all of this, because I absolutely need to do that, but also, then if I make a fix, I can push that fix back out to the community, and everybody gets to benefit. STEPHANIE: Cool. Well, that's another thing that I look forward to hearing more on the development of [laughs] later if it pans out that way. JOËL: One thing that has been interesting with this Snowflake work is that there are a lot of moving parts and multiple different packages that I need to install to get this all to work. So, I mentioned that I might be doing a pull request against the Snowflake Adapter for ActiveRecord, but all of this talks through a sort of lower-level technology protocol called ODBC, which is a sort of generic protocol for speaking to data stores, and that actually has two different pieces. I had to install two different packages. There is a sort of low-level executable that I had to install on my local dev machine and that I have to install on our servers. And on my Mac, I'm installing that via Homebrew, which is a system package. And then to get Ruby bindings for that, there is a Ruby gem that I install that allows Ruby code to talk to ODBC, and that's installed via RubyGems or Bundler. And that got me thinking about sort of these two separate ecosystems that I tend to work with every day. We've got sort of the system packages and the, I don't know what you want to call them, language packages maybe, things like RubyGems, but that could also be NPM or whatever your language of choice is, and realizing that we kind of have things split into two different zones, and sometimes we need both and wondering a little bit about why is that difference necessary. STEPHANIE: Yeah, I don't have an answer to that [laughs] question right now, but I can say that that was an area that really tripped me up, I think, when I was first a fledgling developer. And I was really confused about where all of these dependencies were coming from and going through, you know, setting up my first project and being, like, asked to install Postgres on my machine but then also Bundler, which then also installs more dependencies [laughs]. The lines between those ecosystems were not super clear to me. And, you know, even now, like, I find myself really just kind of, like, learning what I need to know to get by [laughs] with my day-to-day work. But I do like what you said about these are kind of the two main layers that you're working with in terms of package management. And it's really helpful to have that knowledge so you can troubleshoot when there is an issue at one or the other. JOËL: And you mentioned Postgres. That's another one that's interesting because there are components in both of those ecosystems. Postgres itself is typically installed via a system package manager, so something like Homebrew on a Mac or apt-get on a Linux machine. But then, if you're interacting with Postgres in a Ruby app, you're probably also installing the pg gem, which are Ruby's bindings for Postgres to allow Ruby to talk to Postgres, and that lives in the package ecosystem on RubyGems. STEPHANIE: Yeah, I've certainly been in the position of, you know, again, as consultants, we oftentimes are also setting up new laptops entirely [laughs] like client laptops and such and bundling and the pg gem is installed. And then at least I have, you know, I have to give thanks to the very clear error message that [laughs] tells me that I don't have Postgres installed on my machine. Because when I mentioned, you know, troubleshooting earlier, I've certainly been in positions where it was really unclear what was going on in terms of the interaction between what I guess we're calling the Ruby package ecosystem and our system level one. JOËL: Especially for things like the pg gem, which need to compile against some existing libraries, those always get interesting where sometimes they'll fail to compile because there's a path to some C compiler that's not set correctly or something like that. For me, typically, that means I need to update the macOS command line tools or the Xcode command line tools; I forget what the name of that package is. And, usually, that does the trick. That might happen if I've upgraded my OS version recently and haven't downloaded the latest version of the command line tools. STEPHANIE: Yeah. Speaking of OS versions, I have a bit of a story to share about using...I've never said this name out loud, but I am pretty sure that it would just be pronounced as wkhtmltopdf [laughs]. For some reason, whenever I see words like that in my brain, I want to, like, make it into a pronounceable thing [laughs]. JOËL: Right, just insert some vowels in there. STEPHANIE: Yeah, wkhtmltopdf [laughs]. Anyway, that was being used in an app to generate PDF invoices or something. It's a pretty old tool. It's a CLI tool, and it's, as far as I can tell, it's been around for a long time but was recently no longer maintained. And so, as I was working on this app, I was running into a bug where that library was causing some issues with the PDF that was generated. So, I had to go down this route of actually finding a Ruby gem that would figure out which package binary to use, you know, based off of my system. And that worked great locally, and I was like, okay, cool, I fixed the issue. And then, once I pushed my change, it turns out that it did not work on CI because CI was running on Ubuntu. And I guess the binary didn't work with the latest version of Ubuntu that was running on CI, so there was just so many incompatibilities there. And I was wanting to fix this bug. But the next step I took was looking into community-provided packages because there just simply weren't any, like, up-to-date binaries that would likely work with these new operating systems. And I kind of stopped at that point because I just wasn't really sure, like, how trustworthy were these community packages. That was an ecosystem I didn't know enough about. In particular, I was having to install some using apt from, you know, just, like, some Linux community. But yeah, I think I normally have a little bit more experience and confidence in terms of the Ruby package ecosystem and can tell, like, what gems are popular, which ones are trustworthy. There are different heuristics I have for evaluating what dependency to pull in. But here I ended up just kind of bailing out of that endeavor because I just didn't have enough time to go down that rabbit hole. JOËL: It is interesting that learning how to evaluate packages is a skill you have to learn that varies from package community to package community. I know that when I used to be very involved with Elm, we would often have people who would come to the Elm community from the JavaScript community who were used to evaluating NPM packages. And one of the metrics that was very popular in the JavaScript community is just stars on GitHub. That's a really important metric. And that wasn't really much of a thing in the Elm community. And so, people would come and be like, "Wait, how do I know which package is good? I don't see any stars on GitHub." And then, it turns out that there are other metrics that people would use. And similarly, you know, in Ruby, there are different ways that you might use to evaluate Ruby gems that may or may not involve stars on GitHub. It might be something entirely different. STEPHANIE: Yeah. Speaking of that, I wanted to plug a website that I have used before called the Ruby Toolbox, and that gives some suggestions for open-source Ruby libraries of various categories. So, if you're looking for, like, a JSON parser, it has some of the more popular ones. If you're looking for, you know, it stores them by category, and I think it is also based on things like stars and forks like that, so that's a good one to know. JOËL: You could probably also look at something like download numbers to see what's popular, although sometimes it's sort of, like, an emergent gem that's more popular. Some of that almost you just need to be a little bit in the community, like, hearing, you know, maybe listening to podcasts like this one, subscribing to Ruby newsletters, going to conferences, things like that, and to realize, okay, maybe, you know, we had sort of an old staple for JSON parsing, but there's a new thing that's twice as fast. And this is sort of becoming the new standard, and the community is shifting towards that. You might not know that just by looking at raw stats. So, there's a human component to it as well. STEPHANIE: Yeah, absolutely. I think an extension of knowing how to evaluate different package systems is this question of like, how much does an average developer need to know about package management? [laughs] JOËL: Yeah, a little bit to a medium amount, and then if you're writing your own packages, you probably need to know a little bit more. But there are some things that are really maybe best left to the maintainers of package managers. Package managers are actually pretty complex pieces of software in terms of all of the dependency management and making sure that when you say, "Oh, I've got Rails, and this other gem, and this other gem, and it's going to find the exact versions of all those gems that play nicely together," that's non-trivial. As a sort of working developer, you don't need to know all of the algorithms or the graph theory or any of that that underlies a package manager to be able to be productive in your career. And even as a package developer, you probably don't need to really know a whole lot of that. STEPHANIE: Yeah, that makes sense. I actually had referred to our internal at thoughtbot here, our kind of, like, expectations for skill levels for developers. And I would say for an average developer, we kind of just expect a basic understanding of these more complex parts of our toolchain, I think, specifically, like, command line tools and package management. And I think I'd mentioned earlier that, for me, it is a very need-to-know basis. And so, yeah, when I was going down that little bit of exploration around why wkhtmltopdf [chuckles] wasn't working [chuckles], it was a bit of a twisty and turning journey where I, you know, wasn't really sure where to go. I was getting very obtuse error messages, and, you know, I had to dive deep into all these forums [laughs] for all the various platforms [laughs] about why libraries weren't working. And I think what I did come away with was that like, oh, like, even though I'm mostly working on my local machine for development, there was some amount of knowledge I needed to have about the systems that my CI and, you know, production servers are running on. The project I was working on happened to have, like, a Docker file for those environments, and, you know, kind of knowing how to configure them to install the packages I needed to install and just knowing a little bit about the different ways of doing that on systems outside of my usual daily workflows. JOËL: And I think that gets back to some of the interesting distinctions between what we might call language packages versus system packages is that language packages more or less work the same across all operating systems. They might have a build step that's slightly different or something like that, but system packages might be pretty different between different operating systems. So, development, for me, is a Mac, and I'm probably installing system packages via something like Homebrew. If I then want that Rails app to run on CI or some Linux server somewhere, I can't use Homebrew to install things there. It's going to be a slightly different package ecosystem. And so, now I need to find something that will install Postgres for Linux, something that will install, I guess, wkhtmltopdf [laughs] for Linux. And so, when I'm building that Docker file, that might be a little bit different for Mac versus for...or I guess when you run a Docker file, you're running a containerized system. So, the goal there is to make this system the same everywhere for everyone. But when you're setting that up, typically, it's more of a Linux-like system. And so running inside the Docker container versus outside on the native Mac might involve a totally different set of packages and a different package tool. As opposed to something like Bundler, you've got your gem file; you bundle install. It doesn't matter if you're on Linux or macOS. STEPHANIE: Yes, I think you're right. I think we kind of answered our own question at the top of the show [laughs] about differences and what do you need to know about them. And I also like how you pointed out, oh yeah, like, Docker is supposed to [laughs], you know, make sure that we're all developing in the same system, essentially. But, you know, sometimes you have different use cases for it. And, yeah, when you were talking about installing an application on your native Mac and using Homebrew, but even, you know, not everyone even uses Homebrew, right? You can install manually [laughs] through whatever official installer that application might provide. So, there's just so many different ways of doing something. And I had the thought that it's too bad that we both [chuckles] develop on Mac because it could be really interesting to get a Linux user's perspective in here. JOËL: You mentioned not installing via Homebrew. A kind of glaring example of that in my personal setup is that I use Postgres.app to manage Postgres on my machine rather than using Homebrew. I've just...over the years, the Homebrew version every time I upgrade my operating system or something, it's just such a pain to update, and I've lost too many hours to it, and Postgres.app just works, and so I've switched to that. Most other things, I'll use the Homebrew version, but Postgres it's now Postgres.app. It's not even a command line install, and it works fine for me. STEPHANIE: Nice. Yeah. That's interesting. That's a good tip. I'll have to look into that next time because I have also certainly had to just install so many [laughs] various versions of Postgres and figure out what's going on with them every time I upgrade my OS. I'm with you, though, in terms of the packages world I'm looking for, it works [laughs]. JOËL: So, you'd mentioned earlier that packages is sort of an area that's a bit of a need-to-know basis for you. Are there, like, particular moments in your career that you remember like, oh, that's the moment where I needed to, like, take some time and learn a little bit of the next level of packages? STEPHANIE: That's a great question. I think the very beginnings of understanding how package versions work when you have multiple projects on your machine; I just remember that being really confusing for me. When I started out, like, you know, as soon as I cloned my second repo [laughs], and was very confused about, like, I'm sure I went through the process of not installing gems using Bundler, and then just having so much chaos [laughs] wrecked in my development environment and, you know, having to ask someone, "I don't understand how this works. Like, why is it saying I have multiple versions of this library or whatever?" JOËL: Have you ever sudo gem installed a gem? STEPHANIE: Oh yeah, I definitely have. I can't [laughs], like, even give a good reason for why I have done it, but I probably was just, like, pulling my hair out, and that's what Stack Overflow told me to do. I don't know if I can recommend that, but it is [chuckles] one thing to do when you just are kind of totally stuck. JOËL: There was a time where I think that that was in the READMEs for most projects. STEPHANIE: Yeah, that's a really good point. JOËL: So, that's probably why a lot of people end up doing that, but then it tends to install it for your system Ruby rather than for...because if you're using something like Rbenv or RVM or ASDF to manage multiple Ruby versions, those end up being what's using or even Homebrew to manage your Ruby. It wouldn't be installing it for those versions of Ruby. It would be installing it for the one that shipped with your Mac. I actually...you know what? I don't even know if Mac still ships with Ruby. It used to. It used to ship with a really old version of Ruby, and so the advice was like, "Hey, every repo tells you to install it with sudo; don't do that. It will mess you up." STEPHANIE: Huh. I think Mac still does ship with Ruby, but don't quote me on that [laughter]. And I think that's really funny that, like, yeah, people were just writing those instructions in READMEs. And I'm glad that we've collectively [laughs] figured out that difference and want to, hopefully, not let other developers fall into that trap [laughs]. Do you have a particular memory or experience when you had to kind of level up your knowledge about the package ecosystem? JOËL: I think one sort of moment where I really had to level up is when I started really needing to understand how install paths worked, especially when you have, let's say, multiple versions of a gem installed because you have different projects. And you want to know, like, how does it know which one it's using? And then you see, oh, there are different paths that point to different directories with the installs. Or when you might have an executable you've installed via Homebrew, and it's like, oh yeah, so I've got this, like, command that I run on my shell, but actually that points to a very particular path, you know, in my Homebrew directory. But maybe it could also point to some, like, pre-installed system binaries or some other custom things I've done. So, there was a time where I had to really learn about how the path shell variable worked on a machine in order to really understand how the packages I installed were sometimes showing up when I invoked a binary and sometimes not. STEPHANIE: Yeah, that is another really great example that I have memories of [laughs] being really frustrated by, especially if...because, you know, we had talked earlier about all the different ways that you can install applications on your system, and you don't always know where they end up [laughs]. JOËL: And this particular memory is tied to debugging Postgres because, you know, you're installing Postgres, and some paths aren't working. Or maybe you try to update Postgres and now it's like, oh, but, like, I'm still loading the wrong one. And why does PSQL not do the thing that I think it does? And so, that forced me to learn a little bit about, like, under the hood, what happens when I type brew install PostgreSQL? And how does that mesh with the way my shell interprets commands and things like that? So, it was maybe a little bit of a painful experience but eye-opening and definitely then led to me, I think, being able to debug my setup much more effectively in the future. STEPHANIE: Yeah. I like that you also pointed out how it was interacting with your shell because that's, like, another can of worms, right? [laughs] In terms of just the complexity of how these things are talking to each other. JOËL: And for those of our listeners who are not familiar with this, there is a shell command that you can use called which, W-H-I-C-H. And you can prefix that in front of another command, and it will tell you the path that it's using for that binary. So, in my case, if I'm looking like, why is this PSQL behaving weirdly or seems to be using the old version, I can type 'which space psql', and it'll say, "Oh, it's going to this path." And I can look at it and be like, oh, it's using my system install of Postgres. It's not using the Homebrew one. Or, oh, maybe it's using the Homebrew install, not my Postgres.app version. I need to, like, tinker with the paths a little bit. So, that has definitely helped me debug my package system more than once. STEPHANIE: Yeah, that's a really good tip. I can recall just totally uninstalling everything [laughs] and reinstalling and fingers crossed it would figure out a route to the right thing [laughs]. JOËL: You know what? That works. It's not the, like, most precise solution but resetting your environment when all else fails it's not a bad solution. So, we've been talking a lot about what it's like to interact with a package ecosystem as developers, as users of packages, but what if you're a package developer? Sometimes, there's a very clear-cut place where to publish, and sometimes it's a little bit grayer. So, I could see, you know, I'm developing a database, and I want that to be on operating systems, probably should be a system-level package rather than a Ruby gem. But what if I'm building some kind of command line tool, and I write it in Ruby because I like writing Ruby? Should I publish that as a gem, or should I publish that as some kind of system package that's installed via Homebrew? Any opinions or heuristics that you would use to choose where to publish on one side or the other? STEPHANIE: As not a package developer [laughs], I can only answer from that point of view. That is interesting because if you publish on a, you know, like, a system repository, then yeah, like, you might get a lot more people using your tool out there because you're not just targeting a specific language's community. But I don't know if I have always enjoyed downloading various things to my system's OS. I think that actually, like, is a bit complicated for me or, like, I try to avoid it if I can because if something can be categorized or, like, containerized in a way that, like, feels right for my mental model, you know, if it's written in Ruby or something really related to things I use Ruby in, it could be nice to have that installed in my, like, systems RubyGems. But I would be really interested to hear if other people have opinions about where they might want to publish a package and what kind of developers they're hoping to find to use their tool. JOËL: I like the heuristic that you mentioned here, the idea of who the audience is because, yeah, as a Ruby developer who already has a Ruby setup, it might be easier for me to install something via a gem. But if I'm not a Ruby developer who wants to use the packages maybe a little bit more generic, you know, let's say, I don't know, it's some sort of command line tool for interacting with GitHub or something like that. And, like, it happens to be written in Ruby, but you don't particularly care about that as a user of this. Maybe you don't have Ruby installed and now you've got to, like, juggle, like, oh, what is RubyGems, and Bundler, and all this stuff? And I've definitely felt that occasionally downloading packages sort of like, oh, this is a Python package. And you're going to need to, like, set up all this stuff. And it's maybe designed for a Python audience. And so, it's like, oh, you're going to set up a virtual environment and all these things. I'm like, I just want your command line tools. I don't want to install a whole language. And so, sometimes there can be some frustration there. STEPHANIE: Yeah, that is very true. Before you even said that, I was like, oh, I've definitely wanted to download a command line tool and be like, first install [laughs] Python. And I'm like, nope, I'm bailing out of this. JOËL: On the other hand, as a developer, it can be a lot harder to write something that's a bit more cross-platform and managing all that. And I've had to deal a little bit with this for thoughtbot's Parity tool, which is a command-line tool for working with Heroku. It allows you to basically run commands on either staging or production by giving you a staging command and a production command for common Heroku CLI tasks, which makes it really nice if you're working and you're having to do some local, some development, some staging, and some production things all from your command line. It initially started as a gem, and we thought, you know what? This is mostly command line, and it's not just Rubyists who use Heroku. Let's try to put this on Homebrew. But then it depends on Ruby because it's written in Ruby. And now we had to make sure that we marked Ruby as a dependency in Homebrew, which meant that Homebrew would then also pull in Ruby as a dependency. And that got a little bit messy. For a while, we even experimented with sort of briefly available technology called Traveling Ruby that allowed you to embed Ruby in your binary, and you could compile against that. That had some drawbacks. So, we ended up rolling that back as well. And eventually, just for maintenance ease, we went back to making this a Ruby gem and saying, "Look, you install it via RubyGems." It does mean that we're targeting more of the Ruby community. It's going to be a little bit harder for other people to install, but it is easier for us to maintain. STEPHANIE: That's really interesting. I didn't know that history about Parity. It's a tool that I have used recently and really enjoyed. But yeah, I think I remember someone having some issues between installing it as a gem and installing it via Homebrew and some conflicts there as well. So, I can also see how trying to decide or maybe going down one path and then realizing, oh, like, maybe we want to try something else is certainly not trivial. JOËL: I think, in me, I have a little bit of the idealist and the pragmatist that fight. The idealist says, "Hey, if it's not, like, aimed for Ruby developers as a, like, you can pull this into your codebase, if it's just command line tools and the fact that it's written in Ruby is an implementation detail, that should be a system package. Do not distribute binaries via RubyGems." That's the idealist in me. The pragmatist says, "Oh, that's a lot of work and not always worth it for both the maintainers and sometimes for the users, and so it's totally okay to ship binaries as RubyGems." STEPHANIE: I was totally thinking that I'm sure that you've been in that position of being a user and trying to download a system package and then seeing it start to download, like, another language. And you're like, wait, what? [laughter] That's not what I want. JOËL: So, you and I have shared some of our heuristics in the way we approach this problem. Now, I'm curious to hear from the audience. What are some heuristics that you use to decide whether your package is better shipped on RubyGems versus, let's say, Homebrew? Or maybe as a user, what do you prefer to consume? STEPHANIE: Yes. And speaking of getting listener feedback, we're also looking for some listener questions. We're hoping to do a bit of a grab-bag episode where we answer your questions. So, if you have anything that you're wanting to hear me and Joël's thoughts on, write us at hosts@bikeshed.fm. JOËL: On that note, shall we wrap up? STEPHANIE: Let's wrap up. Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeee!!!!!!! AD: Did you know thoughtbot has a referral program? If you introduce us to someone looking for a design or development partner, we will compensate you if they decide to work with us. More info on our website at: tbot.io/referral. Or you can email us at referrals@thoughtbot.com with any questions.

The Bike Shed
412: Vertical Slices

The Bike Shed

Play Episode Listen Later Jan 16, 2024 32:23


Joël shares a unique, time-specific bug he encountered, which causes a page to crash only in January. This bug has been fixed in previous years, only to reemerge due to subsequent changes. Stephanie talks about her efforts to bring more structure to her work-from-home environment. She describes how setting up a bird feeder near her desk and keeping chocolates at her desk serve as incentives to work more from her desk. Together, Stephanie and Joël take a deep dive into the challenges of breaking down software development tasks into smaller, more manageable chunks. They explore the concept of 'vertical slice' development, where features are implemented in thin, fully functional segments, contrasting it with the more traditional 'horizontal slice' approach. This discussion leads to insights on collaborative work, the importance of iterative development, and strategies for efficient and effective software engineering. thoughtbot Live Streams (https://www.youtube.com/@thoughtbot/streams?themeRefresh=1) Stephanie's Live Stream (https://www.youtube.com/watch?v=jWmCOMbOxTs) Joël's Talk on Time (https://www.youtube.com/watch?v=54Hs2E7zsQg) Finish the Owl Meme (https://knowyourmeme.com/photos/572078-how-to-draw-an-owl) Full Stack Slices (https://thoughtbot.com/blog/break-apart-your-features-into-full-stack-slices) Elephant Carpaccio (https://blog.crisp.se/2013/07/25/henrikkniberg/elephant-carpaccio-facilitation-guide) Outside-in Feature Development (https://thoughtbot.com/blog/testing-from-the-outsidein) Working Iteratively (https://thoughtbot.com/blog/working-iteratively) Transcript:  STEPHANIE: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Stephanie Minn. JOËL: And I'm Joël Quenneville. And together, we're here to share a bit of what we've learned along the way. STEPHANIE: So, Joël, what's new in your world in the year 2024? JOËL: Yeah, it's 2024. New year, new me. Or, in this case, maybe new year, new bugs? I'm working on a project where I ran into a really interesting time-specific bug. This particular page on the site only crashes in the month of January. There's some date logic that has a weird boundary condition there, and if you load that page during the month of January, it will crash, but during the entire rest of the year, it's fine. STEPHANIE: That's a fun New Year's tradition for this project [laughs], fixing this bug [laughs] every year. JOËL: It's been interesting because I looked a little bit at the git history of this bug, and it looks like it's been fixed in past Januarys, but then the fix changes the behavior slightly, so people bring the behavior back correct during the rest of the year that also happens to reintroduce the bug in January, and now I'm back to fixing it in January. So, it is a little bit of a tradition. STEPHANIE: Yeah, that is really funny. I was also recently debugging something, and we were having some flakiness with a test that we wrote. And we were trying to figure out because we had some date/time logic as well. And we were like, is there anything strange about this current time period that we are in that would potentially, you know, lead to a flaky test? And we were looking at the clock and we're like, "I don't think it's like, you know, midnight UTC or anything [laughs] like that." But, I mean, I don't know. It's like, how could you possibly think of, like, all of the various weird edge cases, you know, related to that kind of thing? I don't think I would ever be like, huh, it's January, so, surely, that must [laughs] mean that that's this particular edge case I'm seeing. JOËL: It's interesting because I feel like there's a couple of types of time-specific bugs that we see pretty frequently. If you're near the daylight savings boundary, let's say a week before sometimes, or whatever you're...if you're doing, like, a week from now logic or something like that, typically, I'll see failures in the test suite or maybe actual crashes in the code a week before springing forward and a week before falling back. And then, like you said, sometimes you see failures at the end of the day, Eastern time for me, when you approach that midnight UTC time boundary. I think this is the first time I've seen a failure in January due to the month being, like, a month boundary...or it's a year boundary really is what's happening. STEPHANIE: Yeah. That just sounds like another [laughs] thing you have to look out for. I'm curious: are you going to fix this bug for real or leave it for [laughs] 2025? JOËL: I've got a fix that I think is for real and that, like, not only fixes the break in January but also during the rest of the year gives the desired behavior. I think part of what's really interesting about this bug is that there are some subtle behavioral changes between a few different use cases where this code is called, part of which depend on when in the year you're calling it and whether you want to see it for today's date versus you can also specify a date that you want to see this report. And so, it turns out that there are a lot more edge cases than might be initially obvious. So, this turned into effectively a product discussion, and realizing, wait a minute, the code isn't telling the full story. There's more at a product level we need to discuss. And actually, I think I learned a lot about the product there. So, while it was maybe a surprising and kind of humorous bug to come across, I think it was actually a really good experience. STEPHANIE: Nice. That's awesome. That's a pretty good way to start the year, I would say. JOËL: I'd say so. How about you? What's new in your world? STEPHANIE: So, I don't know, I think towards the end of the year, last year, I was in a bit of a slump where I was in that work-from-couch phase of [laughs] the year, you know, like, things are slowing down and I, you know, winter was starting here. I wanted to be cozy, so I'd, you know, set up on the couch with a blanket. And I realized that I really wasn't sitting at my desk at all, and I kind of wanted to bring a little bit of that structure back into my workday, so I [chuckles] added some incentives for me to sit at my desk, which include I recently got a bird feeder that attaches to the window in my office. So, when I sit at my desk, I can hopefully see some birds hanging out. They are very flighty, so I've only seen birds when I'm, like, in the other room. And I'm like, oh, like, there's a bird at the bird feeder. Like, let me get up close to, like, get to admire them. And then as soon as I, like [laughs], get up close to the window, they fly away. So, I'm hoping that if I sit at my desk more, I'll spontaneously see more birds, and maybe they'll get used to, like, a presence closer to the window. And then my second incentive is I now have little chocolates at my desk [laughs]. JOËL: Nice. STEPHANIE: I've just been enjoying, like, a little treat and trying to keep them as a...okay, I've worked at my desk for an hour, and now I get a little reward for that [laughs]. JOËL: I like that. Do you know what kind of species of birds have been coming to your feeder? STEPHANIE: Ooh, yes. So, we got this birdseed mix called Cardinal and Friends [laughs]. JOËL: I love that. STEPHANIE: So, I have seen, like, a really beautiful red male cardinal come by. We get some robins and some chickadees, I think. Part of what I'm excited for this winter is to learn more how to identify more bird species. And I usually like to be out in nature and stuff, and winter is a hard time to do that. So, this is kind of my way of [chuckles] bringing that more into my life during the season. So, this is our first episode after a little bit of a break for the holidays. There actually has been some content of ours that has been published out in the world on the internet [laughs] during this time. And just wanted to point out in the few weeks that there weren't any Bike Shed episodes, I ended up doing a thoughtbot Rails development livestream with thoughtbot CEO Chad Pytel, and that was my first-time live streaming code [laughs]. And it was a really cool experience. I'm glad I had this podcast experience. So, I'm like, okay, well I have, you know, that, like, ability to do stuff kind of off script and present in the moment. But yeah, that was a really cool thing that I got to do, and I feel a little bit more confident about doing those kinds in the future. JOËL: And for those who are not aware, Chad does–I think it's a weekly live stream on Fridays where he's doing various types of code. So, he's done some work on some internal projects. He did a series where he upgraded, I think, a Rails 2 app all the way to Rails 7, typically with a guest who's another teammate from thoughtbot working on a thing. So, for those of our listeners that might find interesting, we'll put a link in the show notes where you can go see that. I think it's on YouTube and on Twitch. STEPHANIE: Yes. JOËL: What did you pair on? What kind of project were you doing for the livestream? STEPHANIE: So, we were working on thoughtbot's internal application called Hub, which is where we have, like, our internal messaging features. It's where we do a lot of our business operations-y things [laughs]. So, all of the, like, agency work that we do, we use our in-house software for that, and so Chad and I were working on a feature to introduce something that would help out with how we staff team members on projects. In other content news [laughs], Joël, I think you have something to share as well. JOËL: Yeah. So, we've mentioned on past episodes that I gave a talk at RubyConf this past November all about what the concept of time actually means within a program and the different ways of representing it, and the fact that time isn't really a single thing but actually kind of multiple related quantities. And over the holiday break, the talks from that conference got published. I'm pretty excited that that is now out there. We'd mentioned that as a highlight in the previous episode, highlighting accomplishments for the year, but it just wasn't quite out yet. We couldn't link it there. So, I'll leave a link in the show notes for this episode for anyone who's interested in seeing that. STEPHANIE: Sounds like that talk is also timely for a debug you -- JOËL: Ha ha ha! STEPHANIE: Were also mentioning earlier in the episode. So, a few episodes ago, I believe we mentioned that we had recently had, like, our company internal hackathon type thing where we have two days to get together and work with team members who we might not normally work with and get some cool projects started or do some team bonding, that kind of thing. And since I'm still, you know, unbooked on client work, I've been doing a lot of internal thoughtbot stuff, like continuing to work on the Hub app I mentioned just a bit ago. And from the hackathon, there was some work that was unfinished by, like, a project team that I decided to pick up this week as part of my internal work. And as I was kind of trying to gauge how much progress was made and, like, what was left to accomplish to get it over the finish line so it could be shipped, I noticed that because there were a couple of different people working on it, they had broken up this feature which was basically introducing, like, a new report for one of our teams to get some data on how certain projects are going. And there was, like, a UI portion and then some back-end portion, and then part of the back-end portion also involved a bit of a complex query that was pulled out as a separate ticket on its own. And so, all of those things were slightly, you know, were mostly done but just needed those, like, finishing touches, and then it also needed to come together. And I ended up pairing on this with another thoughtboter, and we spent the same amount of time that the hackathon was, so two days. We spent those two days on that, like, aspect of putting it all together. And I think I was a bit surprised by how much work that was, you know, we had kind of assumed that like, oh, like, all these pieces are mostly finished, but then the bulk of what we spended our time doing was integrating the components together. JOËL: Does this feel like a bit of a finish the rest of the OWL meme? STEPHANIE: What is that meme? I'm not familiar with it, but now I really want to know [laughs]. JOËL: It's a meme kind of making fun of some of these drawing tutorials where they're like, oh; first you draw, like, three circles. STEPHANIE: [laughs] JOËL: And then just finish the rest of the owl. STEPHANIE: [laughs] JOËL: And I was thinking of this beautifully drawn picture. STEPHANIE: Oh, that's so funny. Okay, yeah, I can see it in my head [laughs] now. It's like how to go from three circles, you know, to a recognizable [laughs] owl animal. JOËL: So, especially, they're like, oh, you know, like, we put in all the core classes and everything. It's all just basically there. You just need to connect it all together, and it's basically done [laughs]. And then you spend a lot of time actually getting that what feels like maybe the last 20 or 10% but takes maybe 80% of the time. STEPHANIE: Yeah, that sounds about right. So, you know, kind of working on that got me thinking about the alternative, which is honestly something that I'm still working on getting better at doing in my day-to-day. But there is this idea of a vertical slice or a full-stack slice, and that, basically, involves splitting a large feature into those full-stack slices. So, you have, like, a fully implemented piece rather than breaking them apart by layers of the stack. So, you know, I just see pretty frequently that, like, maybe you'll have a back-end ticket to do the database migration, to create your models, just whatever, maybe your controllers, or maybe that is even, like, another piece and then, like, the UI component. And those are worked on separately, maybe even by different people. But this vertical slice theory talks about how what you really want is to have a very thin piece of the feature that still delivers value but fully works. JOËL: As opposed to what you might call a horizontal slice, which would be something like, oh, I've built three Rails models. They're there. They're in the code. They talk to tables in the database, but there's nothing else happening with them. So, you've done work, but it's also more or less dead code. STEPHANIE: Yeah, that's a good point. I have definitely seen a lot of unused code paths [laughs] when you kind of go about it that way and maybe, like, that UI ticket never gets completed. JOËL: What are some tips for trying to do some of these narrower slices? Like, I have a ticket, and I have some work I need to do. And I want to break it down because I know it's going to be too big, and maybe the, like, intuitive way to do it is to split it by layers of your stack where I might do all the models, commit, ship that, deploy, then do some controllers, then do some view, or something like that, and you're suggesting instead going full stack. How do you break down the ticket more when all the pieces are interrelated? STEPHANIE: Yeah, that's a great point. One easy way to visualize it, especially if you have designs or something for this feature, right? Oftentimes, you can start to parse out sections or components of the user interface to be shipped separately. Like, yes, you would want all of it to have that rich feature, but if it's a view of some cards or something, and then, yeah, there's, like, the you can filter by them. You can search by them. All of those bits can be broken up to be like, well, like, the very basic thing that a customer would want to see is just that list of cards, and you can start there. JOËL: So, aggressively breaking down the card at, like, almost a product level. Instead of breaking it down by technical pieces, say, like, can we get even smaller amounts of behavior while still delivering value? STEPHANIE: Yeah, yeah, exactly. I like that you said product level because I think another axis of that could also be complexity. So, oftentimes, you know, I'll get a feature, and we're like, oh, we want to support these X number of things that we've identified [laughs]. You know, if it's like an e-com app you're building, you know, you're like, "Do we have all these products that we want to make sure to support?" And, you know, one way to break that down into that vertical slice is to ask, like, what if we started with just supporting one before we add variants or something like that? Teasing out, like, what would end up being the added complexity as you're developing, once you have to start considering multiple parameters, I think that is a good way to be able to start working more iteratively. And so, you don't have to hold all of that complexity in your head. JOËL: It's almost a bit of like a YAGNI principle but applied to features rather than to code. STEPHANIE: Yeah. Yeah. I like that. At first, I hesitated a little bit because I've certainly been in the position where someone has said like, "Well, we do really need this [laughs]." JOËL: Uh-huh. And, sometimes, the answer is, yes, we do need that, but what if I gave you a smaller version of that today, and we can do the other thing tomorrow? STEPHANIE: Right. Yeah, it's not like you're rejecting the idea that it's necessary but the way that you get about to that end result, right? JOËL: So, you keep using the term vertical slice or full-stack slice. I think when I hear that term, I think of specifically an article written by former thoughtboter, German Velasco, on our blog. But I don't know if that's maybe a term that has broader use in the industry. Is that a term that you've heard elsewhere? STEPHANIE: That's a good question. I think I mostly hear, you know, some form of like, "Can we break this ticket down further?" and not necessarily, like, if you think about how, right? I'm, like, kind of doing a motion with my hand [chuckles] of, like, slicing from top to bottom as opposed to, you know, horizontal. Yeah, I think that it may not be as common as I wish it were. Even if there's still some amount of adapting or, like, persuading your team members to get on board with this idea, like, I would be interested in, like, introducing that concept or that vocabulary to get teams talking about, like, how do they break down tickets? You know, like, what are they considering? Like, what alternatives are there? Like, are horizontal slices working for them or not? JOËL: A term that I've heard floating around and I haven't really pinned down is Elephant Carpaccio. Have you heard that before? STEPHANIE: I have, only because I, like, discovered a, like, workshop facilitation guide to run an exercise that is basically, like, helping people learn how to identify, like, smaller and smaller full-stack slices. But with the Elephant Carpaccio analogy, it's kind of like you're imagining a feature as big as an elephant. And you can create, like, a really thin slice out of them, and you can have infinite number of slices, but they still end up creating this elephant. And I guess you still get the value of [chuckles] a little carpaccio, a delicious [laughs] appetizer of thinly sliced meat. JOËL: I love a colorful metaphor. So, I'm curious: in your own practice, do you have any sort of guidelines or even heuristics that you like to use to help work in a more, I guess, iterative fashion by working with these smaller slices? STEPHANIE: Yeah, one thought that I had about it is that it plays really well with Outside-In Test Driven Development. JOËL: Hmmm. STEPHANIE: Yeah. So, if, you know, you are starting with a feature test, you have to start somewhere and, you know, maybe starting with, like, the most valuable piece of the feature, right? And you are starting at that level of user interaction if you're using Capybara, for example. And then it kind of forces you to drop down deeper into those layers. But once you go through that whole process of outside-in and then you arrive back to the top, you've created your full-stack feature [laughs], and that is shippable or, like, committable and, you know, potentially even shippable in and of itself. And you already have full test coverage with it. And that was a cool way that I saw some of those two concepts work well together. JOËL: Yeah, there is something really fun about the sort of Red-Green-Refactor cycle that TDD forces on you and that you're typically writing the minimum code required to pass a test. And it really forces you out of that developer brain where you're just like, oh, I've got to cover my edge cases. I've got to engineer for some things. And then maybe you realize you've written code that wasn't necessary. And so, I've found that often when I do, like, actually TDD a feature, I end up with code that's a lot leaner than I would otherwise. STEPHANIE: Yes, lean like a thin slice of Elephant Carpaccio. [laughter] JOËL: One thing you did mention that I wanted to highlight was the fact that when you do this outside-in approach for your tiny slice, at the end, it is shippable. And I think that is a core sort of tenet of this idea is that even though you're breaking things down into smaller and smaller slices, every slice is shippable to production. Like, it doesn't break the build. It doesn't break the website. And it provides some kind of value to the user. STEPHANIE: Yeah, absolutely. I think one thing that I still kind of get hung up on sometimes, and I'm trying to, you know, revisit this assumption is that idea of, like, is this too small? Like, is this valuable enough? When I mentioned earlier that I was working on a report, I think there was a part of me that's like, could I just ship a report with two columns [laughs]? And the answer is yes, right? Like, I thought about it, and I was like, well, if that data is, like, not available anywhere else, then, yeah, like, that would be valuable to just get out there. But I think the idea that, like, you know, originally, the hope was to have all of these things, these pieces of information, you know, available through this report, I think that, like, held me back a little bit from wanting to break it down. And I held it a little bit too closely and to be like, well, I really want to, like, you know, deliver something impressive. When you click on it, it's like, wow, like, look at all this data [laughs]. So, I'm trying to push back a little bit on my own preconceived notions that, like, there is such a thing as, like, a too small of a demo. JOËL: I've often worked with this at a commit level, trying to see, like, how small can I get a commit, and what is too small? And now you get into sort of the fraught question of what is a, you know, atomic commit? And I think, for me, where I've sort of come down is that a commit must pass CI. Like, I don't want a commit that's going to go into the main branch. I'm totally pro-work-in-progress commits on a branch; that's fine. But if it's going to get shipped into the main branch, it needs to be green. And it also cannot introduce dead code. STEPHANIE: Ooh. JOËL: So, if you're getting to the point where you're breaking either of those, you've got some sort of, like, partial commit that's maybe too small that needs more to be functional. Or you maybe need to restructure to say, look, instead of adding just ten models, can I add one model but also a little bit of a controller and a view? And now I've got a vertical slice. STEPHANIE: Yeah, which might even be less code [laughs] in the end. JOËL: Yes, it might be less code. STEPHANIE: I really like that heuristic of not introducing dead code, that being a goal. I'm going to think about that a lot [laughs] and try to start introducing that into when I think something is ready. JOËL: Another thing that I'll often do, I guess, that's almost like it doesn't quite fit in the slice metaphor, but it's trying to separate out any kind of refactor work into its own commit that is, you know, still follows those rules: it does not introduce dead code; it does not break the build; it's independently shippable. But that might be something that I do that sets me up for success when I want to do that next slice. So, maybe I'm trying to add a new feature, but just the way we built some of the internal models, they don't have the interface that I need right now, and that's fine because I don't want to build these models in anticipation of the future. I can change them in the future if I need. But now the future has come, and I need a slightly different shape. So, I start by refactoring, commit, maybe even ship that deploy. Maybe I then do my small feature afterwards. Maybe I come back next week and do the small feature, but there are two independent things, two different commits, maybe two different deploys. I don't know that I would call that refactor a slice and that it maybe goes across the full stack; maybe it doesn't. It doesn't show to the user because a refactor, by definition, is just changing the implementation without changing behavior. But I do like to break that out and keep it separate. And I guess it helps keep my slices lean, but I'm not quite sure where refactors fit into this metaphor. STEPHANIE: Yeah, that's interesting because, in my head, as I was listening to you talk about that, I was visualizing the owl again, the [laughs] owl meme. And I'm imagining, like, the refactoring making the slice richer, right? It's like you're adding details, and you're...it's like when you end up with the full animal, or the owl, the elephant, whatever, it's not just, like, a shoddy-looking drawing [laughs]. Like, ideally, you know, it has those details. Maybe it has some feathers. It's shaded in, and it is very fleshed out. That's just my weird, little brain trying [laughs] to stretch this metaphor to make it work. Another thing that I want to kind of touch a little bit more about when we're talking about how a lot of the work I was spending recently was that glue work, you know, the putting the pieces together, I think there was some aspect of discovery involved that was missed the first time around when these tickets were broken up more horizontally. I think that one really important piece that I was doing was trying to reconcile the different mental models that each person had when they were working on their separate piece. And so, maybe there's, like, an API, and then the frontend is expecting some sort of data, and, you know, you communicate it in a way that's, like, kind of hand-off-esque. And then when you put it together, it turns out that, oh, the pieces don't quite fit together, and how do you actually decide, like, what that mental model should be? Naming, especially, too, I've, you know, seen so many times when the name...like, an attribute on the frontend is named a little bit different than whatever is on the backend, and it takes a lot of work to unify that, like, to make that decision about, should they be the same? Should they be different? A lot of thought goes into putting those pieces together. And I think the benefit of a full-stack slice is that that work doesn't get lost. Especially if you are doing stuff like estimating, you're kind of discovering that earlier on. And I think what I just talked about, honestly, is what prevents those features from getting shipped in the end if you were working in a more horizontal way. JOËL: Yeah. It's so easy to have, like, big chunks of work in progress forever and never actually shipping. And one of the benefits of these narrower slices is that you're shipping more frequently. And that's, you know, interesting from a coding perspective, but it's kind of an agile methodology thing as well, the, like, ship smaller chunks more frequently. Even though you're maybe taking a little bit more overhead because you're having to, like, take the time to break down tasks, it will make your project move faster as a whole. An aspect that's really interesting to me, though, is what you highlighted about collaboration and the fact that every teammate has a slightly different mental model. And I think if you take the full-stack slice and every member is able to use their mental model, and then close the loop and actually, like, do a complete thing and ship it, I think it allows every other member who's going to have a slightly different mental model of the problem to kind of, yes, and... the other person rather than all sort of independently doing their things and having to reconcile them at the end. STEPHANIE: Yeah, I agree. I think I find, you know, a lot of work broken out into backend and frontend frequently because team members might have different specialties or different preferences about where they would like to be working. But that could also be, like, a really awesome opportunity for pairing [laughs]. Like, if you have someone who's more comfortable in the backend or someone more comfortable in the frontend to work on that full-stack piece together, like, even outside of the in-the-weeds coding aspects of it, it's like you're, at the very least, making sure that those two folks have that same mental model. Or I like what you said about yes, and... because it gets further refined when you have people who are maybe more familiar with, like, something about the app, and they're like, "Oh, like, don't forget about we should consider this." I think that, like, diversity of experience, too, ends up being really valuable in getting that abstraction to be more accurate so that it best represents what you're trying to build. JOËL: Early on, when I was pretty new working at thoughtbot, somebody else at the company had given me the advice that if I wanted to be more effective and work faster on projects, I needed to start breaking my work down into smaller chunks, and this is, you know, fairly junior developer at the time. The advice sounds solid, and everything we've talked about today sounds really solid. Doing it in practice is hard, and it's taken me, you know, a decade, and I'm still working on getting better at it. And I wrote an article about working iteratively that covers a lot of different elements where I've kind of pulled on threads and found out ways where you can get better at this. But I do want to acknowledge that this is not something that's easy and that just like the code that we're working on iteratively, our technique for breaking things down is something that we improve on iteratively. And it's a journey we're all on together. STEPHANIE: I'm really glad that you brought up how hard it is because as I was thinking about this topic, I was considering barriers into working in that vertical slice way, and barriers that I personally experience, as well as just I have seen on other teams. I had alluded to some earlier about, like, the perception of if I ship this small thing, is it impressive enough, or is it valuable enough? And I think I realized that, like, I was getting caught up in, like, the perception part, right? And maybe it doesn't matter [chuckles], and I just need to kind of shift the way I'm thinking about it. And then, there are more real barriers or, like, concrete barriers that are tough. Long feedback loops is one that I've encountered on a team where it's just really hard to ship frequently because PR reviews aren't happening fast enough or your CI or deployment process is just so long that you're like, I want to stuff everything into [chuckles] this one PR so that at least I won't have to sit and wait [laughs]. And that can be really hard to work against, but it could also be a really interesting signal about whether your processes are working for you. It could be an opportunity to be like, "I would like to work this way, but here are the things that are preventing me from really embracing it. And is there any improvement I can make in those areas?" JOËL: Yeah. There's a bit of a, like, vicious cycle that happens there sometimes, especially around PR review, where when it takes a long time to get reviews, you tend to decide, well, I'm going to not make a bunch of PRs; I'm going to make one big one. But then big PRs are very, like, time intensive and require you to commit a lot of, like, focus and energy to them, which means that when you ask me for a review, I'm going to wait longer before I review it, which is going to incentivize you to build bigger PRs, which is going to incentivize me to wait longer, and now we just...it's a vicious cycle. So, I know I've definitely been on projects where a question the team has had is, "How can we improve our process? We want faster code review." And there's some aspect of that that's like, look, everybody just needs to be more disciplined or more alert and try to review things more frequently. But there's also an element of if you do make things smaller, you make it much easier for people to review your code in between other things. STEPHANIE: Yeah, I really liked you mentioning incentives because I think that could be a really good place to start if you or your team are interested in making a change like this, you know, making an effort to look at your team processes and being like, what is incentivized here, and what does our system encourage or discourage? And if you want to be making that shift, like, that could be a good place to start in identifying places for improvement. JOËL: And that happens on a broader system level as well. If you look at what does it take to go from a problem that is going to turn into a ticket to in-production in front of a client, how long is that loop? How complex are the steps to get there? The longer that loop is, the slower you're iterating. And the easier it is for things to just get hung up or for you to waste time, the harder it is for you to change course. And so, oftentimes, I've come on to projects with clients and sort of seen something like that, and sort of seen other pain points that the team has and sort of found that one of the root causes is saying, "Look, we need to tighten that feedback loop, and that's going to improve all these other things that are kind of constellation around it." STEPHANIE: Agreed. On that note, shall we wrap up? JOËL: Let's wrap up. STEPHANIE: Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeee!!!!!!! AD: Did you know thoughtbot has a referral program? If you introduce us to someone looking for a design or development partner, we will compensate you if they decide to work with us. More info on our website at: tbot.io/referral. Or you can email us at referrals@thoughtbot.com with any questions.

The Bike Shed
410: All About Documentation

The Bike Shed

Play Episode Listen Later Dec 12, 2023 32:02


Joël shares his experiences with handling JSON in a Postgres database. He talks about his challenges with ActiveRecord and JSONB columns, particularly the unexpected behavior of storing and retrieving JSON data. Stephanie shares her recent discovery of bookmarklets and highlights a bookmarklet named "Check This Out," which streamlines searching for books on Libby, an ebook and audiobook lending app. The conversation shifts to using constants in code as a form of documentation. Stephanie and Joël discuss how constants might not always accurately reflect current system behavior or logic, leading to potential misunderstandings and the importance of maintaining accurate documentation. Bookmarklets (https://www.freecodecamp.org/news/what-are-bookmarklets/) "Check This Out" Bookmarklet (https://checkthisout.today/) Libby (https://libbyapp.com/interview/welcome#doYouHaveACard) Productivity Tricks (https://www.bikeshed.fm/403) 12 Factor App Config (https://12factor.net/config) A Hierarchy of Documentation (https://challahscript.com/hiearchy_of_documentation) Sustainable Rails (https://sustainable-rails.com/) rails-erd gem (https://github.com/voormedia/rails-erd) Transcript STEPHANIE: Hello and welcome to another episode of the Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Stephanie Minn. JOËL: And I'm Joël Quenneville. And together, we're here to share a bit of what we've learned along the way. STEPHANIE: So, Joël, what's new in your world? JOËL: What's new in my world is JSON and how to deal with it in a Postgres database. So, I'm dealing with a situation where I have an ActiveRecord model, and one of the columns is a JSONB column. And, you know, ActiveRecord is really nice. You can just throw a bunch of different data at it, and it knows the column type, and it will do some conversions for you automatically. So, if I'm submitting a form and, you know, form values might come in as strings because, you know, I typed in a number in a text field, but ActiveRecord will automatically parse that into an integer because it knows we're saving that to an integer column. So, I don't need to do all these, like, manual conversions. Well, I have a form that has a string of JSON in it that I'm trying to save in a JSONB column. And I expected ActiveRecord to just parse that into a hash and store it in Postgres. That is not what happens. It just stores a raw string, so when I pull it out again, I don't have a hash. I have a raw string that I need to deal with. And I can't query it because, again, it is a raw string. So, that was a bit of an unexpected behavior that I saw there. STEPHANIE: Yeah, that is unexpected. So, is this a field that has been used for a while now? I'm kind of surprised that there hasn't been already some implementations for, like, deserializing it. JOËL: So, here's the thing: I don't think you can have an automatic deserialization there because there's no way of knowing whether or not you should be deserializing. The reason is that JSON is not just objects or, in Ruby parlance, hashes. You can also have arrays. But just raw numbers not wrapped in hashes are also valid JSON as are raw strings. And if I just give you a string and say, put this in a JSON field, you have no way of knowing, is this some serialized JSON that you need to deserialize and then save? Or is it just a string that you should save because strings are already JSON? So, that's kind of on you as the programmer to make that distinction because you can't tell at runtime which one of these it is. STEPHANIE: Yeah, you're right. I just realized it's [laughs] kind of, like, an anything goes [laughs] situation, not anything but strings are JSON, are valid JSON, yep [laughs]. That sounds like one of those things that's, like, not what you think about immediately when dealing with that kind of data structure, but... JOËL: Right. So, the idea that strings are valid JSON values, but also all JSON values can get serialized as strings. And so, you never know: are you dealing with an unserialized string that's just a JSON value, or are you dealing with some JSON blob that got serialized into a string? And only in one of those do you want to then serialize before writing into the database. STEPHANIE: So, have you come to a solution or a way to make your problem work? JOËL: So, the solution that I did is just calling a JSON parse before setting that attribute on my model because this value is coming in from a form. I believe I'm doing this when I'm defining the strong parameters for that particular form. I'm also transforming that string by parsing it into a hash with the JSON dot parse, which then gets passed to the model. And then I'm not sure what JSONB serializes as under the hood. When you give it a hash, it might store it as a string, but it might also have some kind of binary format or some internal AST that it uses for storage. I'm not sure what the implementation is. STEPHANIE: Are the values in the JSONB something that can be variable or dynamic? I've seen some people, you know, put that in getter so that it's just kind of done for you for anyone who needs to access that field. JOËL: Right now, there is a sort of semi-consistent schema to that. I think it will probably evolve to where I'll pull some of these out to be columns on the table. But it is right now kind of an everything else sort of dumping ground from an API. STEPHANIE: Yeah, that's okay, too, sometimes [laughs]. JOËL: Yeah. So, interesting journey into some of the fun edge cases of dealing with a format whose serialized form is also a valid instance of that format. What's been new in your world? STEPHANIE: So, I discovered something new that has been around on the internet for a while, but I just haven't been aware of it. Do you know what a bookmarklet is? JOËL: Oh, like a JavaScript code that runs in a bookmark? STEPHANIE: Yeah, exactly. So, you know, in your little browser bookmark where you might normally put a URL, you can actually stick some JavaScript in there. And it will run whenever you click your bookmark in your browser [chuckles]. So, that was a fun little internet tidbit that I just found out about. And the reason is because I stumbled upon a bookmarklet made by someone. It's called Check This Out. And what it does is there's another app/website called Libby that is used to check out ebooks and audiobooks for free from your local public library. And what this Check This Out bookmarklet does is you can kind of select any just, like, text on a web page, and then when you click the bookmarklet, it then just kind of sticks it into the query params for Libby's search engine. And it takes you straight to the results for that book or that author, and it saves you a few extra manual steps to go from finding out about a book to checking it out. So, that was really neat and cute. And I was really surprised that you could do that. I was like, whoa [laughs]. At first, I was like, is this okay? [laughs] If you, like, you can't read, you know, you don't know what the JavaScript is doing, I can see it being a little sketchy. But –- JOËL: Be careful of executing arbitrary JavaScript. STEPHANIE: Yeah, yeah. When I did look up bookmarklets, though, I kind of saw that it was, you know, just kind of a fun thing for people who might be learning to code for the first time to play around with. And some fun ideas they had for what you could do with it was turning all the font on a web page to Comic Sans [laughs]. So yeah, I thought that was really cute. JOËL: Has that inspired you to write your own? STEPHANIE: Well, we did an episode a while ago on productivity tricks. And I was thinking like, oh yeah, there's definitely some things that I could do to, you know, just stick some automated tasks that I have into a bookmarklet. And that could be a really fun kind of, like, old-school way of doing it, as opposed to, you know, coding my little snippets or getting into a new, like, Omnibar app [laughs]. JOËL: So, something that is maybe a little bit less effort than building yourself a browser extension or something like that. STEPHANIE: Yeah, exactly. JOËL: I had a client project once that involved a...I think it was, like, a five-step wizard or something like that. It was really tedious to step through it all to manually test things. And so, I wrote a bookmarklet that would just go through and fill out all the fields and hit submit on, like, five pages worth of these things. And if anything didn't work, it would just pause there, and then you could see it. In some way, it was moving towards the direction of, like, an automated like Capybara style test. But this was something that was helping for manual QA. So, that was a really fun use of a bookmarklet. STEPHANIE: Yeah, I like that. Like, just an in-between thing you could try to speed up that manual testing without getting into, like you said, an automated test framework for your browser. JOËL: The nice thing about that is that this could be used without having to set up pretty much anything, right? You paste a bit of JavaScript into your bookmark bar, and then you just click the button. That's all you need to do. No need to make sure that you've got Ruby installed on your machine or any of these other things that you would need for some kind of testing framework. You don't need Selenium. You don't need ChromeDriver. It just...it works. So, I was working...this was a greenfield startup project. So, I was working with a non-technical founder who didn't have all these things, you know, dev tooling on his machine. So, he wanted to try out things but not spend his days filling out forms. And so, having just a button he could click was a really nice shortcut. STEPHANIE: That's really cool. I like that a lot. I wasn't even thinking about how I might be able to bring that in more into just my daily work, as opposed to just something kind of fun. But that's an awesome idea. And I hope that maybe I'll have a good use for one in the future. JOËL: It feels like the thing that has a lot of potential, and yet I have not since written...I don't think I've written any bookmarklets for myself. It feels like it's the kind of thing where I should be able to do this for all sorts of fun tooling and just automate my life away. Somehow, I haven't done that. STEPHANIE: Bring back the bookmarklet [laughs]. That's what I have to say. JOËL: So, I mentioned earlier that I was working with a JSONB column and storing JSON on an ActiveRecord model. And then I wanted to interact with it, but the problem is that this JSON is somewhat arbitrary, and there are a lot of magic strings in there. All of the key names might change. And I was really concerned that if the schema of that JSON ever changed, if we changed some of the key names or something like that, we might accidentally break code in multiple parts of the app. So, I was very careful while building that model to quarantine any references to any raw strings only within that model, which meant that I leaned really heavily on constants. And, in some way, those constants end up kind of documenting what we think the schema of that JSON should be. And that got me thinking; you were telling me recently about a scenario where some code you were working with relied heavily on constants as a form of documentation, and that documentation kind of lied to you. STEPHANIE: Yeah, it did. And I think you mentioned something that I wanted to point out, which is that the magic strings that you think might change, and you wanted to pull that out into a constant, you know, so at least it's kind of defined in one place. And if it ever does change, you know, you don't have to change it in all of those places. And I do think that, normally, you know, if there's opportunities to extract those magic strings and give a name to them, that is beneficial. But I was gripping a little bit about when constants become, I guess, like, too wieldy, or there's just kind of, like, too much of a dependency on them as the things documenting how the app should work when it's constantly changing. I realized that I just used constant and constantly [laughs]. JOËL: The only constant is that it is not constant. STEPHANIE: Right. And so, the situation that I found myself in—this was on a client project a little bit ago—was that the constants became, like, gatekeepers of that logic where dev had to change it if the app's behavior changed, and maybe we wanted to change the value of it. And also, one thing that I noticed a lot was that we, as developers, were getting questions about, "Hey, like, how does this actually work?" Like, we were using the constants for things like pricing of products, for things like what is a compatible version for this feature. And because that was only documented in the code, other people who didn't have access to it actually were left in the dark. And because those were changing with somewhat frequency, I was just kind of realizing how that was no longer working for us. JOËL: Would you say that some of these values that we stored as constants were almost more like config rather than constants or maybe they're just straight-up application data? I can imagine something like price of an item you probably want that to be a value in the database that can be updated by an admin. And some of these other things maybe are more like config that you change through some kind of environment variable or something like that. STEPHANIE: Yeah, that's a good point. I do think that they evolved to become things that needed to be configured, right? I suppose maybe there wasn't as much information or foresight at the beginning of like, oh, this is something that we expect to change. But, you know, kind of when you're doing that first pass and you're told, like, hey, like, this value should be the price of something, or, like, the duration of something, or whatever that may be. It gets codified [chuckles]. And there is some amount of lift to change it from something that is, at first, just really just documenting what that decision was at the time to something that ends up evolving. JOËL: How would you draw a distinction between something that should be a constant versus something that maybe would be considered config or some other kind of value? Because it's pretty easy, right? As developers, we see magic numbers. We see magic strings. And our first thought is, oh, we've seen this problem before—constant. Do you have maybe a personal heuristic for when to reach for a constant versus when to reach for something else? STEPHANIE: Yeah, that's a good question. I think when I started to see it a lot was especially when the constants were arrays or hashes [laughs]. And I guess that is actually kind of a signal, right? You will likely be adding more stuff [laughs] into that data structure [laughs]. And, again, like, maybe it's okay, like, the first couple of times. But once you're seeing that request happen more frequently, that could be a good way to advocate for storing it in the database or, like, building a lightweight admin kind of thing so that people outside of the dev team can make those configuration changes. I think also just asking, right? Hey, like, how often do we suspect this will change? Or what's on the horizon for the product or the team where we might want to introduce a way to make the implementation a bit more flexible to something that, you know, we think we know now, but we might want to adjust for? JOËL: So, it's really about change and how much we think this might change in the future. STEPHANIE: Speaking of change, this actually kind of gets into the broader topic of documentation and how to document a changing and evolving entity [chuckles], you know, that being, like, the codebase or the way that decisions are made that impact how an application works. And you had shared, in preparation for this topic, an article that I read and enjoyed called Hierarchy of Documentation. And one thing that I liked about it is that it kind of presented all of the places that you could put information from, you know, straight in the code, to in your commit messages, to your issue management system, and to even wikis for your repo or your team. And I think that's actually something that we would want to share with new developers, you know, who might be wondering, like, where do I find or even put information? I really liked how it was kind of, like, laid out and gave, like, different reasons for where you might want to put something or not. JOËL: We think a lot about documentation as code writers. I'm curious what your experience is as a code reader. How do you tend to try to read code and understand documentation about how code works? And, apparently, the answer is, don't read the constants because these constants lie. STEPHANIE: I think you are onto something, though, because I was just thinking about how distrustful I've become of certain types of documentation. Like, when I think of code comments, on one hand, they should be a signal, right? They should kind of draw your attention to something maybe weird or just, like, something to note about the code that it's commenting on, or where it's kind of located in a file. But I sometimes tune them out, I'm not going to lie. When I see a really big block of code [chuckles] comment, I'm like, ugh, like, do I really have to read all of this? I'm also not positive that it's still relevant to the code below it, right? Like, I don't always have git blame, like, visually enabled in my editor. But oftentimes, when I do a little bit of digging, that comment is left over from maybe when that code was initially introduced. But, man, there have been lots of commits [chuckles] in the corresponding, you know, like, function sense, and I'm not really sure how relevant it is anymore. Do you struggle with the signal versus noise issue with code comments? How much do you trust them, and how much do you kind of, like, give credence to them? JOËL: I think I do tend to trust them with maybe some slight skepticism. It really depends on the codebase. Some codebases are really bad sort of comment hygiene and just the types of comments that they put in there, and then others are pretty good at it. The ones that I tend to particularly appreciate are where you have maybe some, like, weird function and you're like, what is going on here? And then you've got a nice, little paragraph up top explaining what's going on there, or maybe an explanation of ways you might be tempted to modify that piece of code and, like, why it is the way it is. So, like, hey, you might be wanting to add an extra branch here to cover this edge case. Don't do that. We tried it, and it causes problems for XY reasons. And sometimes it might be, like, a performance thing where you say, look, the code quality person in you is going to look at this and say, hey, this is hard to read. It would be better if we did this more kind of normalized form. Know that we've particularly written this in a way that's hard to read because it is more performant, and here are the numbers. This is why we want it in this way. Here's a link to maybe the issue, or the commit, or whatever where this happened. And then if you want to start that discussion up again and say, "Hey, do we really need performance here at the cost of readability?", you can start it up again. But at least you're not going to just be like, oh, while I'm here, I'm going to clean up this messy code and accidentally cause a regression. STEPHANIE: Yeah. I like what you said about comment hygiene being definitely just kind of, like, variable depending on the culture and the codebase. JOËL: I feel like, for myself, I used to be pretty far on the spectrum of no comments. If I feel the need to write a comment, that's a smell. I should find other ways to communicate that information. And I think I went pretty far down that extreme, and then I've been slowly kind of coming back. And I've probably kind of passed the center, where now I'm, like, slightly leaning towards comments are actually nice sometimes. And they are now a part of my toolkit. So, we'll see if I keep going there. Maybe I'll hit some point where I realize that I'm putting too much work into comments or comments are not being helpful, and I need to come back towards the center again and focus on other ways of communicating. But right now, I'm in that phase of doing more comments than I used to. How about you? Where do you stand on that sort of spectrum of all information should be communicated in code tokens versus comments? STEPHANIE: Yeah, I think I'm also somewhere in the middle. I think I have developed an intuition of when it feels useful, right? In my gut, I'm like, oh, I'm doing something weird. I wish I didn't have to do this [chuckles]. I think it's another kind of intuition that I have now. I might leave a comment about why, and I think that is more of that signal, right? Though I also recently have been using them more as just, like, personal notes for myself as I'm, you know, in my normal development workflow, and then I will end up cleaning them up later. I was working on a codebase where there was a soft delete functionality. And that was just, like, a concern that was included in some of the models. And I didn't realize that that's what was going on. So, when I, you know, I was calling destroy, I thought it was actually being deleted, and it turns out it wasn't. And so, that was when I left a little comment for myself that was like, "Hey, like, this is soft deleted." And some of those things I do end up leaving if I'm like, yes, other people won't have the same context as me. And then if it's something that, like, well, people who work in this app should know that they have soft delete, so then I'll go ahead and clean that up, even though it had been useful for me at the time. JOËL: Do you capture that information and then put it somewhere else then? Or is it just it was useful for you as a stepping-stone on the journey but then you don't need it at the end and nobody else needs to care about it? STEPHANIE: Oh, you know what? That's actually a really great point. I don't think I had considered saving that information. I had only thought about it as, you know, just stuff for me in this particular moment in time. But that would be really great information to pull out and put somewhere else [chuckles], perhaps in something like a wiki, or like a README, or somewhere that documents things about the system as a whole. Yeah, should we get into how to document kind of, like, bigger-picture stuff? JOËL: How do you feel about wikis? Because I feel like I've got a bit of a love-hate relationship with them. STEPHANIE: I've seen a couple of different flavors of them, right? Sometimes you have your GitHub wiki. Sometimes you have your Confluence ecosystem [laughs]. I have found that they work better if they're smaller [laughs], where you can actually, like, navigate them pretty well, and you have a sense of what is in there, as opposed to it just being this huge knowledge base that ends up actually, I think, working against you a little bit [laughs]. Because so much information gets duplicated if it's hard to find and people start contributing to it maybe without keeping in mind, like, the audience, right? I've seen a lot of people putting in, like, their own personal little scripts [laughs] in a wiki, and it works for them but then doesn't end up working for really anyone else. What's your love-hate relationship to them? JOËL: I think it's similar to what you were saying, a little bit of structure is nice. When they've just become dumping grounds of information that is maybe not up to date because over the course of several years, you end up with a lot of maybe conflicting articles, and you don't know which one is the right thing to do, it becomes hard to find things. So, when it just becomes a dumping ground for random information related to the company or the app, sometimes it becomes really challenging to find the information I need and to find information that's relevant, to the point where oftentimes looking something up in the wiki is my last resort. Like, I'm hoping I will find the answer to my question elsewhere and only fallback to the wiki if I can't. STEPHANIE: Yeah, that's, like, the sign that the wiki is really not trustworthy. And it kind of is diminishing returns from there a bit. I think I fell into this experience on my last project where it was a really, really big wiki for a really big codebase for a lot of developers. And there was kind of a bit of a tragedy of the commons situation, where on one hand, there were some things that were so manual that the steps needed to be very explicitly documented, but then they didn't work a lot of the time [laughs]. But it was hard to tell if they weren't working for you or because it was genuinely something wrong with, like, the way the documentation laid out the steps. And it was kind of like, well, I'm going to fix it for myself, but I don't know how to fix it for everyone else. So, I don't feel confident in updating this information. JOËL: I think that's what's really nice about the article that you mentioned about the hierarchy of documentation. It's that all of these different forms—code, comments, commit messages, pull requests, wikis—they don't have to be mutually exclusive. But sometimes they work sort of in addition to each other sort of each adding more context. But also, sometimes it's you sort of choose the one that's the highest up on that list that makes sense for what you're trying to do, so something like documenting a series of steps to do something maybe a wiki is a good place for that. But maybe it's better to have that be executable. Could that be a script somewhere? And then maybe that can be a thing that is almost, like, living documentation, but also where you don't need to maybe even think about the individual steps anymore because the script is running, you know, 10 different things. And I think that's something that I really appreciated from the book Sustainable Rails is there's a whole section there talking about the value of setup scripts and how people who are getting started on your app don't want to have to care about all the different things to set it up, just run a script. And also, that becomes living documentation for what the app needs, as opposed to maybe having a bulleted list with 10 elements in it in your project README. STEPHANIE: Yeah, absolutely. In the vein of living documentation, I think one thing that wikis can be kind of nice for is for putting visual supplements. So, I've seen them have, like, really great graphs. But at the same time, you could use a gem like Rails-ERD that generates the entity relationship diagram as the schema of your database changes, right? So, it's always up to date. I've seen that work well, too, when you want to have, like I said, those, like, system-level documentation that sometimes they do change frequently and, you know, sometimes they don't. But that's definitely worth keeping in mind when you choose, like, how you want to have that exist as information. JOËL: How do you feel about deleting documentation? Because I feel like we put so much work into writing documentation, kind of like we do when writing tests. It feels like more is always better. Do you ever go back and maybe sort of prune some of your docs, or try to delete some things that you think might no longer be relevant or helpful? STEPHANIE: I was also thinking of tests when you first posed that question. I don't know if I have it in my practice to, like, set aside time and be like, hmm, like, what looks outdated these days? I am starting to feel more confident in deleting things as I come across them if I'm like, I just completely ignored this or, like, this was just straight up wrong [laughs]. You know, that can be scary at first when you aren't sure if you can make that determination. But rather than thrust that, you know, someone else going through that same process of spending time, you know, trying to think about if this information was useful or not, you can just delete it [laughs]. You can just delete tests that have been skipped for months because they don't work. Like, you can delete information that's just no longer relevant and, in some ways, causing you more pain because they are cluttering up your wiki ecosystem so that no one [laughs] feels that any of that information is relevant anymore. JOËL: I'll be honest, I don't think I've ever deleted a wiki article that was out of date or no longer relevant. I think probably the most I've done is go to Slack and complain about how an out-of-date wiki page led me down the wrong path, which is probably not the most productive way to channel those feelings. So, maybe I should have just gone back and deleted the wiki page. STEPHANIE: I do like to give a heads up, I think. It's like, "Hey, I want to delete this thing. Are there any qualms?" And if no one on your team can see a reason to keep it and you feel good about that it's not really, like, serving its purpose, I don't know, maybe consider just doing it. JOËL: To kind of wrap up this topic, I've got a spicy question for you. STEPHANIE: Okay, I'm ready. JOËL: Do you think that AI is going to radically change the way that we interact with documentation? Imagine you have an LLM that you train on maybe not just your code but the Git history. It has all the Git comments and maybe your wiki. And then, you can just ask it, "Why does function foo do this thing?" And it will reference a commit message or find the correct wiki article. Do you think that's the future of understanding codebases? STEPHANIE: I don't know. I'm aware that some people kind of can see that as a use case for LLMs, but I think I'm still a little bit nervous about the not knowing how they got there kind of part of it where, you know, yes, like I am doing this manual labor of trying to sort out, like, is this information good or trustworthy or not? But at least that is something I'm determining for myself. So, that is where my skepticism comes in a little bit. But I also haven't really seen what it can do yet or seen the outcomes of it. So, that's kind of where I'm at right now. JOËL: So, you think, for you, the sort of the journey of trying to find and understand the documentation is a sort of necessary part of building the understanding of what the code is doing. STEPHANIE: I think it can be. Also, I don't know, maybe my life would be better by having all that cut out for me, or I could be burned by it because it turns out that it was bad information [laughs]. So, I can't say for sure. On that note, shall we wrap up? JOËL: Let's wrap up. STEPHANIE: Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeee!!!!!! AD: Did you know thoughtbot has a referral program? If you introduce us to someone looking for a design or development partner, we will compensate you if they decide to work with us. More info on our website at: tbot.io/referral. Or you can email us at: referrals@thoughtbot.com with any questions.

The Bike Shed
409: Support & Maintenance and Rotating Developers

The Bike Shed

Play Episode Listen Later Dec 5, 2023 28:07


Stephanie recommends "Blue Eye Samurai" and a new ceramic pot (donabe) for cooking. Joël talks about the joy of holding a warm beverage in a unique mug. Stephanie discusses her shift to a part-time support and maintenance role at thoughtbot, contrasting it with her full-time development work. She highlights the importance of communication, documentation, and workplace flexibility in this role. Stephanie appreciates the professional growth opportunities and aligns this flexible work style with her long-term career goals. Blue Eye Samurai (https://www.netflix.com/title/81144203) Donabe pots (https://jinenstore.com/collections/nagatani-en) thoughtbot's Support & Maintenance services (https://thoughtbot.com/services/rails-maintenance) Transcript: JOËL: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Joël Quenneville. STEPHANIE: And I'm Stephanie Minn. And together, we're here to share a bit of what we've learned along the way. JOËL: So, Stephanie, what's new in your world? STEPHANIE: I have a TV show recommendation this week. I think this is my first time having TV or movies to recommend, so this will be fun. My partner and I just finished watching Blue Eye Samurai on Netflix, which is an animated historical Samurai drama. But the really cool thing about it is that the protagonist she's a woman who is disguising herself as a man, and she is half Japanese and half White, which the show takes place during Edo, Japan. And so that was a time when Japan was locked down, and there were no outsiders allowed in the country. And so, to be mixed race like that was to be, like, kind of, like, demonized and to be really excluded and shamed. And so, the main character is on, like, a revenge mission. And it was such a cool show. I was kind of, like, on the edge of my seat the whole time. And it's very beautifully animated. There were just a lot of really awesome things about it. And I think it's very different from what I've been seeing on TV these days. JOËL: Is this a single-season show? STEPHANIE: So far, there's just one season. I think it's pretty new, yeah. It's very watchable in a couple of weekends. [laughter] JOËL: Dangerously so. STEPHANIE: Yeah, exactly [laughs]. JOËL: How do you feel about the way they end the arc in season one? Do they kind of leave you on a cliffhanger, or does it feel like a pretty satisfying place? STEPHANIE: Ooh, I think both, which is the sweet spot, in my opinion, where it's not, like, cliffhanger for the sake of, like, ugh, now I feel like I have to just watch the next part to see what happens because I was left unsatisfied. I like when seasons are kind of like chapters of the story, right? And the characters are also well written, too, and really fleshed out even, you know, some of the side characters. They all have their arcs that are really satisfying. And, again, I just was left very impressed. JOËL: I guess that's the power of good storytelling. STEPHANIE: Yeah. I was reading a review of the show. And that was kind of the theme of–it was just that, like, this is really good storytelling, and I would have to agree. Yeah, I highly recommend checking it out. It was very fun. It was very bloody, but [chuckles], for me, it being animated actually made it a little more palatable for me [laughs]. The fight scenes, the action scenes were really cool. I think the way that it's been described is kind of, like, you know, if you like historical dramas, or if you like things like Game of Thrones, there's kind of something for everyone. I recommend checking it out. Joël, what's new in your world? JOËL: Listeners of the show don't know this, but you and I are on a video call while we're recording this. And you'd commented earlier that I was holding a cool mug. It's got a rock climbing hold as a handle, which is pretty fun. I enjoy a lot of bouldering. That makes it a fun mug. But I was recently thinking about just how much pleasure I get from holding a mug with a warm beverage. It's such a small thing, but it makes me so happy. And that got me thinking more broadly about what are things in life that are kind of like that. They're small things that have, like, an outsized impact on your happiness. Do you have anything like that? STEPHANIE: Oh yes, absolutely. You were talking about the warmth of a hot beverage in your hands. And I was thinking about something similar, too, because I'm pretty sure this time of year last year, I talked about something that was new in my world that was just, like, a thing that I got to make winter more tolerable for me here in Chicago, and I think it was, like, a heated blanket [laughs]. And I am similarly in that space this year of like, what can I do or get to make this winter better than last winter? So, this year, what I got that I'm really excited to use— it actually just came in the mail—is this ceramic pot called the donabe that's kind of mainly used for Japanese cooking, especially, like, hot pot. And so, it will be a huge improvement to my soup game this year [laughs]. Similarly, it's kind of, like, one of those small things where you can take it from the stovetop where you're cooking straight to the table, and I'm so looking forward to that. It's kind of like your hot beverage in your hand but, like, three times the size [laughs]. JOËL: Right. The family-style version of it. STEPHANIE: Yeah, exactly. So, that's what I'm really looking forward to this year as something that is just, like, I don't know, a little small upgrade to my regular soup routine. But I think I will get a lot of pleasure [laughs] out of it. JOËL: What do you normally cook in that style of pot? Is it typically you do a hot pot in there, or is it meant for soups? STEPHANIE: Yeah, it holds heat really well, so I think that's why it's used for soup a lot. And the one that I got specifically has a little ceramic steamer plate as well. And so, I'm looking forward to having, like, this setup that's made for steaming, where you don't have to have any, like, too many extra bits. And, again, it can go from stove to table, and that's one less thing I [chuckles] need to wash. JOËL: I love it. So, something else that is kind of new in your world is you'd mentioned on a recent episode you'd wrapped up with your current client. And you've rotated on to not exactly a new client but a new almost line of business. You're doing a rotation with our support and maintenance team. Can you tell us a little bit about what that is like? STEPHANIE: Yeah. I'm excited to share more about it because this is my first time on this team doing this work. And it's pretty new for thoughtbot, too. I think it's only, like, a year old that we have had this sub-team of the one that you and I are on, Boost. In the sub-team, support and maintenance is focused on providing flexible part-time work for clients who are just needing some dedicated hours, not necessarily for, you know, a lot of, like, intense new feature work, but making sure that things are running smoothly. A lot of the clients, you know, have had Rails apps that are several years old, that are chugging along [chuckles], just need that, like, attention every now and then to make sure that upgrades are happening, fix any bugs, kind of as the app just continues to work and provide value. And then, occasionally, there is a little bit of feature work. But the interesting thing about being on this team is that instead of being on one client full-time, you are working on a lot of different clients at the same time, and a lot of them are on retainers. So, they maybe have, like, 20 hours a month of work that gets filled with kind of whatever tasks need to be done during that time. So yeah, I recently joined a few days ago and have been very surprised by kind of this style of work. It's different from what I'm used to. JOËL: That seems pretty different than the sort of traditional thoughtbot client engagement. Typically, if I'm a client and I'm hiring a team from thoughtbot, as a client, I get sort of a dedicated team. And they're probably either building some things for me or maybe working with my team and sort of full-time building features. Whereas if I hire the support and maintenance team, it sounds like it's a bit more ad hoc. And it's things I assume it's like, oh, we probably need to upgrade our Rails version since a new release came out last month. Can you do that? Here's a small bug that was reported. Can somebody fix that? Things along those lines. Is that pretty approximate of what the experience is for a client? STEPHANIE: Yeah, I would say so. I think the other surprising thing has been there have been a little bit of more DevOps type of tasks as well mixed in there. Because oftentimes, these are smaller clients who maybe have, like, a few developers actively working on new features and that type of stuff. But there is, like, so much of the connecting work that needs to happen when you have an application. And if you don't have a full in-house team for that, that often gets put on developers' plates. But it's kind of nice to have this flexible support and maintenance team, again, to, like, do the work as it comes up. A lot of it is not necessarily, like, stuff that can be planned in advance. It's kind of like, oh, we're hitting, like, our usage limit for this Heroku add-on. Let's evaluate if this is still working for us, if this is a good tier to be on. Like, should we upgrade? Are there other levers we could pull or adjustments we can make? So, that's actually been some of the stuff that I've been working on, too, which is, again, a little bit different from normal development work but also still very much related. And it's all kind of part of the job. And, you know, a lot of the skills are transferable. And to know how to do development in a framework then sets you up, I think, really well to, like, be able to make those kinds of evaluations. JOËL: So, it sounds like you almost, in a sense, provide a bit of a velocity cushion for clients so that if something does come up where they would maybe normally need to pull a dev off of feature work to do some side thing for a couple of days, you can come in and handle that so that their dev team stays focused on shipping features. STEPHANIE: Yeah, I like that phrase you used: velocity cushion. That's cool. I like it. The other surprising thing that I have kind of quite enjoyed, at least for now, is because we bill a little bit differently on this work; we have to track our hours more explicitly. And that has actually helped me focus a lot more on what I'm doing and if I should continue to be doing what I'm doing. I'm timeboxing things a lot more because I know that if there is a ceiling on the number of hours, I want to make sure that that time is spent in the most valuable way. And I also really enjoy, like, the boundaries of timeboxing, yes, but also, like, the tasks are usually scoped pretty narrowly so that they are things that you can accomplish, definitely in the week, because you don't know if you'll kind of still be working for this client next week but even more so, like, within a few days. And that is nice because I can kind of, like, you know, track my hours, finish the task, and then feel a little bit more free to go do something else without being, like, okay, like, what's the next thing that I need to be doing? There's a little bit more freedom, I think, when you're kind of, like, optimizing towards, like, finishing each item. JOËL: Do the stories of the work that you have to do does it typically come kind of pre-scoped? Are you involved in making sure that it has, like, very aggressive scoping? STEPHANIE: Yeah. So far, I've not been involved in doing the scoping work, and it has come pre-scoped, which has been nice. This was also, again, just different. Because I was on a client team previously, a lot of the work to be done was the disambiguating, the, like, figuring out what to be doing. Whereas here, because, again, we're kind of optimized for people coming in and out, if there is uncertainty or lack of clarity, it's pointed out early, and someone is like, "Okay, I will take care of this. Like, I'll take the lead on this so that it can be handed off." One client that I'm working on is using Basecamp's Shape Up methodology, which I actually hadn't worked with in a very explicit way before. And that has been interesting to learn about a little bit, too. One thing that I have enjoyed about it is instead of sprints, they're called cycles. And I like that a lot because, you know, sprints kind of have the connotation of, like, you're running as fast as you can but also, like, you can't run that way forever [laughs]. And so, even that, like, little bit of rewording change is really nice. The variable part is scope, right? It's we're focused on delivering something completely and very intentionally cutting scope as kind of the main lever. JOËL: How do you maintain sort of focus and flow if you're jumping across multiple clients? Because you said, you work with multiple clients as part of this team. And I feel like I can get a little bit frustrated sometimes, even just jumping between, like, tickets within one project. And so, I could imagine that jumping between different clients during the week or even the day might be really disruptive. Have you found techniques to help you stay in the flow? STEPHANIE: Yeah, that is a tough one because, also, every client has their different application; you then have to start up on [laughs] your local machine, and that is kind of annoying. You know, I do still tend to kind of, like, bundle similar work together. If, like, there's a few things I can do for a client on one day, I'll make sure to focus on that. But what I mentioned earlier about, like, seeing something to completion has been really, I want to say, fun even. Because it then kind of, like, frees up that mental space of, like, okay, I don't have to, like, have this thing that I'm working on lingering in my head about, like, oh, did I forget to do something? Or, you know, have, like, shower thoughts of like, oh, I just thought of a new way to implement this [laughs] feature because it doesn't spill over as much as maybe larger initiatives anyway. And so, I am context-switching, but it's only kind of after I've gotten something to a good place where I've left all of the notes. And that's another thing that I'm now kind of compelled to do a little more actively. It's like, every single day, I'm kind of making sure that the work that I've done has been reported on, one, because I have to track my hours, so, you know, and I sometimes leave notes about what that time was spent on doing. And also, when the expectation is that someone else will be picking up, then there's no, like, oh, like, let me hold on to this, and only when I know that I have to hand off something that's when I'll do the, like, dedicated knowledge dumping. It's kind of just built into the process a little more frequently. JOËL: So, you're setting up for, like, an imminent vacation factor. STEPHANIE: Yeah. Which I kind of like because then I can take a vacation [laughs] whenever I want and not have to worry too much about, oh, did I do everything I needed to do before I leave? JOËL: So, you know, these practices that you're doing are specifically adapted for the style of work that you have. Are there any that you think you would bring to your own practice if you ever rotated back on to a dedicated client project, anything that you would do there that you would want to include from your practice here? STEPHANIE: Yeah. It does sound kind of weird because part of what's nice about being on a full-time team is that there is less, oh, if I don't get something done today, I have tomorrow to do it [laughs]. And it seems like that would be like, oh, like, kind of take the pressure off a little bit. But I would be really curious to continue having, like, such an intense awareness about how I'm spending my time. Because I've certainly gotten a little bit lax on, like, full-time development work when you just go down a rabbit hole [laughs] and you come out, like, three hours later, and you're like, "What did I just do?" [laughs] And, you know, maybe that's what needed to be done, and that's fine. But if you have the information that it took you three hours, you can at least make a better-informed decision about, like, oh, maybe I should have stopped a little earlier or, like, yeah, it took about three hours, and that's okay. I think that would be an interesting area to incorporate and to be able to report more frequently. And I also like to know how other people spend their time, too. So, just, like, that sharing of information would also be really beneficial even to, like, a team. JOËL: What about the more aggressive documentation? Is that something that...because that can be really time-consuming, I imagine, as well. Is that something that you would value in a kind of, more focused full-time project context? STEPHANIE: Yeah. One part I've enjoyed about it is that I'm documenting, like, decision-making a lot more actively where, you know, I'm kind of, like, surfacing to be like, hey, here's the outcomes of, like, my research. We're not as, you know, embedded in the business, and we don't have as much of that, like, context and knowledge about what the best solutions are all the time. I'm documenting all of that, you know, usually, for the client stakeholder to be like, "Hey, here's my recommendations, like, how do you want to...what do you think is the best way to go? On one hand, it's kind of nice not to have to, like, be solely responsible for making that decision, right? And I'm kind of, like, leaning on, like, hey, like, you're the expert of your application and your product, you know, here's what I've learned. And now I've, like, put this all, like, for you and presented it to you. And I think that, for me, has gotten lost sometimes when I end up being the same person of, like, doing the research and then deciding, and it just kind of ends up being held in my head. And that, I think, is something really important to document, even if it's just for other people to, like, see how that process might work or, like, what things I already considered or didn't try. That exercise, I think, can be really important. So, so far, the documentation has not necessarily been, like, code level, but more, like, for each task, it's, like, showing your work, right? And not in a, like, you're being monitored [laughs] sort of way but in a way that supports it getting done with a lot of that turnover. JOËL: It's almost like a mini report that you're doing. So, you'd mentioned, for example, an application running into memory problems on Heroku. It sounds like you would then go maybe investigate that and then make some recommendations on whether they need to increase some dynos or maybe make some internal changes. It sounds like you may or may not be the one to execute those changes. But you would write up some, like, a mini report and submit that to the client, and then they can make their own execution choices. STEPHANIE: Yeah, exactly. And they can execute it themselves or then create a new ticket for the next person rotating on to support and maintenance to tackle it in a different cycle. JOËL: So, support and maintenance doesn't just do the investigation. Your team might do the execution as well. It's just that the sort of more research-y stuff and the execution stuff gets split out into different tickets because it's so tightly scoped. STEPHANIE: Yeah, that sounds right. JOËL: I like that. STEPHANIE: One area that I wasn't sure that I was going to like so much about this kind of work is, you know, when you're not kind of embedded on a team, I was thinking that I might not feel as connected, or I would miss a bit of that getting to know people and just, like, seeing people face to face on a daily basis. I'm still evaluating how that would go so far because it has definitely been, like, mostly asynchronous communication, you know, which is what works well for this type of the style of team or project. But I think what has been helpful is realizing that, like, oh yeah, like, I can also get that elsewhere, you know, with thoughtbot folks like with you doing this podcast every week. And right now, there are, like, two Boost members who are doing support and maintenance full time, and folks who are unbooked kind of come in and out. And I can see that there's still a team. So, it's not nearly as kind of, like, isolating as what I had thought it would be. JOËL: There's something that's really curious to me, I think, sitting at the intersection of the idea of fostering more team interactions and the sort of, like, mini reports that you write. And that's that I would love to see more sharing among all of us at thoughtbot about different interesting problems that we've had to solve or that we're tackling on different client work. Because I think in that case, it's a situation where we all just learn something, you know, maybe I've never had to deal with a memory leak or might not even have an idea of, like, how to approach memory issues on Heroku. So, seeing your little mini report, if you'd maybe share that, and, you know, maybe it can be anonymized in some way if needs to, I think would be really nice, at the very least, something that could be done, like, internally. So, I almost wonder if, like, building that practice of, you know, maybe not for every ticket that I do because, you know, I don't want to just be dumping my tickets in the thoughtbot Slack. But I run into something interesting and be like, oh, let me tell a little story about this and do a little write-up. That might be something that's good for the whole team and not just for folks who are on support and maintenance. STEPHANIE: Yeah, absolutely. As you were saying that, I was thinking about how it does kind of encourage me to find support outside of my, like, immediate team, right? Because I don't necessarily have one with the client and to, I don't know, I'm imagining, like, these roots growing in terms of different communities I'm a part of and bringing those problems just outside of my internal world, and kind of getting that outside feedback because by necessity a little bit, right? But also, with the added benefit of, you know, I think that's also how a lot of people end up writing content that gets shared with the world. So, I had the misconception that I would be kind of just, like, on my own off doing things like just tickets and being a little coding robot, but I've been surprised by it feels very fresh and new. So, I think, I guess, I was needing a little bit of that [laughs]. JOËL: I was having a conversation with another thoughtboter recently about how valuable sometimes change can be for its own sake and how that can sort of refresh. You want it just at the rate where you have a chance to build some stability. You don't want chaos. But sometimes change can sort of take you out of a rut, give you energy, maybe sort of restart some good habits that you had sort of let atrophy. And that finding, like, just that right level of shaking things up can really help a team, you know, get their effectiveness to the next level. STEPHANIE: Yeah. I like what you said about good habits, for sure. A couple of other random, little things that I just thought of about what I've liked is, I don't know, maybe this is a little silly. But we, you know, use shared credentials for logging into different services and applications or third parties that clients are using. And that has actually been something that has been so easy [laughs] and very low friction compared to, you know, joining a new project and manually be added as, like, your individual account to all of the different things. And things inevitably get forgotten, and then you have to rely on someone else to do it. And sometimes they don't get back to you [laughs] for a while. The self-serviceness of this work has been cool, too. And I just, yeah, wanted to say that I really appreciated the thought that went into making it as easy as possible to be like, yeah, I can find the credentials here. It is, you know, a bit more anonymized because I'm just using, like, a shared account. JOËL: Like a generic thoughtbot account on a client system rather than stephanie@thoughtbot. STEPHANIE: Yeah, exactly. But I think I saved so much time [laughs] this week just being able to do all of that myself and, you know, knowing where to look first before having to ask. JOËL: I guess you'd need something like that, right? If you're only jumping in on a project for the first time, for a couple of hours or something like that, you don't want to go through a whole onboarding process because that might then, like, easily double. You know, instead of doing two hours on this project, you're now doing four. STEPHANIE: Yeah, exactly. I guess the other takeaway, for me, was like, oh, definitely, if I were to have to set up accounts [laughs] for an application, you know, I've obviously seen where it was like, very clearly, like, the founder having created all these personal accounts for this services, and people are still using their credentials many years later [laughs], even though they probably, like, maybe may not even work for the company anymore. But yeah, the shared credentials and using that generic account that anyone can kind of get into when needed has really lowered the barrier to jump into doing that work, right? And especially because, like you said, it reduces that time. And we're, you know, billing by the hour anyway. So, it's kind of a win-win situation. JOËL: And I totally understand why you would not want something like that for a longer engagement. But for something like support and maintenance, it sounds like it was the right choice. STEPHANIE: Yeah, yeah. Again, I just mentioned it because it's just different. And so, maybe if this sparks any ideas for our listeners about how processes could be different or, like, the styles or ways of working can be different, I think that would be cool. JOËL: And just to be clear here, it sounds like what you're doing is for sort of each client; you create a separate set of credentials that are for that client but that are about thoughtbot generically. You don't have, like, one thoughtbot email and password that we reuse for every client. STEPHANIE: [laughs] Oh yes. That would be not so good [laughs] if we got hacked and suddenly, now they have access to everything. JOËL: So, every client gets its own unique email password combo. We're using security best practices here. And then, since you do have to share them through a team, are you doing some sort of, like, shared 1Password vault or something along those lines? STEPHANIE: Yeah, we are using a shared 1Password vault. That is definitely what I meant [laughs] the first time when I was mentioning the shared credentials, where that was basically the only thing I had to get onboarded to, the vault, for support and maintenance to be able to hit the ground running. JOËL: So, this sounds like a pretty exciting new style of project for you. Is this something that you would see yourself preferring to do longer term, to sort of focus on this style of project? Or do you think that you'd like to come back to more classic project work in the near future? STEPHANIE: I'm not sure yet, but I'm also hoping to have an answer to that question. And it definitely does feel like an experiment for me personally. I can see liking it, and that also fitting well with some of my longer-term goals of being able to, like, step back from work. Maybe working fewer days a week is something that I've, like, thought about in terms of, like, a long-term goal of mine because I'm not as needed [laughs] on a team. Which I think, in the past, I also had a bit of a misconception that, like, in order to be a good developer, I had to have all the domain knowledge, and be indispensable, and, like, be the go-to person to answer all the questions. But now I'm at a point where I don't want to [laughs] necessarily have to answer, like, every question because that creates, like, a dependency on me. And if I need to step away from work, then that could be tough, right? The vacation factor that you mentioned. So, this style of work is very interesting in terms of if it might provide me a little bit more of that, not exactly work-life balance, but just kind of be closer to my goals in terms of what I want out of work and my time. And, hopefully, I'm going to be doing this next week, but I don't know because that's the nature of it [laughs]. But if I am, then I'll definitely have more to say about it. Probably. JOËL: Well, it definitely sounds like we'll have to check in again on what's, I guess, not so new in your world on a future episode. On that note, shall we wrap up? STEPHANIE: Let's wrap up. Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeee!!!!!! AD: Did you know thoughtbot has a referral program? If you introduce us to someone looking for a design or development partner, we will compensate you if they decide to work with us. More info on our website at: tbot.io/referral. Or you can email us at referrals@thoughtbot.com with any questions.

The Bike Shed
408: Work Device Management

The Bike Shed

Play Episode Listen Later Nov 28, 2023 32:57


Joël recaps his time at RubyConf! He shares insights from his talk about different aspects of time in software development, emphasizing the interaction with the audience and the importance of post-talk discussions. Stephanie talks about wrapping up a long-term client project, the benefits of change and variety in consulting, and maintaining a balance between project engagement and avoiding burnout. They also discuss strategies for maintaining work-life balance, such as physical separation and device management, particularly in a remote work environment. Rubyconf (https://rubyconf.org/) Joël's talk slides (https://speakerdeck.com/joelq/which-time-is-it) Flaky test summary slide (https://speakerdeck.com/aridlehoover/the-secret-ingredient-how-to-understand-and-resolve-just-about-any-flaky-test?slide=170) Transcript: STEPHANIE: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Stephanie Minn. JOËL: And I'm Joël Quenneville. And together, we're here to share a bit of what we've learned along the way. STEPHANIE: So, Joël, what's new in your world? JOËL: Well, as of this recording, I have just gotten back from spending the week in San Diego for RubyConf. STEPHANIE: Yay, so fun. JOËL: It's always so much fun to connect with the community over there, talk to other people from different companies who work in Ruby, to be inspired by the talks. This year, I was speaking, so I gave a talk on time and how it's not a single thing but multiple different quantities. In particular, I distinguish between a moment in time like a point, a duration and amount of time, and then a time of day, which is time unconnected to a particular day, and how those all connect together in the software that we write. STEPHANIE: Awesome. How did it go? How was it received? JOËL: It was very well received. I got a lot of people come up to me afterwards and make a variety of time puns, which those are so easy to make. I had to hold myself back not to put too many in the talk itself. I think I kept it pretty clean. There were definitely a couple of time puns in the description of the talk, though. STEPHANIE: Yeah, absolutely. You have to keep some in there. But I hear you that you don't want it to become too punny [laughs]. What I really love about conferences, and we've talked a little bit about this before, is the, you know, like, engagement and being able to connect with people. And you give a talk, but then that ends up leading to a lot of, like, discussions about it and related topics afterwards in the hallway or sitting together over a meal. JOËL: I like to, in my talks, give little kind of hooks for people who want to have those conversations in the hallway. You know, sometimes it's intimidating to just go up to a speaker and be like, oh, I want to, like, dig into their talk a little bit. But I don't have anything to say other than just, like, "I liked your talk." So, if there's any sort of side trails I had to cut for the talk, I might give a shout-out to it and say, "Hey, if you want to learn more about this aspect, come talk to me afterwards." So, one thing that I put in this particular talk was like, "Hey, we're looking at these different graphical ways to think about time. These are similar to but not the same as thinking of time as a one-dimensional vector and applying vector math to it, which is a whole other side topic. If you want to nerd out about that, come find me in the hallway afterwards, and I'd love to go deeper on it." And yeah, some people did. STEPHANIE: That's really smart. I like that a lot. You're inviting more conversation about it, which I know, like, you also really enjoy just, like, taking it further or, like, caring about other people's experiences or their thoughts about vector math [laughs]. JOËL: I think it serves two purposes, right? It allows people to connect with me as a speaker. And it also allows me to feel better about pruning certain parts of my talk and saying, look, this didn't make sense to keep in the talk, but it's cool material. I'd love to have a continuing conversation about this. So, here's a path we could have taken. I'm choosing not to, as a speaker, but if you want to take that branch with me, let's have that afterwards in the hallway. STEPHANIE: Yeah. Or even as, like, new content for yourself or for someone else to take with them if they want to explore that further because, you know, there's always something more to explore [chuckles]. JOËL: I've absolutely done that with past talks. I've taken a thing I had to prune and turned it into a blog post. A recent example of that was when I gave a talk at RailsConf Portland, which I guess is not so recent. I was talking about ways to deal with a test suite that's making too many database requests. And talking about how sometimes misusing let in your RSpec tests can lead to more database requests than you expect. And I had a whole section about how to better understand what database requests will actually be made by a series of let expressions and dealing with the eager versus lazy and all of that. I had to cut it. But I was then able to make a blog post about it and then talk about this really cool technique involving dependency graphs. And that was really fun. So, that was a thing where I was able to say, look, here's some content that didn't make it into the talk because I needed to focus on other things. But as its own little, like, side piece of content, it absolutely works, and here's a blog post. STEPHANIE: Yeah. And then I think it turned into a Bike Shed episode, too [laughs]. JOËL: I think it did, yes. I think, in many ways, creativity begets creativity. It's hard to get started writing or producing content or whatever, but once you do, every idea you have kind of spawns new ideas. And then, pretty soon, you have a backlog that you can't go through. STEPHANIE: That's awesome. Any other highlights from the conference you want to shout out? JOËL: I'd love to give a shout-out to a couple of talks that I went to, Aji Slater's talk on the Enigma machine as a German code machine from World War II and how we can sort of implement our own in Ruby and an exploration of object-oriented programming was fantastic. Aji is just a masterful storyteller. So, that was really great. And then Alan Ridlehoover's talk on dealing with flaky tests that one, I think, was particularly useful because I think it's one of the talks that is going to be immediately relevant on Monday morning for, like, every developer that was in that room and is going back to their regular day job. And they can immediately use all of those principles that Alan talked about to deal with the flaky tests in their test suite. And there's, in particular, at the end of his presentation, Alan has this summary slide. He kind of broke down flakiness across three different categories and then talked about different strategies for identifying and then fixing tests that were flaky because of those reasons. And he has this table where he sort of summarizes basically the entire talk. And I feel like that's the kind of thing that I'm going to save as a cheat sheet. And that can be, like, I'm going to link to this and share it all over because it's really useful. Alan has already put his slides up online. It's all linked to that particular slide in the show notes because I think that all of you would benefit from seeing that. The talks themselves are recorded, but they're not going to be out for a couple of weeks. I'm sure when they do, we're going to go through and watch some and probably comment on some of the talks as well. So, Stephanie, what is new in your world? STEPHANIE: Yeah. So, I'm celebrating wrapping up a client project after a nine-month engagement. JOËL: Whoa, that's a pretty long project. STEPHANIE: Yeah, that's definitely on the longer side for thoughtbot. And I'm, I don't know, just, like, feeling really excited for a change, feeling really, you know, proud of kind of, like, all of the work that we had done. You know, we had been working with this client for a long time and had been, you know, continuing to deliver value to them to want to keep working with us for that long. But I'm, yeah, just looking forward to a refresh. And I think that's one of my favorite things about consulting is that, you know, you can inject something new into your work life at a kind of regular cadence. And, at least for me, that's really important in reducing or, like, preventing the burnout. So, this time around, I kind of started to notice, and other people, too, like my manager, that I was maybe losing a bit of steam on this client project because I had been working on it for so long. And part of, you know, what success at thoughtbot means is that, like, we as employees are also feeling fulfilled, right? And, you know, what are the different ways that we can try to make sure that that remains the case? And kind of rotating folks on different projects and kind of making sure that things do feel fresh and exciting is really important. And so, I feel very grateful that other people were able to point that out for me, too, when I wasn't even fully realizing it. You know, I had people checking in on me and being like, "Hey, like, you've been on this for a while now. Kind of what I've been hearing is that, like, maybe you do need something new." I'm just excited to get that change. JOËL: How do you find the balance between sort of feeling fulfilled and maybe, you know, finding that point where maybe you're feeling you're running out of steam–versus, you know, some projects are really complex, take a while to ramp up; you want to feel productive; you want to feel like you have contributed in a significant way to a project? How do you navigate that balance? STEPHANIE: Yeah. So, the flip side is, like, I also don't think I would enjoy having to be changing projects all the time like every couple of months. That maybe is a little too much for me because I do like to...on our team, Boost, we embed on our team. We get to know our teammates. We are, like, building relationships with them, and supporting them, and teaching them. And all of that is really also fulfilling for me, but you can't really do that as much if you're on more shorter-term engagements. And then all of that, like, becomes worthwhile once you're kind of in that, like, maybe four or five six month period where you're like, you've finally gotten your groove. And you're like, I'm contributing. I know how this team works. I can start to see patterns or, like, maybe opportunities or gaps. And that is all really cool, and I think also another part of what I really like about being on Boost. But yeah, I think what I...that losing steam feeling, I started to identify, like, I didn't have as much energy or excitement to push forward change. When you kind of get a little bit too comfortable or start to get that feeling of, well, these things are the way they are [laughs], -- JOËL: Right. Right. STEPHANIE: I've now identified that that is kind of, like, a signal, right? JOËL: Maybe time for a new project. STEPHANIE: Right. Like starting to feel a little bit less motivated or, like, less excited to push myself and push the team a little bit in areas that it needs to be pushed. And so, that might be a good time for someone else at thoughtbot to, like, rotate in or maybe kind of close the chapter on what we've been able to do for a client. JOËL: It's hard to be at 100% all the time and sort of always have that motivation to push things to the max, and yeah, variety definitely helps with that. How do you feel about finding signals that maybe you need a break, maybe not from the project but just in general? The idea of taking PTO or having kind of a rest day. STEPHANIE: Oh yeah. I, this year, have tried out taking time off but not going anywhere just, like, being at home but being on vacation. And that was really great because then it was kind of, like, less about, like, oh, I want to take this trip in this time of year to this place and more like, oh, I need some rest or, like, I just need a little break. And that can be at home, right? Maybe during the day, I'm able to do stuff that I keep putting off or trying out new things that I just can't seem to find the time to do [chuckles] during my normal work schedule. So, that has been fun. JOËL: I think, yeah, sometimes, for me, I will sort of hit that moment where I feel like I don't have the ability to give 100%. And sometimes that can be a signal to be like, hey, have you taken any time off recently? Maybe you should schedule something. Because being able to refresh, even short-term, can sort of give an extra boost of energy in a way where...maybe it's not time for a rotation yet, but just taking a little bit of a break in there can sort of, I guess, extend the time where I feel like I'm contributing at the level that I want to be. STEPHANIE: Yeah. And I actually want to point out that a lot of that can also be, like, investing in your life outside of work, too, so that you can come to work with a different approach. I've mentioned the month that I spent in the Hudson Valley in New York and, like, when I was there, I felt, like, so different. I was, you know, just, like, so much more excited about all the, like, novel things that I was experiencing that I could show up to work and be like, oh yeah, like, I'm feeling good today. So, I have all this, you know, energy to bring to the tasks that I have at work. And yeah, so even though it wasn't necessarily time off, it was investing in other things in my life that then brought that refresh at work, even though nothing at work really changed [laughs]. JOËL: I think there's something to be said for the sort of energy boost you get from novelty and change, and some of that you get it from maybe rotating to a different project. But like you were saying, you can change your environment, and that can happen as well. And, you know, sometimes it's going halfway across the country to live in a place for a month. I sometimes do that in a smaller way by saying, oh, I'm going to work this morning from a coffee shop or something like that. And just say, look, by changing the environment, I can maybe get some focus or some energy that I wouldn't have if I were just doing same old, same old. STEPHANIE: Yeah, that's a good point. So, one particularly surprising refresh that I experienced in offboarding from my client work is coming back to my thoughtbot, like, internal company laptop, which had been sitting gathering dust [laughs] a little bit because I had a client-issued laptop that I was working in most of the time. And yeah, I didn't realize how different it would feel. I had, you know, gotten everything set up on my, you know, my thoughtbot computer just the way that I liked it, stuff that I'd never kind of bothered to set up on my other client-issued laptop. And then I came back to it, and then it ended up being a little bit surprising. I was like, oh, the icons are smaller on this [laughs] computer than the other computer. But it definitely did feel like returning to home, I think, instead of, like, being a guest in someone else's house that you haven't quite, like, put all your clothes in the closet or in the drawers. You're still maybe, like, living out of a suitcase a little bit [laughs]. So yeah, I was kind of very excited to be in my own space on my computer again. JOËL: I love the metaphor of coming home, and yeah, being in your own space, sleeping in your own bed. There's definitely some of that that I feel, I think, when I come back to my thoughtbot laptop as well. Do you feel like you get a different sense of connection with the rest of our thoughtbot colleagues when you're working on the thoughtbot-issued laptop versus a client-issued one? STEPHANIE: Yeah. Even though on my client-issued computer I had the thoughtbot Slack, like, open on there so I could be checking in, I wasn't necessarily in, like, other thoughtbot digital spaces as much, right? So, our, like, project management tools and our, like, internal company web app, those were things that I was on less of naturally because, like, the majority of my work was client work, and I was all in their digital spaces. But coming back and checking in on, like, all the GitHub discussions that have been happening while I haven't had enough time to catch up on them, just realizing that things were happening [laughs] even when I was doing something else, that is both cool and also like, oh wow, like, kind of sad that I [chuckles] missed out on some of this as it was going on. JOËL: That's pretty similar to my experience. For me, it almost feels a little bit like the difference between back when we used to be in person because thoughtbot is now fully remote. I would go, usually, depending on the client, maybe a couple of days a week working from their offices if they had an office. Versus some clients, they would come to our office, and we would work all week out of the thoughtbot offices, particularly if it was like a startup founder or something, and they might not already have office space. And that difference and feeling the connection that I would have from the rest of the thoughtbot team if I were, let's say, four days a week out of a client office versus two or four days a week out of the thoughtbot office feels kind of similar to what it's like working on a client-issued laptop versus on a thoughtbot-issued one. STEPHANIE: Another thing that I guess I forgot about or, like, wasn't expecting to do was all the cleanup, just the updating of things on my laptop as I kind of had it been sitting. And it reminded me to, I guess, extend that, like, coming home metaphor a little bit more. In the game Animal Crossing, if you haven't played the game in a while because it tracks, like, real-time, so it knows if you haven't, you know, played the game in a few months, when you wake up in your home, there's a bunch of cockroaches running around [laughs], and you have to go and chase and, like, squash them to clean it up. JOËL: Oh no. STEPHANIE: And it kind of felt like that opening my computer. I was like, oh, like, my, like, you know, OS is out of date. My browsers are out of date. I decided to get an internal company project running in my local development again, and I had to update so many things, you know, like, install the new Ruby version that the app had, you know, been upgraded to and upgrade, like, OpenSSL and all of that stuff on my machine to, yeah, get the app running again. And like I mentioned earlier, just the idea of like, oh yeah, this has evolved and changed, like, without me [laughs] was just, you know, interesting to see. And catching myself up to speed on that was not trivial work. So yeah, like, all that maintenance stuff still got to do it. It's, like, the digital cleanup, right? JOËL: Exactly. So, you mentioned that on the client machine, you still had the thoughtbot Slack. So, you were able to keep up at least some messages there on one device. I'm curious about the experience, maybe going the other way. How much does thoughtbot stuff bleed into your personal devices, if at all? STEPHANIE: Barely. I am very strict about that, I think. I used to have Slack on my phone, I don't know, just, like, in an earlier time in my career. But now I have it a rule to keep it off. I think the only thing that I have is my calendar, so no email either. Like, that is something that I, like, don't like to check on my personal time. Yeah, so it really just is calendar just in case I'm, like, out in the morning and need to be, like, oh, when is my first meeting? But [laughs] I will say that the one kind of silly thing is that I also refuse to sign into my Google account for work. So, I just have the calendar, like, added to my personal calendar but all the events are private. So, I can't actually see what the events are [laughs]. I just know that I have something going on at, like, 10:00 a.m. So, I got to make sure I'm back home by then [laughs], which is not so ideal. But at the risk of being signed in and having other things bleed into my personal devices, I'm just living with that for now [laughs]. JOËL: What I'm hearing is that I could put some mystery events on your calendar, and you would have a fun surprise in the morning because you wouldn't know what it is. STEPHANIE: Yeah, that is true [laughs]. If you put, like, a meeting at, like, 8:00 a.m., [laughs] then I'm like, oh no, what's this? And then I arrive, and it's just, like [laughs], a fun prank meeting. So, you know, you were talking about how you were at the conference this week. And I'm wondering, how connected were you to work life? JOËL: Uh, not very. I tried to be very present in the moment at the conference. So, I'm, you know, connected to all the other thoughtboters who were there and connecting with the attendees. I do have Slack on my phone, so if I do need to check it for something. There was a little bit of communication that was going on for different things regarding the conference, so I did check in for that. But otherwise, I tried to really stay focused on the in-person things that are happening. I'm not doing any client work during those days that I'm at RubyConf, and so I don't need to deal with anything there. I had my thoughtbot laptop with me because that's what I used to give my presentation. But once the presentation was done, I closed that laptop and didn't open it again, and, honestly, that felt kind of good. STEPHANIE: Yeah, that is really nice. I'm the same way, where I try to be pretty connected at conferences, and, like, I will actually redownload Slack sometimes just for, like, coordinating purposes with other folks who are there. But I think I make it pretty clear that I'm, like, away. You know, like, I'm not actually...like, even though I'm on work time, I'm not doing any other work besides just being present there. JOËL: So, you mentioned the idea of work time. Do you have, like, a pretty strict boundary between personal time and work time and, like, try not to allow either to bleed into each other? STEPHANIE: Yeah. I can't remember if I've mentioned this on the show. I think I have, but I'm going to again because one of my favorite things that I picked up from The Bike Shed back when Chris Toomey and Steph Viccari were hosting the show is Chris had, like, a little ritual that he would do every day to signal that he was done with work. He would close his laptop and say, "Schedule shutdown complete," I think. And I've started adopting it because then it helps me be like, I'm not going to reopen my laptop after this because I have said the words. And even if I think of something that I maybe need to add to my to-do list, I will, instead of opening my computer and adding to my, like, whatever digital to-do list, I will, like, write it down on a piece of paper instead for the sake of, you know, not risking getting sucked back into, you know, whatever might be going on after the time that I've, like, decided that I need to be done. JOËL: So, you have a very strict divisioning between work time and personal time. STEPHANIE: Yeah, I would say so. I think it's important for me because even when I take time off, you know, sometimes folks might work a half day or something, right? I really struggle with having even a half day feel like, once I'm done with work, having that feel like okay, like, now I'm back in my personal time. I'd much prefer not working the entire day at all because that is kind of the only way that I can feel like I've totally reclaimed that time. Otherwise, it's like, once I start thinking about work stuff, it's like I need a mental boundary, right? Because if I'm thinking about a work problem, or, like, an interaction or, like, just anything, it's frustrating because it doesn't feel like time in my own brain [laughs] is my own. What do work and personal time boundaries look like for you? JOËL: I think it's evolved over time. Device usage is definitely a little bit more blurry for me. One thing that I have started doing since we've gone fully remote as the pandemic has been winding down and, you know, you can do things, but we're still working from home, is that more days than not, I work from home during the day, and then I leave my home during the evening. I do a variety of social activities. And because I like to be sort of present in the moment, that means that by being physically gone, I have totally disconnected because I'm not checking emails or anything like that. Even though I do have thoughtbot email on my phone, Gmail allows me to like log into my personal account and my thoughtbot account. I have to, like, switch between the two accounts, and so, that's, like, more work than I would want. I don't have any notifications come in for the thoughtbot account. So, unless I'm, like, really wanting to see if a particular email I'm waiting for has come in, I don't even look at it, ever. It's mostly just there in case I need to see something. And then, by being focused in the moment doing social things with other people, I don't find too much of a temptation to, like, let work life bleed into personal life. So, there's a bit of a physical disconnect that ends up happening by moving out of the space I work in into leaving my home. STEPHANIE: Yeah. And I'm sure it's different for everyone. As you were saying that, I was reminded of a funny meme that I saw a long time ago. I don't think I could find it if I tried to search for it. But basically, it's this guy who is, you know, sitting on one side of the couch, clearly working. And he's kind of hunched over and, like, typing and looking very serious. And then he, like, closes his laptop, moves over, like, just slides to the other side of the couch, opens his laptop. And then you see him, like, lay back, like, legs up on the coffee table. And it's, like, work computer, personal computer, but it's the same computer [laughs]. It's just the, like, how you've decided like, oh, it's time for, you know, legs up, Netflix watching [laughs]. JOËL: Yeah. Yeah. I'm curious: do you use your thoughtbot computer for any personal things? Or is it just you shut that down; you do the closing ritual, and then you do things on a separate device? STEPHANIE: Yeah, I do things on a separate device. I think the only thing there might be some overlap for are, like, career-related extracurriculars or just, like, development stuff that I'm interested in doing, like, separate from what I am paid to do. But that, you know, kind of overlaps a little bit because of, like, the tools and the stuff I have installed on my computer. And, you know, with our investment time, too, that ends up having a bit of a crossover. JOËL: I think I'm similar in that I'll tend to do development things on my thoughtbot machine, even though they're not necessarily thoughtbot-related, although they could be things that might slot into something like investment time. STEPHANIE: Yeah, yeah. And it's because you have all your stuff set up for it. Like, you're not [laughs] trying to install the latest Ruby version on two different machines, probably [laughs]. JOËL: Yeah. Also, my personal device is a Windows machine. And I've not wanted to bother learning how to set that up or use the Windows Subsystem for Linux or any of those tools, which, you know, may be good professional learning activities. But that's not where I've decided to invest my time. STEPHANIE: That makes sense. I had an interesting conversation with someone else today, actually, about devices because I had mentioned that, you know, sometimes I still need to incorporate my personal devices into work stuff, especially, like, two-factor authentication. And specifically on my last client project...I have a very old iPhone [laughs]. I need to start out by saying it's an iPhone 8 that I've had for, like, six or seven years. And so, it's old. Like, one time I went to the Apple store, and I was like, "Oh, I'm looking for a screen protector for this." And they're like, "Oh, it's an iPhone 8. Yikes." [laughs] This was, you know, like, not too long ago [laughs]. And the multi-factor authentication policy for my client was that, you know, we had to use this specific app. And it also had, like, security checks. Like, there's a security policy that it needed to be updated to the latest iOS. So, even if I personally didn't want to update my iOS [laughs], I felt compelled to because, otherwise, I would be locked out of the things that I needed to do at work [laughs]. JOËL: Yeah, that can be a challenge sometimes when you're adding work things to personal devices, maybe not because it's convenient and you want to, but because you don't have a choice for things like two-factor auth. STEPHANIE: Yeah, yeah. And then the person I was talking to actually suggested something I hadn't even thought about, which is like, "Oh, you know, if you really can't make it work, then, like, consider having that company issue another device for you to do the things that they're, like, requiring of you." And I hadn't even thought of that, so... And I'm not quite at the point where I'm like, everything has to be, like, completely separate [laughs], including two-factor auth. But, I don't know, something to consider, like, maybe that might be a place I get to if I'm feeling like I really want to keep those boundaries strict. JOËL: And I think it's interesting because, you know, when you think of the kind of work that we do, it's like, oh, we work with computers, but there are so many subfields within it. And device management and, just maybe, corporate IT, in general, is a whole subfield that is separate and almost a little bit alien. Two, I feel like me, as a software developer, I'm just aware of a little bit...like, I've read a couple of articles around...and this was, you know, years ago when the trend was starting called Bring Your Own Device. So, people who want to say, "Hey, I want to use my phone. I want to have my work email on my phone." But then does that mean that potentially you're leaking company memos and things? So, how do you secure that kind of thing? And everything that IT had to think through in order to allow that, the pros and cons. So, I think we're just kind of, as users of that system, touching the surface of it. But there's a lot of thought and discussion that, as an industry, the kind of corporate IT folks have gone through to struggle with how to balance a lot of those things. STEPHANIE: Yeah, yeah. I bet there's a lot of complexity or nuance there. I mean, we're just talking about, like, ways that we do or don't mix work and personal life. And for that kind of work, you know, that's, like, the job is to think really thoroughly about how people use their devices and what should and shouldn't be permissible. The last thing that I wanted to kind of ask about in terms of device management or, like, work and personal intermixing is the idea of being on call and your device being a way for work to reach you and that being a requirement, right? I feel very lucky to obviously not really be in that position. As consultants, like, we're not usually so embedded into a team that we're then brought into, like, an on-call rotation, and I think that's good for me. Like, I don't think that that is something I'd be interested in doing anytime soon. Do you have any experience with that? JOËL: I have not been on a project where I've had to be on call, and I think that's generally true for most of us at thoughtbot who are doing software development. I know those who are doing more kind of platformy SRE-type things are on call. And, in fact, we have specifically hired people in different regions around the world so that we can provide 24-hour coverage for that kind of thing. STEPHANIE: Yeah. And I imagine kind of like what we're talking about with work device management looks even different for that kind of role, where maybe you do need a lot more access to things, like, wherever you might be. JOËL: And maybe the answer there is you get issued a work-specific device and a work phone or something like that, or an old-school work pager. STEPHANIE: [laughs] JOËL: PagerDuty is not just a metaphoric thing. Back in the day, they used actual pagers. STEPHANIE: Yeah, that would be very funny. JOËL: So yeah, I can't speak to it from personal experience, but I could imagine that maybe some of the dynamics there might be a little bit different. And, you know, for some people, maybe it's fine to just have an app on your phone that pings you when something happens, and you have to be on call. And you're able to be present while waiting, like, in case you get pinged, but also let it go while you're on call. I can imagine that's, like, a really weird kind of, like, shadow, like, working, not working experience that I can't really speak to because I have not been in that position. STEPHANIE: Yeah. As you were saying that, I also had the thought that, like, our ability to step away from work and our devices is also very much dependent on, like, a company culture and those types of factors, right? Where, you know, it is okay for me to not be able to look at that stuff and just come back to it Monday morning, and I am very grateful [laughs] for that. Because I recognize that, like, not everyone is in that position where there might be a lot more pressure or urgency to be on top of that. But right now, for this time in my life, like, that's kind of how I like to work. JOËL: I think it kind of sits at the intersection of a few different things, right? There's sort of where you are personally. It might be a combination, like, personality and maybe, like, mental health, things like that, how you respond to how sharp or blurry those lines between work and personal life can be. Like you said, it's also an element of company culture. If there's a company culture that's really pushing to get into your personal life, maybe you need firmer boundaries. And then, finally, what we spent most of this episode talking about: technical solutions, whether that's, like, physically separating everything such that there are two devices. And you close down your laptop, and you're done for the day. And whether or not you allow any apps on your personal phone to carry with you after you leave for the day. So, I think at the intersection of those three is sort of how you're going to experience that, and every person is going to be a little bit different. Because those three...I guess I'm thinking of a Venn diagram. Those three circles are going to be different for everyone. STEPHANIE: Yeah, that makes complete sense. JOËL: On that note, shall we wrap up? STEPHANIE: Let's wrap up. Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeee!!!!!! AD: Did you know thoughtbot has a referral program? If you introduce us to someone looking for a design or development partner, we will compensate you if they decide to work with us. More info on our website at: tbot.io/referral. Or you can email us at: referrals@thoughtbot.com with any questions.

The Bike Shed
402: Musings on Mentorship

The Bike Shed

Play Episode Listen Later Sep 19, 2023 37:56


Joël describes an old-school object orientation exercise that involves circling nouns in a business problem description. The purpose is determining which nouns could become entities or objects in a system. Stephanie shares she's working from the Hudson Valley in New York as a trial run for potentially relocating there. She enjoys the rail trails for biking and contrasts it with urban biking in Chicago. The conversation between Joël and Stephanie revolves around mentorship, both one-on-one and within a group setting. They introduce a new initiative at thoughbot where team members pair up with principal developers for weekly sessions, emphasizing sharing perspectives and experiences. Socratic method (https://tilt.colostate.edu/the-socratic-method/) Mentorship in 3 Acts by Adam Cuppy (https://www.youtube.com/watch?v=eDX5WH1uLz8) Exercism mentoring (https://exercism.org/mentoring) Transcript: STEPHANIE: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Stephanie Minn. JOËL: And I'm Joël Quenneville. And together, we're here to share a bit of what we've learned along the way. STEPHANIE: So, Joël, what's new in your world? JOËL: I was recently having a conversation with a colleague about some old-school object orientation exercises that people used to do when trying to do more of the analysis phase of software, ones that I haven't seen come up a lot in the past; you know, 5, 10 years. The particular one that I'm thinking about is an exercise where you write out the sort of business problem, and then you go through and you circle all of the nouns in that paragraph. And then, from there, you have a conversation around which one of these are kind of the same thing and are just synonyms? Which ones might be slight variations on an idea? And which ones should become entities in your system? Because, likely, these things are then going to be objects in the system that you're creating. STEPHANIE: Wow, that sounds really cool. I'm surprised that it's considered old school or, I guess, I haven't heard of it before. So, it's not something in my toolbox these days. But I really like that idea. I guess, you know if you're doing it on pen and paper, it's obviously kind of timeless to me. JOËL: And you could easily do it, you know, in a Google Doc and underline, or highlight, or whatever you want to do. But it's not an exercise that I see people really doing even at the larger scale but even at, the smaller scale, where you have maybe a ticket in your ticketing system, and it has a paragraph there kind of describing what needs to be done. We tend to just kind of jump into, oh, we're going to build a story and do the work and maybe not always think about what are the entities that need to happen out of that. STEPHANIE: I think the other thing that I really like about this idea is the aligning on shared vocabulary. So, if you find yourself using different words for the same idea, is that an opportunity to pick the vocabulary that best represents what this means? Rather than a situation that I often find myself in, where we're all talking about the same things but using different words and sometimes causing a little bit more confusion than I think is necessary. JOËL: Definitely. It can also be a good opportunity to connect with the product or businesspeople around; hey, here are two words that sound like they're probably meaning the same thing. Is there a distinction in your business? And then, you realize, wait a minute, a shopping cart and an order actually do have some slight differences. And now you can go into those. And that probably sparks some really valuable learning about the problem that you're trying to solve that might not come up otherwise, or maybe that only comes up at code review time, or maybe even during the QA phase rather than during the analysis phase. STEPHANIE: Yeah. I think that's really important for us as developers because, as we know, naming is often the hardest part of writing code, right? And, you know, at that point, you are making that decision or that distinction between maybe a couple of different terms that you're using to describe an idea and putting that down then will continue on to be read. And just propagating that down the line of, is this name actually what we mean? Or maybe we are using words that, at this lower level, make more sense, but when interacting or communicating with business stakeholders or product folks, they are using a different term. And I really like the idea of that activity being a cross-functional one where you can kind of agree on how to move forward there. Because lately, I've been finding myself oftentimes using both words where the product folks are describing it this way, and then we've, on the engineering side, have decided that, okay, we're actually going to call our database table this other thing, and now having to type out both [chuckles] meanings each time because I know that my audience is in both camps. JOËL: Yeah. There's, I think, a lot of value in using the business terms where possible. If you don't use them, there has to be a good reason. There's a slight distinction for the technical term. We're using it to say, hey, it's different from the business idea in interesting ways that only matter to the dev team. STEPHANIE: Is there a name for this activity? JOËL: I don't know, just circling nouns or underlining nouns. STEPHANIE: Cool. Maybe we can come up with something. [laughs] Or someone else can tell us if they know what this kind of exercise is called. JOËL: Gotta name the naming activity. So, how about you, Stephanie, what's new in your world? STEPHANIE: So, I have a pretty exciting life development to share. I am currently working from a different location than my home in Chicago. I'm in the Hudson Valley in New York for the next month because my partner and I are considering moving out here. And we are just kind of looking for a different pace of life a little bit. And we are taking this month as a trial run to see if we want to, you know, be out here permanently. And I've been having a great time so far. One thing that I've really enjoyed is all of the rail trails out here. So, a lot of old railroad tracks have been repurposed for outdoor recreation, and they are great for biking, or running, or even just walking. And I've been able to hop on my bike, you know, and bike a few minutes, and then I'm on the trail and just kind of surrounded by trees and forests. And that's been really nice because I missed having access to nature kind of, like, right outside my door. JOËL: So, you used to do quite a bit of urban biking in Chicago. But it sounds like now you're getting a chance to do more kind of nature biking. STEPHANIE: Yeah, it's a big difference for me because urban biking was always pretty rough or a little scary just, you know, having to bike with traffic. And I got a lot better at it. But now I'm, you know, biking completely off the roads. And I don't have to worry too much about cars. And I can, you know, just enjoy the fresh air around me and just be a lot more relaxed, I think, than I was able to when I was commuting in the city. JOËL: So, here's the real question. At this new location that you're staying at, do you have a bike shed? STEPHANIE: Not yet. But we now could have a bike shed because there's a lot more space out here, too. So, I could theoretically have my bike shed in my nice, big yard right next to my garden. And these are all [laughs] the hopes and dreams I have for my future life. JOËL: Before you build the bike shed, you can have six months of discussion about what color you want to paint it. STEPHANIE: Yeah, that's why I have this podcast, actually. [laughter] So, look out for that in what's new in my world is considering paint colors for a theoretical future bike shed in a place where I yet don't live. JOËL: You're going to become an expert in the Pantone color palettes. STEPHANIE: I hope so. That would be a great addition to my title. So, another thing that's new in both of our shared worlds is a new initiative on Boost, the team we're on, that you have been involved in. It's pairing sessions with the principal developer. JOËL: Yes. So myself and, another principal developer at thoughtbot have been doing weekly pairing sessions, where we take Tuesday afternoons and pair with one of the other members of the team on their client project doing whatever. So, it's not, a, like, pull someone in when you need help or anything that's more kind of targeted in that way. It's more of a you sign up for this ahead of time. And you just know that on this week, you get someone to pair with you who can hopefully bring in a different perspective a lot of experience, and pair with you on your particular project. STEPHANIE: Yeah. I'm so excited about this initiative because I've not been staffed on a project with you before or the other principal developer who's involved. And I have really wanted to work with you all and be able to learn from you. And I think this is a really cool way to make that expertise more accessible if you just don't happen to be working on a project together. JOËL: Yeah. One of the challenges I think of the principal role is that we want it to be a role that has a high impact on the team as a whole. But also, we are people who can be staffed on pretty much any client project that gets thrown at us and can easily be staffed on projects that require solo work. Whereas there are some teammates who I think it's the developer position that we guarantee they're never staffed solo. And so, that can often mean that our principals get staffed on to the really technically challenging problems or the solo problems, but then there's maybe not as much room to have interactions with the rest of the team on a day-to-day basis. STEPHANIE: Yeah. I think the key word you said that had me nodding my head was impact. And I'm curious what your hopes are for this effort and what kind of impact you want to be having for our team. JOËL: I think it's impact on a few different levels, definitely some form of knowledge sharing. Myself and the other principal developer have decade plus experience each in the field, have deep knowledge in a lot of different things like test-driven development, object modeling, security, things like that that build on top of kind of more basic developer skills that we all have. And those are all, I think, great ways that we can support our team if there's any interest in those particular skills or if they come up on a particular project. And knowledge sharing works both ways, right? I think anytime you're pairing with someone else, there's an opportunity to learn on both sides. And so, I think a really important thing when you're pairing with someone, even if you're kind of maybe more explicitly the mentor figure, is to kind of keep that open mind and look for not only what can I give, how can I teach, but what can I learn from this other person? STEPHANIE: Yeah, absolutely. I guess I'm wondering...and I know this is a pretty new programming so far, but is there anything you've learned or anything that surprised you that you weren't expecting when you, you know, first conceived of the idea based on how it's been going? JOËL: Something that really surprised me, there's some feedback I got after one of the pairing sessions, where this colleague who we'd paired together...and I felt like I hadn't contributed a ton, like, this colleague just really had it and was just kind of going through and doing things. So, I was kind of, like, leaving that pairing session being like, oh, I don't know if I added a ton of value here. And then, this colleague reached out to me and said, "Oh, you know, I felt, like, this huge boost of confidence because we were pairing together, and you were just kind of nodding along and basically saying yes to all of my choices." And I hadn't really considered that that can be a really valuable aspect of this sort of pairing. Sometimes you know the right thing to do, like, you've got it. But it's really easy to second-guess yourself. And just having someone along to, you know, give you that thumbs of like, yeah, this is the thing to do, can give you that confidence boost and kind of keep you moving in a way that feels really positive. STEPHANIE: Wow. I love that. That's really powerful, and I get that. Because, you know, obviously, it's very valuable to have your colleagues help generate different ideas that you might not have considered. But that validation can be really useful. And, you know, that's just not something you get when with a rubber duck. [laughs] The rubber duck can't respond, and [laughs] nod along. So, I think that's really cool that you were able to provide some of that confidence. And, in fact, I think that is contributing to their growth, right? In terms of helping identify, you know, those aspects that they're already really strong at, as well as developing that relationship so they know you're available to them next time if they do need someone to either do that invalidating or validating of an idea. JOËL: Yeah, there's a lot of power, I think, in kind of calling out people's strength and providing validation in a way that can really help someone get to the next level in their career. And it feels like such a simple thing. But yeah, sometimes you can have the biggest impact not by kind of going in and helping but just kind of maybe, like, standing back a little bit and giving someone a thumbs up. So, definitely one of the biggest surprises or, I think, one of the biggest lessons learned for me in the past few weeks of doing this. STEPHANIE: That's very cool. JOËL: So, Stephanie, you've also been doing some pairing or some mentoring from what I hear. STEPHANIE: Yeah. So, on my current client work, I have been pairing with a new hire on my client team who recently graduated from college. And this is his first job in software development. And I have been thinking and learning a lot through this experience because one of my goals was to get better at coaching, specifically the idea of asking guiding questions to help someone, you know, arrive at their own solution instead of, you know, making the suggestions myself or kind of dictating where to go. And this has kind of been a progression for me of kind of starting from, well, you know, I have the way that I want to do it. And the person I'm working with who maybe has less experience, like, they might not know where to go. So, we're just going to go along with my idea. And then the next step was offering a few different ideas, like a menu of options and kind of having that discussion about which way to go. And now, I really wanting to practice letting someone else lead entirely and helping them start thinking about the right things but ultimately not giving them the answer. But hopefully, like, the questions I've been asking means that they are able to get to a well-informed answer where they've thought through some of the things that I would think about if I were in the position of making the decision or figuring out how to implement. JOËL: Is this mostly asking questions to get them to think about edge cases, or is this, like, a Socratic approach to teaching? STEPHANIE: Could you describe Socratic approach for me? JOËL: So, the Socratic approach is a teaching approach that is question-based, where you kind of help the student come to the conclusions themselves by answering questions rather than by telling them the answer. STEPHANIE: Oh, interesting. I think a little bit of both. Where it's true, I am able to see some edge cases that folks with less experience might not consider because they just haven't had to run into them before or fight the fires when [laughs] their code in production ends up being a big issue or causes a bug. But I think that's just part of the work where there is kind of, like, a default dynamic that might be fallen into when two people are working together, and their experience levels differ, where the person who has less experience is wanting to lean on the more senior person to tell them where to go, or to expect to be in that position of just learning from them and not necessarily doing as much of the active thinking. But I was really interested in flipping that and doing a bit of a role reversal because I think it can be really impactful and, you know, help folks earlier in their career, like, really level up even more quickly than just watching, but actually doing. And so, the questions I've been asking have been a lot more open-ended in terms of, like, asking, "What do you think about this code that we're looking at?" Or, like, "Where do you want to go next?" And based on, you know, their answers, digging in a little more, and, at the end, maybe, like, giving that validation that we were talking about earlier. I was like, "Great. Like, I think that's a great path forward," or, "I think that's a good idea to spend our time on right now." But the open-ended questions, I think, are also ones that I also would have liked when I was in that position of learning, where having someone trust that I could draw on my past experience but, like, also knowing that they were there to support and maybe orient me if I ended up straying too far off the path. JOËL: How have you navigated situations where maybe you're asking a question about "What do you want to do next?" and they pick something that maybe would work but is not your sort of preferred approach, or maybe something that seems like it would work well enough but, you know, there's maybe a better approach? How do you navigate that? Do you let them take their approach and maybe kind of let them run into some of the edge cases and problems and then say, "Hey, let me show you something new"? Do you probe a little bit earlier? Or do you say, "Hey, that's good, but why don't we try my way"? How do you navigate that kind of situation? STEPHANIE: That is so hard. It's really challenging. Because if you kind of know that there's maybe a more effective way, or a cleaner way, or whatever, and you're seeing your pair or your mentee kind of go down a different path, you know, it's so easy to just kind of jump in and be like, "Oh, actually, like, let me save you some time, and effort, and pain and just kind of tell you that there's something else we could try." But I think I've been trying to sit on my hands a little bit and let them go down that path or at least let them finish explaining kind of what their thought process is and giving them the opportunity to do that act of thinking to see it through without interrupting them because I think it's really important to, you know, just honor the process that they're going through. I will say, though, that I also try to keep an eye on the time. And I am also, like, holding in my head a bit of a higher level, like, the project status, any deadlines, what's on our plate for the sprint. And so, if I'm seeing that maybe the path they want to go down might end up taking a while or we don't quite have enough time for that, to then come back and revisit and adjust and reiterate on, like, their first solution. Then that is usually an opportunity where I might offer them another way or say, like, "Hey, like, this is what I'm thinking," because of those things I mentioned before with deadlines or something I'm considering. But I generally try not to impose any of that as, like, this is what we will do so much as saying, "This is what I think we should do." Because I really want to hone in on the idea that, like, everyone just has opinions [laughs] about how they want to do things. And I'm not claiming mine is the perfect way or even the best way, but just what I'm thinking in this moment. JOËL: Yeah, time permitting, I've really appreciated scenarios where you give people a chance to do the non-optimal solution and run into edge cases that kind of show why that solution is not optimal and then backtrack out of it and then go to the optimal path. I think that's a lesson that really sticks much longer. So, I've even done that in scenarios where I'm building some training material. And I'll kind of purposely have the group go down the sort of obvious path, but that turns out to be non-optimal. And then, you hit a wall where things don't work, and then you have to backtrack. And it's like, okay, so that's why we don't do it that way that may have seemed obvious. Because then everybody remembers as opposed to...I mean, you could just go down this other path, and somebody asks you a question, "Why don't we go down this thing?" And then, they just...maybe they have to remember it, or it becomes a thing where it's like, oh, but, like, we were told that's a bad way to do it. And now you have this sort of, like, weird, like, absolutism about, like, oh, but, you know, Joël said that was bad. So, we just got to remember that's the bad thing. And it's not about the morality of that choice that I think can come through when you're kind of declaring a path good and a path bad, but instead, having experienced, hey, we went down this path. There were some drawbacks to it, which is why we prefer this other path. And I think that tends to stick a lot more with students. STEPHANIE: Yeah. I really like what you said about not wanting to inject that, like, morality argument or even kind of deny them the opportunity to decide for themselves how they thought that path went or, like, how they thought the solution was. If you just tell them like, "No, don't go there," you're kind of closing the door on it. And, yeah, they might spend a lot of time afterwards thinking that, like, that will always be a bad option without really forming an opinion for themselves, which I think is really important. Because, you know, once you do get more experience, that is pretty much, like, the work [laughs] that we're doing all of the time. But another thing that I think is also such a skill is assessing your own work, like, after you go down the path or, like, once you have something working, being able to come back to it and look at it and be like, oh, like, can this be better, right? And I think that can only happen once you have something to look at, once you have, like, a first draft, if you will, or do the less optimal implementation or naive implementation. JOËL: So, when you're trying to prompt someone to kind of build that skill of self-review or self-reflection on some of the work that they've done, how do you as a pair or a mentor help stimulate that? STEPHANIE: Yeah. I think with early career folks, one thing that is an easy way to start the conversation is asking, "Are there any places that could be more readable?" Because that's, I think, an aspect that often gets forgotten because they're trying to hold so much in their heads that they are really just getting the code to work. And I think readability is something that we all kind of understand. It doesn't include any jargon about design patterns that they might not have learned yet. You know, even asking about extracting or refactoring might be not where they are at yet. And so, starting with readability, for example, often gets you some of those techniques that we've learned that have, you know, specialized vocabulary. But I have found that it helps meet them where they're at. And then, in time, when they do learn about those things, they can kind of apply what they've already been doing when kind of prompted with that question as, like, oh, it turns out that I was already kind of considering this in just a different form. JOËL: And I think one thing that you gain with experience is that you have kind of a live compiler or interpreter of the language in your head. And so, sometimes for more complex code, I, as an experienced developer, can look at it and immediately be like, oh yeah, here's some edge cases where this code isn't going to work that someone newer to the language would not have thought of. And so, sometimes the way I like to approach that is either ask about, "Oh, what happens in this scenario?" Or sometimes it's something along the lines of, "Hey, now that we've kind of done the main workflow, there's a couple of edge cases that I want to make sure also work. Let's write out a couple of test cases." So, I'll write a couple of unit tests for edge cases that I know will break the code. But even when we write the unit tests, my pair might assume that these tests will pass. And so, we'll write them; we'll run them and be like, "Oh no, look at that. They're red. I wonder why." And, you know, you don't want to do it in a patronizing way. But there's a way to do that that is, I think, really helpful. And then you can talk about, okay, well, why are these things failing? And what do we need to change about the code to make sure that we correctly handle those edge cases? STEPHANIE: Yeah, that's really great. And now, they also have learned a technique for figuring out how to move forward when they think there might be some edge cases. They're like, oh, I could write a test, and they end up [laughs] maybe learning how to do TDD along the way. But yeah, offering that strategy, I think, as a supplement to having supported them in their workflow, I think, is a really cool way to both help them learn a different strategy or tactic while also not asking them to, like, completely change the way that they do their development. JOËL: So, we've talked about ways that we can coach and mentor in a more of a one-on-one setting. But it can also happen in more of a group setting. And an initiative that I've been involved in recently is, once a quarter, the principals on thoughtbot's Boost team are running a training session on a topic that we choose. And we chose this month to make it really interactive. We created an exercise. We talked a little bit about it, had people break out into breakout rooms for a pretty short time—it was like 20 minutes—and come up with a solution. And then brought it back to the big group to talk through some of the solutions. All of that within 45 minutes, so it's a very kind of dense-packed thing. And I think it went really well. STEPHANIE: Yeah. So, hearing that makes me think that the group wasn't actually going to get to a solution in necessarily that short amount of time. But I'm wondering if that was maybe intentional. Like it was never really about coming to the optimal solution but just the act of thinking about it or practicing how you would do that problem-solving without as much of a focus on the outcome. JOËL: So, yes and no. I think, as you said, the discussion, the journey is more important than the outcome. But also, because we wanted people to have a realistic chance at coming up with some kind of solution, we specifically said, "We don't want code. Don't write a code solution to this." Instead, we suggested people come up with some kind of diagram. So, the problem was, we have some sort of business process where you start by...you have an endpoint that needs to receive some kind of shopping cart JSON and then goes through a few different steps. You have to validate it. You have to attempt to charge their card, and then eventually, it has to be sent off to a warehouse to be fulfilled. And so, we're asking them to diagram this while thinking a little bit about data modeling and a little bit about potential edge cases and errors. People came up with some really interesting diagrams for this because there's multiple different lenses from which you could approach that problem. STEPHANIE: That's cool. I really like that you left it up to the groups to figure out, you know, what kind of tools they wanted to use and the how. You mentioned different lenses. So, I'm taking it that you didn't necessarily share what the steps of starting to consider the data modeling would be. Did you prompt the group in any way? How did you set them up before they broke out? JOËL: So, we had a document that had a problem definition; part of this involved talking to a few external services, so things like attempting to charge their card. I think there was a user service they needed to do to pull some user information. And then, there's that fulfillment center that we submit to the warehouse with your completed order. And so, we had sample JSONs for all of these. Again, the goal is not for them to write any code that deals with it but more to think about: okay, we need information from this payload to plug into this one. And then, if they want to add any sort of intermediate steps, they can do that. And I think sort of two common lenses that you could look at this is from more of an action standpoint, so to say, okay, well, first, we receive this payload, and then we make a call to this endpoint, and we try to do a thing and then success or failure, and then kind of go down this path and success or failure, and kind of keep going down that path until you finally reach that fulfillment endpoint. So, it's almost like a control flow diagram. But you could also take more of a data-centered approach and talk about how the data evolves as it goes through this process. And so, you start with, like, a raw JSON payload. And maybe that gets parsed into a shopping cart object, which then gets turned into a temporary order, which then gets turned into a validated order, which then is combined with a credit card charge to create a fulfillment order, which can then be sent off to the warehouse. And that perspective will completely change the way you think about what the code actually needs to be when you create it. STEPHANIE: Got it. That's cool. So, I'm curious, you know, what went into figuring out what the prompt would look like? I guess, like, where did you start? Did you already know that there would be these two different ways of thinking about or lenses to data modeling that you're, like, oh, like, maybe these groups will go down this route? Or was it, I guess, a bit of a surprise that when you came together, you found out kind of the different approaches? JOËL: We already knew that there would be multiple approaches, and we chose not to specify which one to take. I think now this is getting into almost like curriculum design and more kind of the pedagogy side of things, which I'm, you know, excited and passionate about. I don't know, is that something that you've done at all for some of your projects or areas where you've been coaching people? STEPHANIE: It's not been. But I actually do think it's a bit of a goal of mine to lead a workshop at some point at a conference because I really like the hands-on stuff that I get to do day-to-day, you know, working one-on-one with people. And, you know, I also am on the conference circuit. [laughs] And I was thinking that maybe workshops could be a really cool way to bring together those two things of like, well, I am enjoying that experience of working one-on-one, but it is, oftentimes, you know, just on our regular day-to-day work. And so, I would be really curious about how to develop that kind of curriculum for teaching purposes. Do you find yourself starting with problems you see on client work and kind of stripping that down into something maybe a little more general, or do these problems kind of just come up spontaneously? [chuckles] JOËL: So, workshop design is, I think, its own really fascinating topic, and honestly, we could probably do a whole episode on it. But the short of it is I typically work backwards from an end goal. So, just like when I'm writing a blog post, I have one big thing I want people to learn from a workshop, and then everything works backwards from there. Anything that is part of the workshop has to be building towards that big goal, that one thing I want people to learn. Otherwise, I strip it out. So, it's an exercise in ruthlessly cutting to make sure that I'm not overwhelming people and, you know, that we can fit in the time that we have because there's always not enough time in a workshop. And people can very easily get sidetracked or overwhelmed. So, as much as possible, have everything focusing in towards one goal. Circling back to the mentoring side of things, I'm curious what you see is maybe some of the biggest challenges as a mentor or a coach. STEPHANIE: Well, I think, for me, it was, in some ways, like, seeing myself in that role as mentor. Like, oftentimes, that was decided for me by someone else as, like, "Oh, hey. We have a new hire, and, like, would you be their onboarding buddy?" Or, you know, a manager kind of identifying, like, oh, like, Stephanie has been in this role for, you know, a few years now. She's surely ready to mentor [laughs] new folks or people joining the team. And that was really hard for me because I was like, well, I still have so much to learn [laughs], you know, like, how could I possibly be in that position now? You know, I am still learning from all these other people who are mentors to me. So, one thing that took me a long time was learning that I did have things that I knew that other people didn't. And I started to think of it more as this, like, ring of overlapping circles where, you know, we all probably do share some common knowledge. But we all are also experts in different things, and everyone always has something to teach. Even if you're just, like, a few months or, like, a year ahead of someone else, that is actually a really powerful spot to cultivate peer mentorship, and where I think learning can really thrive. There's a really great talk about this by Adam Cuppy called Mentorship in Three Acts, where he talks about that peer mentorship, where someone just knows, like, a little more than someone else. That can be really powerful and can be a good entry point for people who are interested in getting into mentorship but are kind of worried that, like, oh, they are, you know, not a senior yet. You know, when you're at a similar experience level as who you're working with, there is a little bit less of what we were describing earlier of, like, that dynamic of knowing what to do but kind of wanting to hold back and let them discover for themselves. In that peer mentorship dynamic, you know, both people are, like, really deep in it, kind of trying things out, experimenting, learning, and that ends up being really fruitful time for both of them. JOËL: Based on your experience, would you say that maybe that's the best place to start for someone who's looking to get into mentorship, so kind of pursue more of a peer mentorship scenario? STEPHANIE: Yeah. I would definitely say that it has helped me a lot. I've had a lot of peer mentorship relationships in the past, where maybe there just wasn't someone on the team who could mentor me at the time. Or maybe I was wanting to collaborate a little bit more and feeling like I did have some ideas and opinions that I wanted to talk about, or share, or get some feedback on. Reaching across my level was really helpful in starting to create that space. Yeah, I was really surprised by all the things that I was learning and all the things that the other person was learning from me that I think was a good wealth of experience for me to then bring to the next step when I found myself kind of in that position of supporting others who were more junior. JOËL: I'd like to also shout out Exercism.io as a great place to get started with mentoring. For those who are not aware, Exercism is a platform where they have a bunch of exercises that you can go through to learn a language. And you can go through them on your own, but you can also go through them with a mentor. Somebody will basically give you a little mini code review on your exercise or maybe help you out if you're stuck. And this all happens asynchronously. And it's volunteer-run. So, they just have people from the community who volunteer to be mentors on there to help coach people through the exercises. We'll put a link in the show notes to the page they have, kind of explaining how the mentorship works and how to sign up. But I did that for a while. And it was a really rewarding experience for me. I thought that I'd be mostly helping and teaching, but honestly, I learned so much as part of the process. So, I would strongly recommend that to anybody who wants to maybe dip their toe a little bit in the mentoring coaching world but maybe feels like they're not quite ready for it. I think it's a great way to start. STEPHANIE: Ooh, that sounds really cool. Yeah, I know that, especially for folks who maybe are working a little bit more independently, or are a bit isolated, or don't have a lot of people on a team that they're able to access; that sounds like a really great solution for folks who are looking for that kind of support outside of their immediate circle. On that note, shall we wrap up? JOËL: Let's wrap up. STEPHANIE: Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeee!!!!!!!! ANNOUNCER: This podcast is brought to you by thoughtbot, your expert strategy, design, development, and product management partner. We bring digital products from idea to success and teach you how because we care. Learn more at thoughtbot.com.

The Bike Shed
400: How To Search

The Bike Shed

Play Episode Listen Later Sep 5, 2023 36:02


Joël shares he has been getting more into long-form reading. Stephanie talks about the challenges she faced in a new project that required integrating with another company's system. Together, they delve into the importance of search techniques for developers, covering various approaches to finding information online. Domain Modeling Made Functional (https://pragprog.com/titles/swdddf/domain-modeling-made-functional/) Episode on heuristics (https://www.bikeshed.fm/398) Episode on specialized vocabulary (https://www.bikeshed.fm/356) Episode on discrete math (https://www.bikeshed.fm/374) Joël's discrete math talk at RailsConf (https://www.youtube.com/watch?v=wzYYT40T8G8) Dash (https://kapeli.com/dash) Alfred (https://www.alfredapp.com/) Indiana Jones and the Crypt of Cryptic Error Messages (https://thoughtbot.com/blog/indiana-jones-and-the-crypt-of-cryptic-error-messages) Browser History confessional by Kevin Murphy (https://www.youtube.com/watch?v=R7LkHjJdH9o) Transcript: STEPHANIE: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Stephanie Minn. JOËL: And I'm Joël Quenneville. And together, we're here to share a bit of what we've learned along the way. STEPHANIE: So, Joël, what's new in your world? JOËL: Something I've been trying to do recently is get more into long-form reading. I read quite a bit of technical content, but most of it are short articles, blog posts, that kind of thing. And I've not read, like, an actual software-related book in a few years, or at least not completed a software-related book. I've started a few chapters in a few. So, something I've been trying to do recently is set aside some time. It's on my calendar. Every week, I've got an hour sit down, read a long-form book, and take notes. STEPHANIE: That's really cool. I actually really enjoy reading technical stuff in a long-form format. In fact, I was similarly kind of trying to do it, you know, once a week, spend a little bit of time in the mornings. And what was really nice about that is, especially if I had, like, a physical copy of the book, I could close my computer and just be completely focused on the content itself. I also love blog posts and articles. We are always talking on the show about, you know, stuff we've read on the internet. But I think there's something very comprehensive, and you can dig really deep and get a very deeper understanding of a topic through a book that kind of has that continuity. JOËL: Right. You can build up a larger idea have more depth. A larger idea can also cover more breadth. A good blog post, typically, is very focused on a single thing, the kind of thing that would really probably only be a single chapter in a book. STEPHANIE: Has your note-taking system differed when you're applying it to something longer than just an article? JOËL: So, what I try to do when I'm reading is I have just one giant note for the whole book. And I'm not trying to capture elements or, like, summarize a chapter necessarily. Instead, I'm trying to capture connections that I make. So, if there's a concept or an argument that reminds me of something perhaps similar in a different domain or a similar argument that I saw made by someone else in a different place, I'll capture notes on that. Or maybe it reminds me of a diagram that I drew the other day or of some work I did on a client six months ago. And so, it's capturing all those connections is what I'm trying to do in my notes. And then, later on, I can kind of go back and synthesize those and say, okay, is there anything interesting here that I might want to pull out as an actual kind of idea note in my larger note-taking system? STEPHANIE: Cool, yeah. I also do a similar thing where I have one big note for the whole book. And when I was doing this, I was even trying to summarize each chapter if I could or at least like jot down some takeaways or some insights or lines that I like felt were really compelling to me. And, like, something I would want to, in some ways, like, have created some, like, marker for me to remember, oh, I really liked something in this chapter. And then, from there, if I didn't capture the whole idea in my note, I knew where I could go to revisit the content. JOËL: And did you find that was helpful for you when you came back to the book? STEPHANIE: Yeah, it did. I usually can recall how, like, I felt reading something. You know, if something was really inspiring to me or really relatable, I can recall that, like, I had that experience or emotion. And it's just, like, trying to find where that was and that this is a system that has worked well for me. Though, I will say that summarizing each chapter did kind of remind me of, like, how we learned how to take notes in school. [laughs] And I think, you know, middle school, or whatever, I recall a particular note-taking format, where you, you know, split the page up into, like, an outline with all the chapters, and you tried to summarize it. And so, it did feel a little bit like homework [laughs]. But I can also see the value in why they taught me how to do that. JOËL: I was recently having a conversation with someone else about the idea of almost, like, assigning yourself the college-style essay question after finishing a book to try to synthesize what you learned. STEPHANIE: Whoa, that's really cool. I can see how that would really, like, push you to synthesize and process what you might have just consumed. And, also, I'm so glad I'm not in school anymore [laughs] so that I don't have to do that on a regular basis. [laughs] I'm curious, Joël, what book are you reading right now? JOËL: I've been reading Domain Modeling Made Functional, which is a really interesting intersection between functional programming, Domain-Driven Design (DDD), and a lot of interesting kind of type theory. And so, that sort of intersection of those three Venn diagrams leads to this really fascinating book that I've been going through. And I think it connects with a lot of other things that I've been thinking about. So, I'll be reading and be like, oh, this reminds me of this concept that we have in test-driven development. Or this reminds me of this idea that we do when we do a product design sprint. And this reminds me of this principle from object-oriented design. And now I'm starting to make all these really interesting connections. STEPHANIE: Awesome. Well, I hope to hear more about what you've learned or kind of what you're thinking about going through this book in future episodes. JOËL: This is not the last time we hear about this book, I'm pretty sure. So, Stephanie, what's new in your world? STEPHANIE: So, I have a little bit of a work update to share. So, lately, I've been brought in to work on a feature that is integrating with another company's system. And the way that I was brought into this work was honestly just being assigned a task. And I was picking up this work, and I was kind of going through the requirements that had been specked out for me, and I was trying to get started. And then, I realized that I actually had a lot of questions. It just wasn't quite fully fleshed out for the level of detail that I needed for implementing. And for the past couple of weeks, we've been chatting in Slack back and forth as I tried to get some of my questions answered. They are trying to help me, but also the things that I'm saying end up confusing them as well. And then, I end up having to try and figure out what they're looking for in order to properly respond to them. And I had not met these people before. These are folks from that other company. And, you know, I'd only just seen their little Slack profile pictures. So, I didn't know who they were. I didn't know what role they had and kind of, like, what perspective they were coming to these conversations from. And after a while, I was feeling a little stressed out because we just kept having this back and forth, and not a lot of answers were coming to fruition. And I really ended up needing the nudge of the manager on my client team to set up a meeting for us to all just talk synchronously. And I think I had...not that I had been avoiding it necessarily, but I guess I was under the impression that we were at the point where we could just, you know, shoot off a question in Slack and that there would be a clear path forward. But the more we kept pulling on that thread, the more I realized that, oh, like, we have a lot of ambiguity here. And it really helped to meet them finally, not in person but, like, over a video call. [laughs] So, this happened yesterday. And, you know, even just, like, going around doing introductions, like, sharing what their role was at the company helped me just understand, like, who I was talking to. You know, I realized, oh, like, the level of technical details that I had been providing was maybe too much for this group. And I was able to have a better understanding of what their needs were, like hearing kind of the problem that they had on their end. And I realized that, oh, like, they actually aren't going to provide me the details for implementation that I was looking for. That's up to me. But at least now I know what their higher-level needs are so that I can make the most informed decisions that I can. JOËL: Fascinating. So, you thought that this was going to be, like, the technical team you're going to work with. And it turns out that this was not who they were. STEPHANIE: In some ways. I think I thought by providing more technical details that would be helpful, but it ended up being more confusing for them. And I think I was similarly kind of frustrated because the ways that I was asking questions or communicating also wasn't getting me the answers that I needed as well. But I felt really great after the meeting because I'm like, wow, you know, it doesn't have to be as stressful. You know, when you start getting into that back and forth on Slack, at least I find it a bit stressful. And it turns out that the antidote to that was just getting together and getting to know each other and hashing out the ambiguity, which does seem to work better in a more synchronous format. JOËL: Do you have kind of a preference for synchronous versus asynchronous when it comes to communication? STEPHANIE: That's a good question. I think it's kind of a pendulum for me. I'm in my asynchronous communication is a bit better for me right now phase, but only because I am just so burnt out on meetings a lot of the time that I'm like, oh, like, I really don't want to add another meeting to my calendar, especially because...I amend my statement; I'm burned out of meetings that don't go well. [laughs] And this meeting, in particular, was different because, you know, I realized, like, oh, like, we are not on the same page, and so how can we get there? And kind of making sure that we were focused on that as an agenda. And I found that ultimately worked out better than the async situation that I was describing, which I'm thinking now, you know when things aren't clear, text-based communication certainly does not help with that. JOËL: So, meetings, sometimes they're actually good. STEPHANIE: Yeah, that's my enlightened discovery this week. JOËL: So, this episode is kind of a special one. We've just hit 400 episodes of The Bike Shed. So, this is episode number 400. It's also my 50th Episode as a co-host. STEPHANIE: Right. That's a huge deal. 400 is a really big number. I don't know if I've ever done 400 of anything before [laughs]. JOËL: The Bike Shed has been going on for almost ten years now. The first episode up on the website is from October 31st, 2014, so just about nine years from that first episode. STEPHANIE: Wow. And it's still going strong. That's really awesome. I think it's really special to be a part of something that has been going on for this long. And, I don't know, maybe there are still listeners today from back in 2014. I would be really excited to hear if anyone out there has been listening to The Bike Shed throughout its whole lifespan. That's really cool. JOËL: Looking back over the last 50-ish episodes you and I have done, do you have a favorite episode that we've recorded? STEPHANIE: This may be a bit of recency bias. But the episode that we did about Software Heuristics I really enjoyed. Because I think we got to bring to the table some of the things we believe and the way we like to do things and kind of compare and contrast that with each other. And I always find people's processes very fascinating. Like, I want to know how you think and where your brain is at when you approach a problem. So, I really enjoyed that topic. What about you? Do you have any highlight episodes? JOËL: I think there's probably two for me. One is the episode that you and I did on Specialized Vocabulary. I think this really touched on a lot of really interesting aspects of writing software that's going to scale, software that works for a team, and also kind of personal growth and exploration. The second one that I think was really fun was the episode I did with Sara Jackson as a guest talking about Discrete Math because that's an episode that I got really excited about the topic. And right after recording the episode, it was the last day of the call for proposals for RailsConf. And I just took that raw excitement, put together a proposal, hit submit before the deadline. And it got accepted and got turned into a talk that I got to give on stage. So, that was, like, just a really fun journey from exciting episode with Sara and then, like, randomly turned into a conference talk. STEPHANIE: That's awesome. That makes me feel so happy. Because it just reminds me about how the stuff we talk about on the show can really resonate with people, you know, enough to become a conference talk that people want to attend. And I also really like that a lot of the topics we've gotten into in the past 50 episodes when we've taken over the show have been a bit more evergreen and just about, you know, the software development experience and a little bit less tied to specific news within the community. Speaking of evergreen topics, today, I wanted to discuss with you an evergreen software skill, and that is searching or Search-Driven Development, even if you will. JOËL: Gotta always get that three-letter acronym, something DD. STEPHANIE: Yeah. I am really curious about how we're going to approach this topic because a lot of folks might joke that a big part of writing software is knowing what to Google. Do you agree with that statement or not? JOËL: Yes and no. There's definitely value in knowing what to Google. It really depends on the kind of work that you're doing. I find that I don't Google that much these days. There are other tools that I use when I'm particularly, like, searching through documentation, but they tend to be less sort of open-ended questions and more where it's like, oh, let's get the actual documentation for this particular class or this particular method from the standard library. STEPHANIE: Oh, interesting. I like that you pointed out that there are different scopes of things you might want to search for. So, am I hearing correctly that when you have something specific in mind that you are just trying to recall or wanting to look up, you know, you're still using search that way, but less so if you are trying to figure out how to approach solving a problem? JOËL: So, oftentimes, if I'm working with a language that I already have familiarity with or a framework that I have familiarity with, I'm going to lean on something more specific. So, I'm going to say, okay, well, I don't exactly remember, like, the argument order for Enumerable's inject method. Is it memo then item, or item then memo? So, I'll just look it up. But I know that the inject method exists. I know what it does. I just don't remember the exact specifics of how to do that. Or maybe I want to write a file to disk, and I don't remember the exact method or syntax to do that. There are some ways that you can do it using a bunch of instance methods. But I think there's also a class method that allows you to kind of do it all at once. So, maybe I just want to look up the documentation for the file class in Ruby and read through that a little bit. That's the kind of thing where I suppose I could also Google, you know, how to save file Ruby, something like that. But for those sorts of things where I already roughly know what I want to do, I find it's often easier just to go directly to the docs. STEPHANIE: Yeah, yeah, that's a great tip. And I actually have a little shortcut to share. I started using DuckDuckGo as my search engine in the past year or so. And there's this really cool feature called Bangs for directly searching on specific sites. From my search bar, I can do, let's say, bang Rails and then my query. And it will search directly the Rails Guides website for me instead of, you know, just showing the normal other results that might come up in my regular search engine. And the same goes for bang Ruby doc. That one shows ruby-doc.org, which is my preferred [laughs] Ruby documentation website. I've really been enjoying it because, you know, it just takes that extra step out of having to either navigate to the site itself first or starting more broadly with my search engine and then just scrolling to find the site that I'm looking for. JOËL: Yeah. I think having some kind of dedicated flow helps a lot. I have a system that I use on my machine. It is Mac-specific. But I use a combination of the application Dash and the application Alfred. It allows me, with just a few keyboard shortcuts, to type out language names. So, I might say, you know, Ruby inject, and then it'll show me all the classes that have that method defined on it, hit Enter, and it pops up the documentation. It's downloaded on my machine, so it works offline. And it's just, you know, a few key presses. And that works really nicely for me. STEPHANIE: Oh, offline search. That's really nice. Because then if you're coding on a plane or something, then [laughs] you don't have to be blocked because you can't look up that little, small piece of information you need to move forward. That's very cool. JOËL: That is really cool. I don't know how often I've really leaned into the offline part of it. I don't know about you; I feel like I don't code on airplanes as much as I thought I would. STEPHANIE: That's fair. I also don't code on airplanes, but the idea that I could is very compelling to me. [laughs] JOËL: Absolutely. So, that's the kind of searches that I tend to do when I'm working in a language that I already know, kind of a day-to-day language that I'm using, or a framework that I'm already pretty familiar with. And this is just looking at all the things I haven't gotten to the point where I've fully memorized, but I have a good understanding of. What about situations where maybe you're a little bit less familiar with? So maybe it's a new framework, or even, like, a situation where you're not really sure how to proceed. How do you search when there's more uncertainty? STEPHANIE: Yeah, that's a good question. I do think I start a bit naively. The reason that we're able to be more specific and know exactly where to go is because we've built up this experience over time of scrolling through search results and clicking, you know, maybe all of them on the first page, even, and looking at them and being like, oh, like, this is not what I want. And then, seeing something else, it's like, oh, this is more helpful and kind of arrived at sources that we trust. And so, if it's something new, I don't really mind just going for a basic search, right? And starting more broadly might even be helpful in that process of building up the experience to figure out which places are reputable for the thing that I'm trying to figure out. JOËL: Yeah, especially when there's a whole new landscape, right? You don't really know what are the places that have good information and the ones that don't. For some things, there might be, like, an obvious first place to start. So, recently, I was on a project where I was trying to do an integration between a Rails app and a Snowflake data warehouse. And so, the first thing I did—I'm not randomly Googling—I went to the Snowflake website, their developer portal, and started reading through documentation for things. Unfortunately, a lot of the documentation is a bit more corporatey and not really helpful for Ruby-specific implementation. So, there's a few pieces that were useful. There were some links that they had that sent me to some good places. But beyond that, I did have to drop to Google search and try to find out what kinds of other things the community had done that could be helpful. Now, that first pass, though, did teach me some interesting things. It gave me some good keywords to search for. So, more than just Ruby plus Snowflake or something like that like, I knew that I likely was going to want to do some kind of connection via ODBC. So, now I could say, okay, Ruby plus ODBC integration, or Ruby plus ODBC driver and see what's happening there. And it turns out that one of the really common use cases for ODBC and Ruby is specifically to talk to Snowflake. And one of the top results was an article saying, "Hey, here's how you can use ODBC to get your Rails app to talk to Rails." And then I knew I struck gold. STEPHANIE: That's really cool. The thing that I was picking up on in what you were saying is the idea of finding what is most relevant to you. And maybe that is something that the algorithm serves you because, like, it's, like, what a lot of people are searching for, you know, a lot of people are engaging with, or matching with all these keywords that you're using. My little hack that I've been [chuckles] using is to use Slack and lean on other people who have maybe a little more, even just, like, a little more experience than me on the subject, and seeing, like, what things they're linking to, and what resources they're sharing. And I've found that to be really helpful as a place to start. Because, at that point like, my co-workers are narrowing down the really broad landscape for me. JOËL: I really like how you're sort of you're redefining the question a little bit here. And that, I think, when we talk about search, there's almost this implicit assumption that search is going to be searching the public internet through Google or some other alternative search engine. But you're talking about actually searching from my private corpus of data, in this case, either thoughtbot or maybe the client's Slack conversations, and pulling up information there that might be much more relevant or much more specific to the work that you're trying to do. STEPHANIE: Yeah. In some ways, I like to think of it as crowd-sourced but, like, a crowd that I trust and, you know, know is relevant to me and what I'm working on. I actually have a fun fact for you. Did you know that Slack is actually an acronym? JOËL: No, I did not know that. What does it stand for? STEPHANIE: It stands for Searchable Log of All Communication and Knowledge. JOËL: That is incredibly clever. I wonder, is this the thing where they came up with that when they made the original name? Or did someone go back later on, you know, a few years into Slack's life and was like, you know what? Our name could be a cool acronym; here's an idea. STEPHANIE: I'm pretty sure it was created in Slack's early days. And I think it might have even helped decide that Slack was going to be called Slack as opposed to some of the other contenders for the name of the software. But I think it's very accurate. And that could just be how I use Slack. I'm a very heavy search power user in Slack. [laughs]. So, I find it very apt. You know, obviously, I use it a lot for finding conversations that happened. But I really do enjoy it as a source of discovery for a specific topic, or, you know, technical question or idea that I'm wanting to just, like, filter down a little bit beyond, like you said, the public internet. In fact, I have found it really useful for when you encounter errors that actually are specific to your domain or your app. Obviously like, you will probably be less successful searching in your search engine for that because it includes, you know, context from your app that other people in the world don't have. But once you are narrowing it down to people at your company, I've been able to get over a lot of troubleshooting humps that way by searching in Slack because likely someone within my team has encountered it before. JOËL: So, you mentioned searching for error messages in particular. And I feel like that is, like, its own, like, very specific searching skill separate from more general, like, how do I X-style questions. Does that distinction kind of line up with your mental map of the searching landscape? STEPHANIE: Yeah. I guess the way that I just talked about it now was potentially a bit confusing because I was saying instead of how you might search for errors normally, but I did not talk about how you might search for errors normally. [laughs] But specifically, you know, if I'm popping error messages into my search engine, I am removing the parts of the stack trace that are specific to my app, right? Because I know that that will only kind of, like, clutter up my query and not be getting me towards a more helpful answer as to the source of my issue, especially if the issue is not my application code. JOËL: Right. I want to give a shout-out to an article on the thoughtbot Blog with a wonderful name: Indiana Jones and the Crypt of Cryptic Error Messages by Louis Antonopoulos. All about how to take an error message that you get from some process in your console and how to make that give you results when you paste it into a search engine. STEPHANIE: I love that name. Very cool. JOËL: So, you've talked a little bit about the idea of searching some things that are not on the public internet. How do you feel about kind of internet knowledge bases, private wikis, that kind of thing? Have you had good success searching through those kinds of things? STEPHANIE: Hmm, I would say mixed success, to be honest. But that's because of maybe more so the way that a team or a company documents information. The reason I say mixed results is because, a lot of the time, the results are outdated, and they're no longer relevant to me. And it doesn't take that much time to pass for something to become outdated, right? Because, like, the code is always changing. And if, you know, someone didn't go and update the documentation about the way that a system has changed, then I usually have to take the stuff that I'm kind of seeing in private wikis with a bit more skepticism, I would say. JOËL: Yeah, I think my experience mirrors yours as well. Also, some private wikis have just become absolutely huge. And so, searches just return a lot of results that are not really relevant to what I'm searching for. The searching algorithms that these systems use are often much less powerful than something like Google. So, they often don't sort results in a way that are bringing relevant things up to the top. So, it's more work to kind of sift through all of the things I don't care about. STEPHANIE: Yeah, bringing up the size of a wiki and, like, all of the pages, that is a good point because I see a lot of duplicate stuff, but that's just, like, slightly different. So, I'm not sure which one I'm supposed to believe. One really funny encounter that I had with a private wiki, or actually it was, like, a knowledge base article that was for the internal team...it was documenting actually a code process. So, it was documenting in more human-readable terms, like the steps an algorithm took to determine some result. But the whole document was prefaced by, "This information came from an email that was sent way long ago." [laughs] JOËL: That's an epic start to a Wiki article. STEPHANIE: Yeah. And there was another really funny line that said, "The reason for this logic is because of a decision made by (This person's name.)," like a business decision that (some random person name). No last name either, so I have no idea [laughs] who they could be referring to and any of the, like, historical context of why that happened. But I thought it was really funny as just a piece of, like, an artifact, of, at the time, when this was written, that meant something to someone, and that knowledge kind of has been diluted [laughs] over the years. JOËL: Yeah, internal wikis, I feel like, are full of that, especially if they've had a few years to grow and the company has changed and evolved. So, now it's time for hot takes. STEPHANIE: Yeah, I'm ready for them. JOËL: We are now in the fancy, new age of AI. Is ChatGPT going to make all of this episode obsolete? STEPHANIE: I'm going to say no, but I'm also biased, and I'm not a ChatGPT enthusiast. I've said it on air. [laughs] I can't even say that I've used it. So, that's kind of where I'm coming from with all this. But I have heard from folks that, convenient as it may be, it is not always 100% accurate or successful. And I think that one of the things I really like about kind of having agency over my search is that I can verify, as a human, the information that I'm seeing. So, you know, when you're, like, browsing a bunch of Stack Overflow questions and you see, you know, all these answers, at least you can, like, do a little bit of, like, investigation using context clues about who is answering the question, you know, like, what experience might they have? If you encounter something on a blog post, for example, you can go to the about page on this person's blog and be like, who are you? [chuckles] And, like, what qualifies you to give this information? And I think that is really valuable for me in terms of evaluating whether I want to go down a path based on what I'm seeing. JOËL: So, I've played with it a tiny, little bit, so not enough to have a good sample size. And I think it can be interesting for some of those less constrained kind of how do I style questions. I'm not necessarily looking for, like, an exact code sample. But even if it just points me towards, oh, I need to be looking at this particular class in this standard library and read through that documentation to build the thing that I want. Or maybe it links me to kind of the classic blog posts that people refer to when talking about this thing. It's a good way sometimes to just narrow down when you're kind of faced with, you know, the infinity of the internet, and you're kind of like, oh, I don't even know where to start. It gives you some keywords or some threads to follow up on that I think can be really interesting. STEPHANIE: The infinity of the internet. I love that phrase. I don't think I've heard it before, but it's very evocative for me [laughs]. And I like what you said about it helping you give a direction and to kind of surface those keywords. In fact, it almost kind of sounds like what I was mentioning earlier about using Slack for, right? And, in that case, the hive mind that I'm pulling from is my co-workers. But also, I can see how powerful it would be to leverage a tool that is guiding you based on the software community at large. JOËL: Something I'd be curious to maybe lean into a little bit more are some of those slightly more specified questions where it does give you a code snippet, so something like writing a file to disk where, right now, it's, you know, five characters. I just pop up Alfred and type up Ruby F, and it gives you the file docs, and it's, you know, right there. There's usually an example at the top of the file. I copy-paste that and get working. But maybe this would be a situation where some AI-assisted tools would be better. It could be searching through something like ChatGPT. It could be maybe even something like Co-pilot, where, you know, you just start typing a little bit, and it just fills out that skeleton of, like, oh, you want to write a file to disk in Ruby. Here's how it's typically done. STEPHANIE: Yeah, you bring up a good point that, in some ways, even the approaches to searching we were talking about originally is still just building off of algorithms helping us to find what we're looking for, right? Though, I did really want to recommend an awesome talk from Kevin Murphy, from a RailsConf a couple of years ago, that's called Browser History Confessional: Searching My Recent Searches. The main message that I really enjoyed from this talk was the idea of thinking about what you're searching for and why because that will, I think, help add a bit of, like, intentionality into that process. You know, it can be very overwhelming, but let that guide you a little bit. One of the things that he mentions is the idea of revisiting your own assumptions with search. So, even if you think you know how to do something, or you might even know, like, how you might want to do it, just going to search to see if there's any other implementations that you haven't thought of that other people are doing that might inform how you approach a problem, or at least, like, make you feel even more confident about your original approach in the first place. I thought that was really cool. That's not something that I do now, but definitely, something that I want to try is to be, like, I think I know how to do this, but let me see what other people are doing because that might spark something new. JOËL: We'll put a link in the show notes to this talk. But I was lucky enough to see it in person. And also would like to second that recommendation. It is worth watching. From this conversation that you and I have had, I'm having, like, two main takeaways. One is kind of what you just said, the idea of being a little bit more cognizant of, what kind of search am I doing? Is this a sort of broad how do I X, where I don't even really know where to start? Is this, like, something really specific where you just don't know what kind of syntax you want to use? Is it an error message where you just want to see what other people have done when they've encountered this? Or any other, like, more specific subcategories. And how being aware of that can help you search more effectively. And secondly, don't limit yourself to the public internet. There's a lot of great information in your company's Slack or other instant messaging service, maybe some kind of documentation system internal, some kind of wiki. And those can be a great place to search as well. STEPHANIE: If we missed any other cool searching tips or tricks or ways that we might be able to improve our processes for searching as developers, I would really love to hear about them. So, if any listeners out there want to write in with their thoughts, that would be super awesome. On that note, shall we wrap up? JOËL: Let's wrap up. STEPHANIE: Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeee!!!!!! ANNOUNCER: This podcast is brought to you by thoughtbot, your expert strategy, design, development, and product management partner. We bring digital products from idea to success and teach you how because we care. Learn more at thoughtbot.com.

The Bike Shed
398: Developing Heuristics For Writing Software

The Bike Shed

Play Episode Listen Later Aug 22, 2023 34:07


Want a cool cucumber salad? Joël's got you covered. Stephanie has evolved and found some pickles she enjoys. Experienced programmers use a lot of heuristics or "rules of thumb" about what makes their code better. These aren't always true, but they work in most situations. Stephanie and Joël discuss a range of heuristics, how to use them, how to come up with them, how to know when to break them, and how to teach them to more junior devs. Pickled mustard seeds (https://www.youtube.com/watch?v=aLMFGk7Ylw0) The purpose of a system is what it does (https://en.wikipedia.org/wiki/The_purpose_of_a_system_is_what_it_does) Intro to empirical software engineering by Hillel Wayne (https://www.youtube.com/watch?v=WELBnE33dpY) Transcript: STEPHANIE: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Stephanie Minn. JOËL: And I'm Joël Quenneville. And together, we're here to share a bit of what we've learned along the way. STEPHANIE: So, Joël, what's new in your world? JOËL: So, as of the recording of this, summer is in full swing, and it's the time of year where we have all these, you know, fresh vegetables out, so I've been really enjoying a lot of those. I think this week; in particular, I've been going into, like, all the variations on cucumber salads. STEPHANIE: Ooh. JOËL: Yeah. So, that's been kind of fun for me. A fun thing I've been doing to spice this up is pickling mustard seeds to add as a topping. That's actually really amazing. It adds just a little bit of acidity, a little bit of crunch, a little bit of texture. And it's pretty. STEPHANIE: That sounds so delicious. And also, I was going to share something about pickles about what's new in my world. [laughs] But first, I am curious, what has been your go-to cucumber salad that you put this pickled mustard seed situation on top? JOËL: So, cucumbers and tomatoes is just the base of everything. And then, it kind of goes with random things I have in my fridge. A little bit of goat cheese on top can be a great topping, big fan of balsamic glaze. You can just get, like, a bottle of that at the grocery store, the pickled mustard seeds. I've recently been trying topping with a fried egg. STEPHANIE: Ooh, that sounds really fun. It kind of, like, adds a bit of savoriness and creaminess and maybe even, like, the crunchy fried edges. That sounds really yummy. JOËL: Particularly if you do it over easy where the center is not fully cooked. When the egg breaks, you effectively get salad dressing for free. STEPHANIE: That sounds so delicious. JOËL: Summer vegetables, they're great. STEPHANIE: They are great. Last year, I did have a cucumber garden, as in a garden, and a few cucumber plants that were too prolific for me, to be honest. I found myself overrun with cucumbers and having to give them away because we just didn't eat them enough. And this year, we scaled back a little bit [laughs] on the cucs. But I am so excited to bring up what's new in my world now because it's, like, so related, and we did not plan this at all. But I have a silly little thing to share about my own pickle journey. So, I used to be a pickle hater. JOËL: You know what? Same. STEPHANIE: Oh my gosh, incredible. Another new thing we've learned about each other. I really, like, wanted to like pickles because, you know, when you order a sandwich in a restaurant, it always comes with the pickle spear. And neither me nor my partner were into pickles, and we would always leave the spear uneaten on the plate, and we felt so bad about it. I felt really bad about it. And so, every, like, three to six months or so, I'd be like, okay, I'm going to gather the courage to try the pickle again and see if maybe my taste buds have changed, and this time I'll like it. And, you know, I would try a bite and just be like, no, no, I don't think it's for me. [laughs] But I guess I was just so primed to do something about, like, wanting to eliminate this really inconsequential food waste. But every time it happened, I would just, you know, [laughs] be, like, oh, if only I loved pickles. And I got my friend, who is a pickle connoisseur, to help me figure out, like, what pickles I might like. So, I asked her to come up with, like, a pickle sampler for me because I really hadn't tried all too many. And that actually really helped me find which ones were a little more palatable to me. So, I found out that I liked the sweeter ones. There's, like, a bread and butter pickle that can be quite sweet. Your diner pickle can be very different from a jar of, like, fancy pickles. [laughs] JOËL: Definitely. STEPHANIE: One day, she gifted me a jar of, like, Polish gherkins that were delicious. JOËL: Hmmm. STEPHANIE: I was like, wow, I can just snack on these. So, the thing that's new is that this time, I went to an Eastern European grocery store, and I bought my own jar of pickled gherkins. And that was something that Stephanie, like, two years ago, would never even do. [laughs] JOËL: That's really cool that you got a chance to sort of explore a broader range of what was available in the pickle world and then were able to find kind of your niche there and discover something new that you actually like. STEPHANIE: Yeah, it was very fun. And now I feel like my whole world has opened up to, you know, pickley and fermented things and just, like, get to enjoy even more snacks. So, to move away from pickles, recently, on my client project, I've been pairing a lot more with other client developers. And one thing that has come up is, you know, talking about our reasoning or our thought process for when we're pairing on some code. And I realized that I have built up a lot of either intuition or maybe some rules that I like to follow when I'm writing code, writing a test, or even doing a code review. And I've realized that you know, as developers, we often use these kinds of shortcuts or heuristics to help orient us as we're doing our work. JOËL: Yeah. I think that's definitely something that either comes yourself from experience or sometimes is passed along, and you get to benefit from somebody else's experience. They learned the hard way a lot of these tips and tricks, and now they kind of pass on some of these guidelines to us. Do you have any favorites that you reach for frequently? STEPHANIE: So, one way I like to approach a problem is to start messy [laughs] and to kind of see what that gets me and then where to go from there. I find that it's a little bit easier for me to draw on things that I've, you know, learned or picked up and tips once I have something in front of me to react to. So, maybe I will just go with the naive implementation and just write all of the code in one method, you know, in a class. And from there, now that it's out of my system, can I kind of come back in with a finer tooth comb and then apply more of a sustained effort to clean things up, right? And, to me, the question I find myself asking is, like, can this be extracted further? And so, you know, if I have everything in one giant method, then yes, [laughs] there is likely, you know, many opportunities to extract that, and maybe I will see something like, oh, the way that I spaced out this code that might be a signal to me that, like, these are some ideas that are grouped together, and I can pull something out there. JOËL: Do you have a heuristic around when to stop extracting? STEPHANIE: That's a good point. I think I tend to stop when I have kind of pulled out the classes that make sense to me. And, at that point, you know, like, maybe there is more extraction that can be done. But at a certain point, you know, you then get these really tiny classes that maybe don't hold their weight. And I think that's also true of methods that then call other methods, and that's the only thing that they do. Then it's like, well, is this too extracted that it's not really giving a future reader helpful information, right? I want the extraction to improve readability. And that tends to be another lens through which I am applying to this idea of, like, can I extract further? Is this extraction helpful for understanding this code? JOËL: I like the idea of looking at the code through multiple lenses. And so, sometimes you look at it through the lens of, yeah, are there enough moving parts here? Or does it feel kind of brittle and all in one place? And then sometimes completely shifting your lens and saying, you know what? Let's put myself in the seat of someone who's looking at this code for the first time. Can I understand it? So, structuring and extracting code is a big part of the work that we do. And I also happen to have a couple of heuristics that I like to use. One is separate branching code from doing code. So, if I have an if...else condition, I try not to put ten lines of logic inside each branch; instead, I have just a call out to a method so that the only thing the conditional does is to choose which path you go, and then each individual path is its own method. Similarly, if I'm writing a method, I'm not going to have a bunch of logic then a conditional mixed in together. So, my heuristic is a method gets to do one of two things. It either gets to choose a path to take or it gets to do a thing, but you can't mix and match both. STEPHANIE: Yeah, that makes a lot of sense. I really appreciate a well-named method that is, you know, determining, like, what condition needs to happen because then that helps me, yeah, like, avoid having to hold all of this information about this condition or this other condition, and this other condition in order to figure out what path I'm trying to take. JOËL: And the naming and the readability, I think, is a big part of this. Another heuristic that I like to use that kind of converges on the same result is trying to write each method at a single level of abstraction. So, if I am writing a method that has some kind of high-level terms it's using, I'm not going to also mix in a lot of low-level implementation. And then, similarly, if it's a method that's doing a lot of, like, low-level nuts and bolts things, I'm going to try not to pull in some of these higher-level domain name methods in there. And so, by separating things out so that every method reads one level of abstraction, you make it much easier for the reader to go through and figure out what's happening. Are we kind of getting that more 10,000-foot view, getting a sense of what's happening, and saying, okay, we want to process the user form, and then we want to send off an email, and then we want to, you know, write to a file? Or are we going through, okay, we're going to increment a counter so that we get exponential back off on our [inaudible 10:28] request? Those two things do not belong together in the same method. STEPHANIE: Yeah, absolutely. I really like this heuristic. And I have been applying it more and more and found it really useful for making sure that you're handling your errors correctly, especially because, at different levels of abstraction, you want to do different things with your errors, right? An implementation error that's raised because, you know, you're calling something accidentally on nil, or maybe a third-party service is down, and you get a custom error, whatever that is, those concerns are different from how you want to handle things at the controller level. And oftentimes, I see those things really mixed together, and honestly, I think leads to a lot of buggy code when you're trying to handle things that can go wrong at the wrong level of abstraction. JOËL: Yeah. Is there a good heuristic around what level you think is best to trigger an exception? Or maybe, more generally, just being aware of different levels of abstraction and knowing that catching or triggering errors at each level will have different impacts. STEPHANIE: I think more of the latter, the having an awareness of what kinds of errors might be possible and what impact that has on the user, right? The user being either an actual customer or, you know, another developer who has to read a notification from an error monitoring service. [laughs] JOËL: This is really interesting to me because I think we've now bridged the concept of heuristics into the idea of mental models. So, the heuristic is write your methods at a single level of abstraction, but that then leads into a mental model where maybe code is structured in three or four different layers. You've got a low level, a mid-level, a high level, something like that, of abstraction. And now, you can use that mental model to start thinking about what are the impacts of exceptions at each layer? And then, maybe you complete the circle by creating a heuristic that relies on that mental model, maybe, I don't know, raise in the low-level rescue at the top level or something. I'm making something absolutely arbitrary up right now. But somehow, we've gone from heuristic, which creates a mental model, which then allows us to build new heuristics on top of that, and that seems like a virtuous cycle to me. STEPHANIE: Yeah, absolutely. I think what I'm also picking up is the idea that you do need a mental model, or you do need to draw on your own ideas about something in order to apply the heuristic, right? You know, someone could tell you to separate branching code from doing code. But maybe you don't know what that means or, like, maybe you don't see why that's important. And sure, you can still apply it and try your best to follow it. But, in some ways, I think that the best heuristics are ones that you've kind of developed for yourself based on your own experience. JOËL: That's really interesting. I think once you've built from your own experience, I definitely feel like they're really impactful because you've kind of synthesized 2, 5, 10, 20 years of experience doing some of this work into, oftentimes, like, you know, a pithy one-line sentence, 5, 6 words that convey an approach that you've found works best, you know, maybe 80% or 90% of the time. The power of synthesis for your own self-learning I think it's really hard to understate. So, I'm curious if there's any other heuristics that you commonly use that you kind of created yourself based off your own experience rather than just having it be more of a broadly received idea from the community. STEPHANIE: I think, for me, it's more so that the experience has helped affirm certain heuristics and also made me feel more comfortable with letting others go. And one that I heard a lot but, like, didn't quite understand until really working through it deeper is the idea of feeling pain when you write a test, and that being a signal of opportunities to try different design with your code. And I just didn't know what that pain was at the beginning. Like, what does that even mean? [laughs] Like, how can a test cause me pain? But on my own, I realized, oh, like, actually, I get really frustrated when I need to stub out a whole method chain, right? And I find myself having to go look up how to do that or just spending a lot of time having to do something that I haven't done before. Maybe the pain comes from having to change a lot of files because, oh no, like, I also broke 20 other tests in the process. But when you're first starting out, oftentimes, you, like, don't know that that is not normal [laughs]; at least, that was true for me. And so, that was something that I had heard about, like, if you are feeling pain when writing a test, then, like, maybe reconsider your code design. But when you don't know how to identify what that pain is, and you also, like, don't know where to go from there, I find that, you know, the heuristic can only help you so much. JOËL: Yeah. Maybe that's something that's challenging with a heuristic in that they're often expressed as these pithy sentences. But if you're not familiar with some of the underlying concepts, that might make them harder to apply, which is unfortunate because, oftentimes, these heuristics that we've developed as a community are targeted to newcomers to help them kind of avoid the mistakes that we've made along the way. STEPHANIE: I think what really helped me the most in connecting a heuristic that's commonly expressed and my own experience is when I've had someone ask me about how I'm feeling when I'm, you know, making some kind of decision or when I'm reading some code. Like, what do I think of this, or what has been my experience with this? And giving me the opportunity on the spot to synthesize that information. Because otherwise, it's hard to figure out, you know, like, what is just normal? This is just life as a developer [laughs]. And what are opportunities to maybe gain some more insight about the work itself? JOËL: One thing that I've learned over time as a developer, and I'm not sure if this quite rises to the level of a heuristic, but a lot of, like, pain and frustration in development doesn't necessarily have to be that way. And it's not necessarily because I'm bad at the job or I'm too new to the technology or whatever. It can often be a sign of underlying design issues or the fact that the system was modeled with certain assumptions that are no longer true. These can often be signals that you can make things better. So, I think if I had to reduce this idea down to a clever one-liner, it'd be something along the lines of, it can be better, or it doesn't have to be this bad. You're writing a test, and it's really annoying. There might be a better way to structure the underlying code that would make the test better. You're having to do some, like, really clunky code to deal with something. Is there maybe a better object design that would make a lot of that pain go away, or at least kind of quarantine it in a certain part of the codebase? STEPHANIE: I actually think you're really onto something because what I was just hearing, I love that, like, it can be better. It's less prescribed, I guess, than some other heuristics, like, you know, do not repeat yourself, or whatever. JOËL: Classic. STEPHANIE: [laughs] It really encourages, like, the individual to think a little deeper. And it actually reminded me of another...this is actually a bit of a pithy saying, but I find it to be really useful. And I'm curious if you've heard it before. It's a systems thinking heuristic, and the phrase is, the purpose of a system is what it does. JOËL: Ooh, I have heard that, and I'm trying to remember what context. STEPHANIE: So, it was coined by a systems thinking expert. Stafford Beer, I think, is his name. And I recently learned about it from a friend. But I think the cool thing is that it can be applied to literally anything [laughs] because everything is a system, you know, or not just software. But I have found a lot of value in applying it to just, like, is this function doing what it says it does, right? Or is it actually also doing, like, a side effect? And turns out, maybe we want to bring that into alignment with what the name of the function is, or try pulling that out, or whatever. I think it can also be true of test suites. I don't know if this is a heuristic or not. But the idea that we should always be testing or all tests are good, yeah, I guess that could pass as a heuristic. By bringing this perspective of the purpose of a system is what it does, it's like, well, is the test suite also so bloated and takes so long and so flaky that it is actually hindering development? And if that is the case, then maybe there is some reevaluation necessary, right? Rather than just claiming that it's helping us have more confidence in our code when that may or may not be true. JOËL: You brought up an interesting idea here, which is that heuristics aren't always right. So, you're talking about the idea that a heuristic like good code is tested code might not be correct in 100% of the cases. Like, how accurate does a heuristic need to be in order for it to be really valuable? You know, you're hoping for something that's, like, 90% correct that you can follow most of the time, except in some edge cases, or something maybe as low as, like, 50% where it's a coin toss whether the heuristic applies in the situation or not. Are those still useful? Or are they maybe more confusing than otherwise? STEPHANIE: Oh wow. That's a really interesting way to frame it because I don't know if I've ever stored information about how well my heuristics are serving me. [laughs] But I do really like the idea that you can use a heuristic as a guiding principle just to try and that you can always back out of it, right? So, if you're wanting to take DRY to the extremist of extremes, just for fun or just to see how that might go, you can go down that path and, at any point, decide, okay, like, I like this, or I don't like this, and choose a different path. But the idea of kind of tracking, like, how well they're working for you that is really interesting to me, and not something I've tried before. JOËL: I love the idea of taking a heuristic and, like, doing a side project whose whole goal is just to kind of push that heuristic to the extreme, to the breaking point so that, that way, you get an intuition of, like, when does it work for you? When does it not? That sounds like a really fun exercise for someone to do. Is that something that you've done yourself? STEPHANIE: Not to the point of a whole side project, but just like I like to try pickles randomly every now and then to see if I like them, [laughs] will just try a new technique and see how it goes. In an episode a while back, we talked about whether we TDD or not, and, to be honest, I don't do it, you know, 100% of the time or all the time. But one day, I did decide to TDD a full-stack feature from start to finish just for fun [laughs], and I enjoyed it. I learned some things about it. And I think now I've kind of integrated the parts that I liked about it into my development flow. Like, I'm not always going to do it. But I think it also just helped me figure out, like, okay, like, what is this thing about that people claim that is the pinnacle of how we should be writing our code? And how can I decide for myself, like, whether it works for me or just pick and choose the parts of it that work for me? JOËL: Yeah. That just seems like a really valuable exercise. There are definitely too many heuristics out there to do that for everything. But I guess I've never thought of it quite so concretely. But I almost wonder if I should, like, add this to my kind of personal growth plan to say, like, once a year, I'm going to take a heuristic and kind of push it to an extreme and see what I can learn about it. STEPHANIE: I actually think what's really cool is the process of, like, any individual developer figuring out what kinds of heuristics they want to follow, as opposed to, you know, like, a mass proclamation that, like, this is the way, right? Are there any heuristics that you have maybe picked up and then let go of because you realized that, you know, they weren't working enough or frequently enough for you or that you just didn't like? JOËL: I don't know about, like, fully letting go, but definitely kind of recontextualize and sometimes even sort of rewrote them a little bit to work for me. So, a classic one would be the idea that shorter code is more readable. So, it's common to see comments on a pull request sort of like, "Hey, you could make this shorter by doing this." And that can be true to a certain extent. When you get to the point where you're playing code golf, it becomes absolutely unreadable. But also, there's a point where sometimes using some other heuristics will result in longer code but actually make it more readable on the whole. And so, packing everything into one method might be overall shorter, so it's fewer lines to read going through a class. But maybe extracting some methods or doing that separating branching code from doing code might lead to an overall longer class but an also overall more readable one. So, I think there's probably a lot of caveats that go with that idea. Oftentimes, shorter can be more readable with, you know, two or three asterisks that maybe go a little bit more into the why that is the case. STEPHANIE: Yeah. I like the contextualizing. That actually reminded me of a talk that I watched recently by Hillel Wayne. It's called Intro to Empirical Software Engineering. And he basically, like, does a deep dive into all these studies about software practices that we think are, quote, unquote, "good," like, as a community or as an industry. And it's like, well, like, how do we actually know? Like, show me the research, right? And one of the studies that he included was trying to determine if using abbreviations for variable names or using the full words made the code easier to debug or not. And so, the main example that he was using was employee number as a variable, and the abbreviation was EMP num. And it turns out that there was no difference in how easy it was to debug. But the approach that each group that was studied differed. So, the folks who had the full names, the full words for the variable names, were kind of using an approach of just scanning the code and being able to understand at a higher level the domain, right? Whereas the folks who were debugging with just abbreviations had to work at a bit of a lower level and, you know, or maybe using breakpoints and debugging the code that way. And I thought that was really cool because, first of all, I think it kind of was trying to prove that, like, we don't actually know if one is better or not. But what is important and interesting to me is the idea that, like, you can choose the method that you like better or that works for you and the human side of it, right? The impact it has on our process. JOËL: That's really cool. I'll have to go and watch that talk. Building this kind of context and nuance around a heuristic, though, takes a lot of time, takes experience. And part of the value of a heuristic is that we're collapsing down maybe our own experience or somebody else's experience into something that doesn't require you to necessarily do all that work upfront. How do you feel about sharing and kind of targeting a lot of these heuristics to newer coders who are kind of trying to get better at their craft and looking for ways to improve without necessarily having to do, you know, five years of experience digging into a particular topic? Do you think heuristics are helpful, or do they maybe mislead? STEPHANIE: I really value when they're presented as an opinion, as opposed to a true fact about code. [laughs] Because I really appreciate when someone is able to explain to me why they chose readability in this particular scenario or why they chose speed and performance. Or maybe they were making a trade-off between accessibility and, you know, something else. To just, like, tell someone, "Oh yeah, like, DRY code is better code," or to just tell someone that without the explanation with, like, offering them the opportunity to reflect themselves on, like, oh, like, where have I seen DRY code that was easier for me to read? That seems a little less helpful in terms of investing in their growth. JOËL: Yeah. Definitely, I think sharing some of the purpose behind it can often be really useful because most of these heuristics are never an end unto themselves. They're a means to some other end. So, you're not writing code that's DRY just because you want to be cool. You're writing code to be DRY because you're trying to improve readability, make it easier to change so you don't have to change it in multiple places. You want to maybe reduce the chance of certain types of bugs. These are all actual purposes of what you want to do in your code. DRY is just one way of getting there. But oftentimes, we might skip that part and just be like, hey, you should make your code DRY because DRY is the best. And it can be, but it's in service to these other goals. STEPHANIE: I think when I am sharing those types of heuristics that are more commonly held, I also do like to preface, like, some people think this, or some people like to do things this way, just to be clear that they don't have to like it or do it. In general, I always prefer injecting more nuance [laughs] into the conversation. But yeah, like, it is a really personal process, I think, and figuring out, like, how any individual makes decisions about, like, all the code they're writing. You have to make a million [laughs] decisions every time you do it. So, yes, like, those heuristics do provide a shortcut. And also, I think it's worth taking the time to think about if it's working, especially for the specific context that you're applying it, right? Because that also can change. And, I don't know, maybe I'm just skeptical of any one size fits all solution. JOËL: I think for myself, with many heuristics, as a beginner coder, I had a bit of, like, a spiral journey, or maybe kind of going up a set of stairs. So, as a brand-new developer, I would make a lot of duplication bugs in my code, where, you know, I would have the same value in multiple places, and then I'd change it in one place, and I don't remember to change it in other places, and the code breaks. And so, being introduced to the idea of DRY actually helped my code get quite a bit better. It was, like, a net positive on my experience because I was not getting burned by all these bugs quite so frequently. And so, for a while, just throwing more DRY into my code just made my life better. And then, eventually, you kind of hit that plateau where I don't run into the pain of these bugs anymore. But now I keep doing more DRY somewhat mindlessly. And I end up with this pile of abstractions that are actually really brittle or frustrating to work with. And now, I have to rethink some of the assumptions behind the heuristic. And then, at that point, yep, maybe recontextualize a little bit, learn about when it's good, when are the trade-offs not worth it. Now I have a better understanding, and I kind of go on another growth bit where it makes a lot of my code better until maybe I hit another plateau. I've kind of maxed out the benefits. I start seeing some of the pain, and then, again, I have to go through this cycle again. And maybe the approach you were talking about earlier, where you do a side project and kind of push a heuristic to its breaking point, is a way to kind of speed run that process. STEPHANIE: Yeah, that's really interesting because you're just committing to it and trying to learn everything you can from it in a very concentrated setting. I also wonder, and it's totally fine if you don't know, but if someone had told you kind of all of those reasons you listed about why DRY code, like, what that achieves, if that may have reframed how you were thinking about applying it. Or was that also something that had to come from doing it enough? JOËL: I think as a brand-new developer, a lot of that would have gone over my head. I was still really shaky on the concept of abstraction. When is it useful? When is it not? So, a lot of those more subtle pitfalls, I think, would not have been relevant to me at that point in my career, even the concept of readability, right? When I'm a brand-new programmer, I'm still getting used to reading a lot of code. And so, the idea that code might be written in a way that's unreadable or more challenging to read, it might just feel like, oh, I just need to get better, improve myself. It's not that the code is written in a hard-to-read way. It's just I don't have enough experience at reading code. And I think that's a common thing that we do as beginners at everything, right? We start by blaming ourselves when things get hard. STEPHANIE: Yeah. I was just thinking that, you know, if you are sharing heuristics with a newer developer or an early-career developer, at the end of the day, like, really, I'm not sure about the value of just dropping it on them and letting them run [laughs] with it. But I think what could be really, really effective is just having a sustained relationship with them and, like, continuing that conversation. It's, like, maybe in a code review or in a pairing session being like, "Oh yeah, like, I see you're practicing DRY. Like, what do you think about how this made this piece of code different?" And kind of baking in that process of self-discovery along the way and speeding it up in that way as well. JOËL: So, what you're really saying is the one heuristic to rule them all is code in community. STEPHANIE: I love that. I'm totally with you. JOËL: On that note, shall we wrap up? STEPHANIE: Let's wrap up. Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeee!!!!!! ANNOUNCER: This podcast is brought to you by thoughtbot, your expert strategy, design, development, and product management partner. We bring digital products from idea to success and teach you how because we care. Learn more at thoughtbot.com.

The Bike Shed
396: Build vs. Buy

The Bike Shed

Play Episode Listen Later Aug 8, 2023 33:57


Joël has been fighting a frustrating bug where he's integrating with a third-party database, and some queries just crash. Stephanie shares her own debugging story about a leaky stub that caused flaky tests. Additionally, they discuss the build vs. buy decision when integrating with third-party systems. They consider the time and cost implications of building their own integration versus using off-the-shelf components and conclude that the decision often depends on the specific needs and priorities of the project, including how quickly a solution is needed and whether the integration is core to the business's value proposition. Ruby class instance variables (https://www.codegram.com/blog/understanding-class-instance-variables-in-ruby/) Build vs Buy by Josh Clayton (https://thoughtbot.com/blog/build-vs-buy-considerations-for-new-products) Sustainable Rails (https://sustainable-rails.com/) Transcript: STEPHANIE: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Stephanie Minn. JOËL: And I'm Joël Quenneville. And together, we're here to share a bit of what we've learned along the way. STEPHANIE: So, Joël, what's new in your world? JOËL: My world has been kind of frustrating recently. I've been fighting a really frustrating bug where I'm integrating with a third-party database. And there are queries that just straight-up crash. Any query that instantiates an instance of an ActiveRecord object will just straight-up fail. And that's because before, we make the actual query, almost like a preflight query that fetches the schema of the database, particularly the list of tables that the database has, and there's something in this schema that the code doesn't like, and everything just crashes. Specifically, I'm using an ODBC connection. I forget exactly what the acronym stands for, Open Database connection, maybe? Which is a standard put up by Microsoft. The way I'm integrating it via Ruby is there's a gem that's a C extension. And somewhere deep in the C extension, this whole thing is crashing. So, I've had to sort of dust off some C a little bit to look through. And it's not super clear exactly why things are crashing. So, I've spent several days trying to figure out what's going on there. And it's been really cryptic. STEPHANIE: Yeah, that does sound frustrating. And it seems like maybe you are a little bit out of your depth in terms of your usual tools for figuring out a bug are not so helpful here. JOËL: Yeah, yeah. It's a lot harder to just go through and put in a print or a debug statement because now I have to recompile some C. And, you know, you can mess around with some things by passing different flags. But it is a lot more difficult than just doing, like, a bundle open and binding to RB in the code. My ultimate solution was asking for help. So, I got another thoughtboter to help me, and we paired on it. We got to a solution that worked. And then, right before I went to deploy this change, because this was breaking on the staging website, I refreshed the website just to make sure that everything was breaking before I pushed the fix to see that everything is working. This is a habit I've picked up from test-driven development. You always want to see your test break before you see it succeed. And this is a situation where this habit paid off because the website was just working. My changes were not deployed. It just started working again. Now it's gotten me just completely questioning whether my solution fixes anything. The difficulty is because I am integrating [inaudible 03:20] third-party database; it's non-deterministic. The schema on there is changing rather frequently. I think the reason things are crashing is because there's some kind of bad data or data that the ODBC adapter doesn't like in this third-party system. But it just got introduced one day; everything started breaking, and then somehow it got removed, and everything is working again without any input or code changes on my end. So, now I don't trust my fix. STEPHANIE: Oh no. Yeah, I would struggle with that because your reality has come crashing down, [laughs] or how you understood reality. That's tough. Where do you think you'll go from here? If it's no longer really an issue in this current state of the schema, is it worth pursuing further at this time? JOËL: So, that's interesting because it turns into a prioritization problem. And for this particular project, with the deadlines that we have, we've decided it's not worth it. I've opened up a PR with my fix, with some pretty in-depth documentation for why I thought that was the fix and what I think the underlying problem is. If this shows up again in the next few days, I'll have that PR that I can pull in and see if it fixes things, and if it doesn't, I'll probably just close that PR, but it'll be available for us if we ever run into this again. I've also looked at a few potential mitigating situations. Part of the problem is that this is a, like, massive system. The Rails app that I'm using really doesn't need to deal with this massive database. I think there's, you know, almost 1,000 tables, and I really only care about a subset of tables in, like, one underlying schema. And so, I think by reducing the permissions of my database user to only those tables that I care about, there's a lower chance of me triggering something like this. STEPHANIE: Interesting. What you mentioned about, you know, having that PR continue to exist will be really helpful for future folks who might come across the same problem, right? Because then they can see, like, all of the research and investigation you've already done. And you may have already done this, but if you do think it's a schema issue, I'm curious about whether the snapshot of the schema could be captured from when it was failing to when it has magically gotten fixed. And I wonder if there may be some clues there for some future investigator. JOËL: Yeah. I'm not sure what our backup situation is because this is a third-party system, so I'd have to figure out what things are like in the admin interface there. But yeah, if there is some kind of auditing, or snapshots, or backups, or something there, and I have rough, you know, if I know it's within a 24-hour period, maybe there's something there that would tell me what's happening. My best guess is that there's some string that is longer than expected or maybe being marked as a CHAR when it should be a VARCHAR, or maybe something that's not a non-UTF-8 encoded character, or something weird like that. So, I never know exactly what was wrong in the schema. There's some weird string thing happening that's causing the Ruby adapter to blow up. STEPHANIE: That also feels so unsatisfying [laughs] for you. I could imagine. JOËL: Yeah, there's no, like, clean resolution, right? It's a, well, the bug is gone for now. We're trying to make it less likely for it to pop up again in the future. I'm trying to leave some documentation for the next person who's going to come along, and I'm moving forward, fingers crossed. Is that something you've ever had to do on one of your projects? STEPHANIE: Given up? Yes. [laughter] I think I have definitely had to learn how to timebox debugging and have some action items for when I just can't figure it out. And, you know, like we mentioned, leaving some documentation for the next person to pick up, adding some additional logging so that maybe we can get more clues next time. But, you know, realizing that I do have to move on and that's the best that I can do is really challenging. JOËL: So, you used two words here to describe the situation: one was giving up, and the other one was timebox. I think I really like the idea of describing this as timeboxing. Giving up feels kind of like, defeatist. You know, there's so many things that we can do with our time, and we really have to be strategic with how we prioritize. So, I like the idea of describing this as a timeboxing situation. STEPHANIE: Yeah, I agree. Maybe I should celebrate every time that I successfully timebox something [laughs] according to how I planned to. [laughs] JOËL: There's always room to extend the timebox, right? STEPHANIE: [laughs] It's funny you bring up a debugging mystery because I have one of my own to share today. And I do have to say that it ended up being resolved, [chuckles] so it was a win in my book. But I will call this the case of the leaky stub. JOËL: That sounds slightly scary. STEPHANIE: It really was. The premise of what we were trying to figure out here was that we were having some flaky tests that were failing with a runtime error, so that was already kind of interesting. But it was quickly determined it was flaky because of the tests running in a certain order, so-- JOËL: Classic. STEPHANIE: Right. So, I knew something was happening, and any tests that came after it were running into this error. And I was taking a look, and I figured out how to recreate it. And we even isolated to the test itself that was running before everything else, that would then cause some problems. And so, looking into this test, I saw that it was stubbing the find method on an ActiveRecord model. JOËL: Interesting. STEPHANIE: Yeah. And the stubbed value that we were choosing to return ended up being referenced in the tests that followed. So, that was really strange to me because it went against everything I understood about how RSpec cleans up stubs between tests, right? JOËL: Yeah, that is really strange. STEPHANIE: Yeah, and I knew that it was referencing the stub value because we had set a really custom, like, ID value to it. So, when I was seeing this exact ID value showing up in a test that seemed totally unrelated, that was kind of a clue that there was some leakage happening. JOËL: So, what did you do next? STEPHANIE: The next discovery was that the error was actually raised in the factory setup for the failing tests and not even getting to running the examples at all. So, that was really strange. And digging into the factories was also its own adventure because there was a lot of complexity in the factories. A lot of them used hooks as well that then called some application code. And it was a wild goose chase. But ultimately, I realized that in the factory setup, we were calling some application code for that model where we had stubbed the find, and it had used the find method to memoize a class instance variable. JOËL: Oh no. I can see where this is going. STEPHANIE: Yeah. So, at some point, our model.find() returned our, you know, stub value that we had wanted in the previous test. And it got cached and just continued to leak into everything else that eventually would try to call that memoized method when it really should have tried to do that look-up for a separate record. JOËL: And class instance variables will persist between tests as long as they're on the same thread, right? STEPHANIE: Yeah, as far as I understand it. JOËL: That sounds like a really frustrating journey. And then that moment when you see the class instance variable, and you're like, oh no, I can't believe this is happening. STEPHANIE: Right? It was a real recipe for disaster, I think, where we had some, you know, really complicated factories. We had some sneaky caching issues, and this, you know, totally seemingly random runtime error that was being raised. And it was a real wild goose chase because there was not a lot of directness in going down the debugging path. I feel like I went around all over the codebase to get to the root of it. And, in the end, you know, we were trying to come up with some takeaways. And what was unfortunate was that you know, like, normally, stubbing find can be okay if you are, you know, really wanting to make sure that you are returning your mocked value that you may have, like, stubbed some other stuff on in your test. But because of all this, we were like, well, should we just not stub find on this really particular model? And that didn't seem particularly sustainable to make as a takeaway for other developers who want to avoid this problem. So, in the end, I think we scoped the stub to be a little more specific with the arguments that we wanted to target. And that was the way that we went forward with the particular flaky test at hand. JOËL: It sounds like the root cause of the problem was not so much the stub as it was the fact that this value is getting cached at the class level. Is that right? STEPHANIE: Yes and no. It seems like a real pain for running the tests. But I'm assuming that it was done for a good reason in production, maybe, maybe not. To be fair, I think we didn't need to cache it at all because it's calling a find, which is, you know, should be pretty quick and doesn't need to be cached. But who knows? It's hard to tell. It was really old code. And I think we were feeling also a little nervous to adjust something that we weren't sure what the impact would be. JOËL: I'm always really skeptical of caching. Caching has its place. But I think a lot of developers are a little too happy to introduce one, especially doing it preemptively that, oh well, we might need a cache here, so why not? Let's add that. Or even sometimes, just as a blind solution to any kind of slowness, oh, the site is slow; let's throw a cache here and hope for the best. And the, like, bedrock, like, rule zero of any kind of performance tuning is you've got to measure before and after and make sure that the change that you introduce actually makes things better. And then, also, is it better enough speed-wise that you're willing to pay any kind of costs associated to maintaining the code now that it's more complex? And a lot of caches can have some higher carrying costs. STEPHANIE: Yeah, that's a great point. This debugging mystery an example of one of them. JOËL: How long did it take you to figure out the solution here? STEPHANIE: So, like you, I actually was on a bit of the incorrect path for a little while. And it was only because this issue affected a different flaky test that someone else was investigating that they were able to connect the dots and be like, I think these, you know, two issues are related. And they were the ones who ultimately were able to point us out to the offending test if you will. So, you know, it took me a few days. And I imagine it took the other developer a few days. So, our combined effort was, like, over a week. JOËL: Yep. So, for all our listeners out there, you just heard that Stephanie and I [laughs] both went on multi-day debugging journeys. That happens to everyone. Just because we've been doing this job for years doesn't mean that every bug is, like, a thing that we figure out immediately. So, separately from this bug that I've been working on, a big issue that's been front of mind for me on this project has been the classic build versus buy decision. Because we're integrating with a third-party system, we have to look at either building our own integration or trying to use some off-the-shelf components. And there's a few different levels of this. There are some parts where you can actually, like, literally buy an integration and think through some of the decisions there. And then there's some situations where maybe there's an open-source component that we can use. And there's always trade-offs with both the commercial and the open-source situation. And we have to decide, are we willing to use this, or do we want to build our own? And those have been some really interesting discussions to have. STEPHANIE: Yeah. I think you actually expanded this decision-making problem into a build versus buy versus open source because they are kind of, you know, really different solutions with different outcomes in terms of, you know, maintenance and dependencies, right? And that all have, like, a little bit of a different way to engage with them. JOËL: Interesting. I think I tend to think of the buy category, including both like commercial off-the-shelf software and also open-source off-the-shelf software, things that we wouldn't build custom for ourselves but that are third-party components that we can pull in. STEPHANIE: Yeah, that's interesting because I had a bit of a different mental model because, in my head, when you're buying a commercial solution, you, you know, are maybe losing out on some opportunities for customization or even, like, forking it on your own. So, with an open-source solution, there could be an aspect of making it work for you. Whereas for a commercial solution, you really become dependent on that other company and whether they are willing to cater [laughs] to your needs or not. JOËL: That's fair. For something that's closed-source where you don't actually have access to the code, say it's more of a software as a service situation, then, yeah, you're kind of locked in and hoping that they can provide the needs that you have. On the flip side, you are generally paying for some level of support. The quality of that varies sometimes from one vendor to another. But if something goes wrong, usually, there's someone you can email, someone you can call, and they will tell you how to fix the problem, or they will fix it on their end. STEPHANIE: For the purposes of this conversation, should we talk about the differences, you know, building yourself or leaning on an existing built-out solution for you? JOËL: The project I'm working on is integrating with a Snowflake data warehouse, which is an external place that stores data accessible through something SQL-like. And one of the things that's attractive about this is that you can pull in data from a variety of different sources, transform it, and have it all stored in a kind of standardized structure that you can then integrate with. So, for pulling data in, you can build your own sort of ingestion pipeline, if you want, with code, and their APIs, and things. But there are also third-party vendors that will give you kind of off-the-shelf components that you can use for a lot of popular other data sources that you might want to pull. So, you're saying; I want to pull from this external service. They've probably got a pre-built connector for it. They can also do things like pull from an arbitrary Postgres database on some other server if that's something you have access to. It becomes really attractive because all you need to do is create an account on this website, plug in a few, like, API keys and URLs. And, all of a sudden, data is just flowing from one third-party system into your Snowflake data Warehouse, and it all just kind of works. And you don't have to bother with APIs, or ODBC, or any of that kind of stuff. STEPHANIE: Got it. Yeah, that does sound convenient. As you were talking about this, I was thinking about how if I were in the position of trying to decide how to make that integration happen, the idea of building it would seem kind of scary, especially if it's something that I don't have a lot of expertise in. JOËL: Yeah, so this was really interesting. In the beginning of the project, I looked into a little bit of what goes into building these, and it's fairly simple in terms of the architecture. You just need something that writes data files to typically something like an S3 bucket. And then you can point Snowflake to periodically pull from that bucket, and you write an import script to, you know, parse the columns and write them to the right tables in the structure that you want inside Snowflake. Where things get tricky is the actual integration on the other end. So, you have some sort of third-party service. And now, how do you sort of, on a timer maybe, pull data from that? And if there are data changes that you're synchronizing, is it just all append-only data? Or are you allowing the third-party service to say, "Hey, I deleted this record, and you should reflect that in Snowflake?" Or maybe dealing with an update. So, all of these things you have to think about, as well as synchronization. What you end up having to do is you probably boot up some kind of small service and, you know, maybe this is a small Ruby app that you have on Heroku, maybe this is, like, an AWS Lambda kind of thing. And you probably end up running this every so many seconds or so many minutes, do some work, potentially write some files to S3. And there's a lot of edge cases you have to think about to do it properly. And so, not having to think about all of those edge cases becomes really enticing when you're looking to potentially pay a third party to do this for you. STEPHANIE: Yeah, when you used the words new service, I bristled a little bit [laughs] because I've definitely seen this happen maybe on a bit of a bigger scale for a tool or solution for some need, right? Where some team is formed, or maybe we kind of add some more responsibilities to an existing team to spin up a new service with a new repo with its own pipeline, and it becomes yet another thing to maintain. And I have definitely seen issues with the longevity of that kind of approach. JOËL: The idea of maintaining a fleet of little services for each of our integrations seemed very unappealing to me, especially given that setting something like this up using the commercial approach probably takes 30 minutes per third-party service. There's no way I'm standing up an app and doing this whole querying every so many minutes, and getting data, and transforming it, and writing it to S3, and addressing all the edge cases in 30 minutes. And it's building something that's robust. And, you know, maybe if I want to go, like, really low tech, there's something fun I could do with, like, a Zapier hook and just, like, duct tape a few services together and make this, like, a no-code solution. I still don't know that it would have the robustness of the vendor. And I don't think that I could do it in the same amount of time. STEPHANIE: Yeah. I like the keyword robustness here because, at first, you were saying, like, you know, this looked relatively small in scope, right? The code that you had to write. But introducing all of the variables of things that could go wrong [laughs] beyond the custom part that you actually care about seemed quite cumbersome. JOËL: I think there's also, at this point, a lot of really interesting prioritization questions. There are money questions, but there are also time questions you have to think about. So, how much dev time do we want to devote upfront to building out these integrations? And if you're trying to move fast and get a proof of concept out, or even get, like, an MVP out in front of customers, it might be worth paying more money upfront to a third-party vendor because it allows you to ship something this week rather than next month. STEPHANIE: Yeah. The "How soon do you need it?" is a very good question to ask. Another one that I have learned to include in my arsenal of, you know, evaluating this kind of stuff comes from a thoughtbot blog by Josh Clayton, where he, you know, talks about the build versus buy problem. And his takeaway is that you should buy when your business is not dependent on it. JOËL: When it's not part of, like, the core, like, value-add that your business is doing. Why spend developer time on something that's not, like, the core thing that your product is when you can pay someone else to do it for you? And like we said earlier, a lot of that time ends up being sunk into edge cases and robustness and things like that to the point where now you have to build an expertise in a, like, secondary thing that your business doesn't really care about. STEPHANIE: Yeah, absolutely. I think this is also perhaps where very clear business goals or a vision would come in handy as well. Because if you're considering building something that doesn't quite support that vision, then it will likely end up continuing to be deprioritized over the long term until it becomes this thing that no one is accountable for maintaining and caring for. And just causes a lot of, honestly, morale issues is what I've seen when some service that was spun up to try to solve a particular problem is kind of on its last legs and has been really neglected, and no one wants to work on it. But it ends up causing issues for the rest of the development team. But then they're also really focused on initiatives that actually do provide the business value. That is a really hard balancing act that I've seen teams struggle with. JOËL: Earlier this year, we were talking about the book Sustainable Rails. And it really hammers home the idea of a carrying cost for the code, and I think that's exactly what we're talking about here. And that carrying cost can be time and money. But I like that you also mentioned the morale effects. You know, that's a carrying cost that just sort of depresses the productivity of your team when morale is low. STEPHANIE: Yeah, absolutely. I'm curious if we could discuss some of the carrying costs of buying a solution and where you've seen that become tricky. JOËL: The first thing to look at is the literal cost, the money aspect of things. And I think it's a really interesting situation for the business models for these types of Snowflake connectors because they typically charge by the amount of data that you're transmitting, so per row of data that you're transmitting. And so, that cost will fluctuate depending on whether the third-party service you're integrating with is, like, really chatty or not. When you contrast that to building, building typically has a relatively fixed cost. It's a big upfront cost, and then there's some maintenance cost to go with it. So, if I'm building some kind of integration for, let's say, Shopify, then there's the cost I need to build up front to integrate that. And if that takes me, I don't know, a week or two weeks, or however long it is, you know, that's a pretty big chunk of time. And my time is money. And so, you can actually do the math and say, "Well, if we know that we're getting so many rows per day at this rate from the commercial vendor, how many weeks do we have to pay for the commercial one before we break even and it becomes more expensive than building it upfront, just in terms of my time?" And sometimes you do that math, and you're like, wow, you know, we could be going on this commercial thing for, like, two years before we break even. In that case, from a purely financial point of view, it's probably worth paying for that connector. And so, now it becomes really interesting. You say, okay, well, which are the connectors that we have that are low volume, and which are the ones that are high volume? Because each of them is going to have a different break-even point. The ones that you break even after, you know, three or four weeks might be the ones that become more interesting to have a conversation about building. Whereas some of the others, it's clearly not worth our time to build it ourselves. STEPHANIE: The way you described this problem was really interesting to me because it almost sounds like you found the solution somewhere in the middle, potentially, where, you know, you may try building the ones that are highest priority, and you end up learning a lot from that experience, right? That could make it easier or at least, like, set you up to consider doing that moving forward in the future if you find, like, that is what is valuable. But it's interesting to me that you kind of have the best of both worlds of, like, getting the commercial solutions now for the things that are lower value and then doing what you can to get the most out of building a solution. JOËL: Yeah. So, my final recommendation ended up being, let's go all commercial for now. And then, once we've built out something, and because speed is also an issue here, once we've built out something and it's out with customers, and we're starting to see value from this, then we can start looking at how much are we paying per week for each of these connectors? And is it worth maybe going back and building our own for some of these higher-volume connectors? But starting with the commercial one for everything. STEPHANIE: Yeah, I actually think that's generally a pretty good path forward because then you are also learning about how you use the commercial solution and, you know, which features of it are critical so that if you do eventually find yourselves, like, maybe considering a shift to building in-house, like, you could start with a more clear MVP, right? Because you know how your team is using an existing product and can focus on the parts that your business are dependent on. JOËL: Yeah, it's that classic iterative development style. I think here it's also kind of inspired by a strategy I typically use for performance, which is make it work before you try to make it fast. And, actually, make it work, then profile, then measure, find the hotspots, and then focus on making those things fast. So, in this case, instead of speed, we're talking about money. So, it's make it work, then profile, find the parts that are expensive, and make the trade-off of, like, okay, is it worth investing into making that part less expensive in terms of resources? STEPHANIE: I like that as a framework a lot. JOËL: A lot of what we do as programmers is optimization, right? And sometimes, we're optimizing for execution time. Sometimes we're optimizing for memory cost, and sometimes we're optimizing for dollars. STEPHANIE: Yeah, that's really interesting because, with the buy solution, you know very clearly, like, how much the thing will cost. Whereas I've definitely seen teams go down the building route, and it always takes longer than expected [laughs], and that is money, right? In terms of the developer's time, for sure. JOËL: Yeah, definitely, like, add some kind of multiplier when you're budgeting out that build alternative because, quite likely, there are some edge cases that you haven't thought about that the commercial partner has, and you will have to spend more time on that than you expected. STEPHANIE: Yeah, in addition to whatever opportunity cost of not working on something that is driving revenue for the business right now. JOËL: Exactly. STEPHANIE: So, the direction of this conversation ended up going kind of towards, like, what is best for the team at, like, a product and company level. But I think that we make these decisions a lot more frequently, even when it comes to whether we pull in a gem or, you know, use an open-source tool or not. And I would be really interested in discussing more of that in another episode. JOËL: Yeah. That gets into some controversial takes, right? It's the evergreen topic of: do we build it ourselves, or do we pull in some kind of third-party package? STEPHANIE: Something for the future to look forward to. On that note, shall we wrap up? JOËL: Let's wrap up. STEPHANIE: Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeeee!!!!! ANNOUNCER: This podcast is brought to you by thoughtbot, your expert strategy, design, development, and product management partner. We bring digital products from idea to success and teach you how because we care. Learn more at thoughtbot.com.

The Bike Shed
395: Human Connection in a Virtual (Work) World

The Bike Shed

Play Episode Listen Later Aug 1, 2023 30:59


Stephanie had a small consulting win: saying no to a client. GeoGuessr is all the rage for thoughtbot's remote working culture, which leads to today's topic of forming human connections in a virtual (work) environment. GeoGuessr (https://www.geoguessr.com/) Strategies for saying no by Elle Meredith (https://www.youtube.com/watch?v=_2zWwwjnuUA) NYT Let's Ignore Each Other in the Same Room (https://www.nytimes.com/2021/09/24/well/live/parallel-play-for-adults.html) Random question generator (https://standup-questions.vercel.app/) Transcript: JOËL: And this is just where it ends. [laughter] Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Joël Quenneville. STEPHANIE: And I'm Stephanie Minn. And together, we're here to share a bit of what we've learned along the way. JOËL: So, Stephanie, what's new in your world? STEPHANIE: So, I have a small consulting win, or even just a small, like, win as a human being [laughs] that I want to share, which is that I feel good about a way that I handled saying no to a stakeholder recently. And, you know, I really got to take them where I can get it because that is so challenging for me. But I feel really glad because we ended up kind of coming out the other side of it having a better understanding of each other's goals and needs. And so, basically, what happened was I was working on a task, and our product owner on our team asked me if it could be done by next week. And immediately, I wanted to say, "Absolutely not." [laughs] But, you know, I took a second and, you know, I had the wherewithal to ask why. You know, I was kind of curious, like, where was this deadline coming from? Like, what was on her radar that, like, wasn't on mine? And she had shared that, oh, you know, if we were able to get it out before this big launch, she was thinking that it actually might make our customer support team's lives easier because we were kind of taking away access to something before some new features rolled out. And, you know, there might be some customers who would complain. And with that information, you know, that was really helpful in helping me understand. And I'm like, yeah, like, that seems like a helpful thing to know, so I could try to strive for it. Because I also, like, want to make that process go easier as well. But I told her that I'd let her know because I honestly wasn't sure if it was possible to do by next week. And after a little bit of, you know, more digging, kind of seeing how my progress was going, in the end, I had to say that I didn't feel confident that we could finish it in time for that deadline because of the other risks, right? Like, I didn't want to just release this thing without feeling good about the plan that we had. And so, that was my small, little win in saying no, and I feel very proud of myself for it. JOËL: I'm proud of you too. That's not easy to just do in the first place, and then to do it well is a whole other level. It sounds, though, that you came out of the other side with the client with almost, like, a better relationship. STEPHANIE: Yeah, I think so. In general, you know, I really struggle when people do end up getting into that debate of, like, "Well, I need this." And someone else says, "Well, I need this other thing." And, you know, at some point, it kind of gets a bit unproductive, right? But I think this was a very helpful way for me to see a path forward when maybe we, like, have different priorities. But, like, can we better understand each other and the impact of them to ultimately, like, make the best decision? The other thing that I wanted to share that I learned recently was there was a recent RailsConf talk by Elle Meredith, and it was about strategies to say no, and I watched it. And one really cool thing that I learned was that the word priority, you know, when it was first created, it actually didn't really have, like, a plural form. There was really only ever, like, a singular priority. And it wasn't until, I think, you know, the recent century or something like that, that people started to use it in a plural form. And that was really enlightening to me. I think it made me rethink the word and how I use it, and it made a lot of sense, too. Because at any given moment, you know, really, you can't be doing more than one thing; I mean, you can try. I know that I have been guilty of multitasking. But that, you know, doesn't always serve me. I never end up doing all of the things that I'm trying to do well. And I would be really curious to kind of, you know, when I do feel that urge, like, think a little bit about, like, what is the one thing that I should be doing right now that is the highest priority? JOËL: I would definitely second that recommendation for this talk. I actually got to see it live at RailsConf, and it was excellent. STEPHANIE: So, Joël, what's new in your world? JOËL: I got to participate in a really fun event at thoughtbot today. We got together with some other people on the Boost Team and played a few rounds of GeoGuessr. And for those who are not familiar with this game, it drops you randomly somewhere in the world in Google Street View. You can move around. And there's a timer, and you have to drop a pin on a map where you think you are. So, you're walking through the streets, and you're like, okay, well, I don't know this language. I'm not sure where we're going. You know, with the vibes going here, I'll bet, you know, this looks like maybe southern China, and then you drop a pin. And oh no, turns out it was actually Singapore. And there's all these little hints and things. People who are really into it have learned all these tricks, and they can be really good. Sara Jackson, who is our resident GeoGuessr expert, is excellent at this. But it was a good time. STEPHANIE: Yeah, it was really fun. I liked that we played a cooperative mode where we were all kind of helping each other out. And so, maybe someone is, like, exploring on the map and sees a street sign and is like, "Oh, like, that looks like this language." And someone else is like, "Oh yeah, like, that is that." Or like, "No, I think it's actually this other language," and sharing all of the different, like, pieces of information that we're finding to get closer and closer to what it might be. And then we celebrate whoever ends up getting the closest because, at some point, it's kind of just, like, just a luck of the pin, right? Where maybe you happen to click on, like, the right place. But it's always really exciting when we're like, wow, like, Sara was only 500 kilometers away in finding the exact place that we were served. So, I had a good time as well. JOËL: So, speaking of cooperative events, this was a work event that we did. We just got together and played a game. And, for me, that was a really fun way to connect with some of my colleagues. I'm curious, what are your thoughts on things that you've seen done well in companies that are remote-first that really foster a sense of connection and community among a team? STEPHANIE: I think this worked especially well today because it was kind of scheduled in regular time that we have as a team to me. And sometimes, you know, the meeting topics are a bit more work-focused. But what I really like is that anyone on the team can host one of these meetings. We have them biweekly, and we just call them Boost biweeklies. Boost is the team that Joël and I are on. JOËL: Naming is the hardest problem in computer science. STEPHANIE: It really is. But I really like that people can bring, you know, a little bit of their own flavor to this meeting. So, whoever is host just kind of comes up with something to do. And sometimes it's like show and tell. You know, other times it is more of like, you know, what's the update on some of the projects that we're doing? Other times, it's the Spicy Takes Lightning Talks that we've kind of mentioned on the podcast before. And yeah, it is just a really nice, like, time for us to get together. And I also feel like I learn something about my co-workers every time that we meet, whether it's the person who is hosting the meeting and kind of where their interests are. I think someone even did, like, chair yoga once and guided the team in doing that. Or because they are more casual, right? Sometimes we just play a game, and I really enjoy that nice break in my day. JOËL: Do you find that the particular style of these meetings makes you feel more connected to your colleagues? Would you prefer just kind of game day one, like we had today, versus maybe, like, lightning talks or a presentation on security or something like that? STEPHANIE: I actually think the diversity is what makes it special. I get to see, you know, a bunch of different sides of my co-workers and, you know, some days, the topic is a little more serious, and that can be really connecting. Another Boost Team member had hosted a biweekly where we kind of shared the challenges of, like, consulting work and, like, onboarding onto a new project and sharing what might be difficult and, like, how we might be feeling when we do join a new project. And I think that was really helpful because it was very validating for something that I thought, like, maybe I felt a little bit more alone in. And the tone was a little bit more, like, earnest and serious. But I came away with it feeling very supported by my team, right? And other times, it is just silliness and fun [laughs], which, you know, is also important. Like, we need to have fun every once in a while. JOËL: That's awesome. Do you feel like when you go to these meetings, you're looking more for knowledge or looking more for connection? STEPHANIE: I think both because knowledge sharing is also, you know, can be really helpful. Like, I have enjoyed learning that, you know, so and so is, like, a GeoGuessr expert, Sara, right? And so, if I ever, like, find myself needing [chuckles] someone to go to about my Google Street View or world geography questions, I know that I can go to her. And, like, knowing that about her, like, makes me feel more connected to her. So, I think both are true. So, we have been talking about a meeting style form of connecting in a remote workplace, but I'm really curious about your thoughts on asynchronous versus synchronous communication and how you find connection with a format that is more asynchronous, not just, you know, being in a meeting together. JOËL: That's really challenging. I think I personally find that something that's mostly synchronous with maybe a little bit of a lag works pretty well for me, so something like Slack, where it's not exactly real-time because someone could take some time to come back to me. But for working hours overlap, there's likely some close-to-synchronous conversation happening. But, you know, I can still get up and, you know, refill my cup of coffee, or it's not quite like I'm sitting in front of a camera. So, I think that, for many things, hits the sweet spot for myself. But there's definitely some things where I think you want a higher, like, information density. And that's, I think, where the synchronous face-to-face meeting really shines. STEPHANIE: Information density. I haven't heard that phrase before, but I like it. JOËL: The idea being, you know, how much information or how many words are you sharing back and forth, you know, per minute or something like that. And when you're talking on a call, you can do a lot more of that than you can going back and forth over Slack or writing an email. STEPHANIE: So, I would say that at thoughtbot, we have a pretty asynchronous Slack culture, which I think can be quite different from other, you know, places I've worked at before or other Slack spaces that I've seen. And I actually find it a little bit harder to engage in that way. We have a dev channel where, you know, people chat about different technical topics. And sometimes, you know, those threads go, like, 40 replies long. And I think you tend to engage a lot more in those. And I'm curious, like, does that scratch the itch for you in terms of that perfect, like, async, kind of some amount of lag for you to be doing other things, kind of doing your work, but then being able to come back and pick up the conversation where I left off? JOËL: Yes, that is really nice because, you know, maybe I have a meeting or something, and I'm not there when the conversation starts, but I don't miss out. And I get to join in, you know, maybe 30 minutes after everyone else. You know, sometimes you don't want to just, like, restart a conversation that's happened and is done. But some of these things will kind of be going on and off all day. And those can be really fun, especially sometimes, like, a new person joins the thread and brings in a totally new perspective or a new angle that kind of, like, breathes new life into it and kind of gives everyone a new perspective. STEPHANIE: Nice. I also think there's something to the idea of seeing more people engage with something that then invites other people to engage with it. JOËL: I would agree with that. It's definitely exciting to see a thread, and it's not like, oh, it's empty, and I'm the only one who's put a response in here. When there is a lot of back and forth, you can almost feel the excitement. And that gets me hyped to, like, keep it going. STEPHANIE: At a previous workplace in our Slack, we had a, like, virtual Jeopardy channel. JOËL: Ooh. STEPHANIE: And so, there was a little Jeopardy bot. And I guess whenever someone, you know, had a low on what they were doing, they would just start, you know, tagging the bot to pose a question. And anyone can answer, right? But once you kind of got the ball rolling, you would see other people start playing as well. And it would get really active for segments of 30 minutes or so. And I always really enjoyed that because, yeah, it was a way for me to remember like, oh yeah, there's, like, other people also, like, typing away on their little keyboards, and we're all here together. But it was really interesting to see, like, when someone got it rolling, like, oh, other people, like, joined in. JOËL: Yeah, being able to see small things like that can really build a sense of connection, even if you're not yourself directly participating. STEPHANIE: Yeah. I think another thing I've been trying out lately is letting people know that I'm in a meeting space and offering to virtually co-work. So, you know, during the early days of when thoughtbot went remote, we had a lounge virtual meeting space for people to hang out with and, you know, get that face time that they weren't getting anymore since we weren't in the office. And, you know, I think that has kind of decreased in terms of engagement over, you know, several years now. And obviously, people have a lot of meeting fatigue and stuff like that. But I was kind of in a mood to revive it a little bit because, yeah, I kind of got over the meeting fatigue and was wanting more face time with people. And the unfortunate thing, though, is that, like, no one was showing up to this room anymore. So, you know, even if someone wanted to hang out in it, you know, they go in. They see no one's there, you know, maybe they stay for a few minutes, but then they're like, okay, well, I'm just going to leave now. And a couple of thoughtboters and I have been trying to revive it where we'll post in our general channel, like, "Hey, like, I'm in this meeting room. Like, come hang out for the next hour if you would like." And that's been working well for me. I have had a few, like, really nice lounge, virtual co-working hangout sessions. Even if one person shows up, honestly, like, that fulfills my want to just, like, speak to another human. [laughs] JOËL: What does virtual co-working look like? Are you just kind of each doing work, but you've got a video camera on, and you're just aware of the presence of someone else? Do you kind of have, like, random breaks where you talk? What is that experience like? STEPHANIE: Oh yeah, that's a good question. I have to say; for me, I'm just talking to the other [laughs] person at that point. I'm not really doing a whole lot of work. And, you know, in some ways, I almost think that, like, in those moments, I am really wanting to chat with someone and, like, that's okay, right? JOËL: It's like a virtual water cooler for you. STEPHANIE: Yeah, exactly. Like, that would be the moment if I were working in office that I would wander into the kitchen looking for a snack but also an unsuspecting victim to start [laughs] a conversation with. JOËL: I feel you. I feel you. I have absolutely done that. STEPHANIE: Yeah. And that's actually what makes me feel a little less guilty about it. Because, you know, when I was working in the office, like, that was such a big part of my day, and it's kind of what kept me motivated. And at home, I do find myself, like, a lot more productive. In fact, like, I think I am because I'm, you know, not spending that time wandering into the kitchen. But at what cost? [laughs] At the cost of, like, me feeling very, like, lonely and, like, kind of burnt out at the end of the day. So, injecting my day with some of these moments, I think, is important to me. And also, again, like, I know that I'm being really productive in my, like, heads-down-time that I want to, you know, allow myself to just like, get that dose of connection. JOËL: I know, for me, when we were doing things like this in person as well, those conversations that happen, yes, there's some random, frivolous stuff, but sometimes, it is a conversation related to work that I'm doing. Because, you know, someone who's not on my project is like, "Hey, how's your project going?" Or whatever. I'm like, "Oh, well, I'm, you know, doing this ODBC connection, and I'm kind of stuck." And, you know, we kind of talk about a few things. It's like, "Oh, did you know about this gem?" And it's like, "Wait, why didn't I talk to you earlier? Because this totally solves my problem." STEPHANIE: Yeah, I think that being a sounding board is so valuable as well. So, I guess I enjoy virtual co-working, not necessarily, you know, us, like, sitting together and doing our work separately. Though I know that there's value in that, especially in real life. Like, I remember reading an article. I'll try to find it and link it. But the idea of just, like, sharing space with someone can be, like, a form of bonding. But I do really enjoy just hearing about what other people are working on and just kind of, like, asking questions about it, right? And maybe we do take away, like, a new perspective or, like, have some insights about, like, the work itself. And, yeah, we don't really get that when we're working remotely by ourselves because there's no one to turn to and be like, "Hey, what do you think about this problem?" JOËL: I love how no matter what the topic is that we're discussing on this show, you always have a book or an article or something that you've read that you can reference. And I think that's amazing. STEPHANIE: Thank you. JOËL: So, you're talking about things that have really helped you feel a deeper sense of connection. I had a realization recently about the power of physical items. In particular, as consultants, sometimes we work with clients who, for security reasons, want us to work on a dedicated laptop for this particular client. And so, we'll have clients maybe—well, now that we're remote—ship us a laptop, and we work on that laptop when we're doing client stuff, and then on our thoughtbot laptops when we're doing thoughtbot things. And when I've been on clients like that, I have felt much more isolated from the thoughtbot team. And just, like, physically switching over to the thoughtbot laptop, all of a sudden, gives me that feeling of connection. And there's something I can't quite explain about the power of the physical item. And, say, I'm working on the thoughtbot laptop today with, you know, thoughtbot Slack in the background or whatever, and I feel more connected to my colleagues. STEPHANIE: Yeah, that is really curious. Did you also have thoughtbot communication channels open in your client laptop during that time? JOËL: I did, and yet still felt more separation. STEPHANIE: Yeah, that's really interesting. The way you're describing it, it was almost like, you know, the main laptop that you work with, with your, like, all of the settings that you like, all of your little shortcuts, you know, the autocomplete to the whatever, like, channels of communication that you are used to seeing. In some ways, that almost feels like home a little bit. And I wonder if working on a client laptop almost kind of feels like, you know, being in a stranger's house, right? JOËL: There's definitely an element of that. Yeah, all the little things I've fine-tuned, some of the productivity software I have on there that are just, you know, I can one by one set them up on the client laptop, depending on permissions. But yeah, it's never quite the same. STEPHANIE: So, when you are in a situation where you're mostly working from a client laptop and maybe embedded in their Slack workspace, embedded in their team, how do you go about investing in connection with your client team? JOËL: So, you know what's kind of weird? Is that when I'm on a client laptop, I feel less connected to my colleagues at thoughtbot, but the reverse is not necessarily true. I don't feel more connected to colleagues on a client team on a client laptop than I would on my thoughtbot laptop. So, I'm not exactly sure what the psychology is going on there. But I feel kind of most connected to both when I'm working on my thoughtbot laptop, which is perhaps a bit strange. STEPHANIE: Oh, yeah, that is interesting. I think, in general, there's an aspect of joining a new client team and trying to figure out the culture there and how you might engage with it, right? And how what you bring to the table kind of fits in with how they do things, and how they talk about things, and how they behave. In some ways, it's kind of, like, you know, an outsider joining this, like, in-group, right? So, I've definitely realized that the ways that I engage and feel connected at thoughtbot, like, may or may not work for the client team that I'm joining. JOËL: Yeah. And onboarding onto a client team is not just a technical exercise, right? It's also a social process where you want to get to know the other people on your team, get to sort of integrate into the way they work, their processes, hopefully, build a little bit of, like, personal connection with individuals because all of those are going to help me do my job better tomorrow, and the day after, and the week after that. STEPHANIE: Yeah. I had mentioned previously that one thing that I've been enjoying on my client team is our daily sync question. So, a random question will be generated, you know, like, "What are you eating for dinner today?" Or, like, "What are you looking forward to this weekend?" And folks are able to share. And the fun thing is that sometimes the answer to the question is longer than their work update itself. JOËL: Nice. STEPHANIE: But that is actually the, you know, the beauty of it because we all just, like, get to laugh and get to, you know, chime in. And I'm like, "Oh yeah, like, that sounds delicious, like, what you're eating for dinner tonight." But, like, that would not work for our Boost Team's sync because, you know, it's a much bigger meeting with sometimes up to, you know, 20 to almost 30 people and, like, we can't quite have as much time spent talking about the fun question of the day. So, I definitely think that, you know, it depends your team size, and makeup, and whatnot. JOËL: Are those questions kind of preset, or do you all get to contribute questions to the list? STEPHANIE: We brainstormed the questions one retro when we were realizing that we were kind of getting a little bored of the existing question that we had. And we came up with a handful that is plugged into, like, a website, or, like, an app that randomly, you know, picks the question of the day. And so, I think, again, when we get a little bored of the ones that we have in rotation, we'll throw in some curveballs in there. JOËL: Have you ever considered adding "What's new in your world?" to this rotation? STEPHANIE: It's funny you mentioned that because it's actually the question that we got a little bit stale on. [laughs] JOËL: Really? STEPHANIE: And we needed to inject some new life into, yeah. It's a classic, you know. But I think the variety is nice, especially since we're meeting almost every day. And before we started recording, you and I were just talking about how even sometimes it's tough to think of something that's new in our world [laughs] because we don't always live the most interesting and, you know, new lives. And sometimes, we kind of just have to dig deep to come up with something, and we only meet weekly. [laughs] JOËL: I can definitely see how doing this daily might be more challenging. I think there's also value in questions that are a little bit more focused. Part of what's fun for this podcast is that "What's new in your world?" is so kind of broad. But maybe for something daily, having something really specific, like, what did you eat for dinner tonight? Means that you aren't just kind of drawing blanks in your mind, like, uh, uh, what is new in my world? What have I done? I don't know; I have a boring life. I don't do anything. Kind of panic mode that you can sometimes get when you hit a meeting. And so, I do know that when I've been sometimes in situations with people where you have questions like that, I've tended to really appreciate the more targeted ones. STEPHANIE: Yeah, that's so interesting you mentioned that because I think in social situations, there's usually maybe, like, someone who is really good at asking those, like, specific questions to get the group talking and, like, you know, engaged in a fun conversation, and that specificity helps. One thing that I was just wondering about is the value of meeting every day in a sync kind of format, and I'm curious if you think that is important to you. If you have been on other teams that don't meet every day, maybe they have, like, a virtual check-in, right? Like, a virtual reminder to share what they're working on as opposed to meeting synchronously. JOËL: I think I've seen sort of different purposes for sync meetings. Sometimes it's very kind of project-heavy, right? You're talking about the tickets you're working on for today. The reason you're having that is specifically for status updates or because you are blocked, and you want somebody else to help unblock you. So, it's very process-focused. I think that varies team to team, but it can be really helpful. Even I've been on projects where it's maybe me and one other person, and we'll have kind of an informal just call each other up every morning and say, "Hey, here's what I'm working on today. Here's kind of roughly the strategy I plan to take on it. And we'll go back and forth." And for something like that, it inevitably also somewhat turns into a bit of a social call, so that's planning and social. And I think that can be really strong. STEPHANIE: Yeah, I like that a lot. JOËL: That's not necessarily going to be the case for every team, every project, especially with larger teams. And I feel like for something like the Boost Team at thoughtbot, we have a daily sync. We're not all working on the same project. So, I don't want to know about the specific details of the ticket you're working on. I'm more interested in getting just a little bit of face time with the whole of our team to feel a connection. And, you know, maybe if you've got something cool that you want to share, and that can be a win. It can even be a struggle. And we can all kind of empathize, right? That, like, "Oh, I dropped production database this morning, and I'm kind of freaking out," is a totally fine thing to share. But "I am working on ticket 1, 2, 3, 4 to add some text to a part of the page," that's not particularly useful to me in the kind of sync that we have for the thoughtbot Boost Team. STEPHANIE: Yeah, absolutely. I think knowing, like, who the audience is of the meeting and, like, how they might be able to support you or be there for you is helpful in making them feel a little more relevant and personal. And I had mentioned that our Boost daily meetings or daily syncs, you know, are a little too big for people to really get into, you know, sharing a fun, personal anecdote, or whatever. But one thing that I really enjoy is that whoever goes last in giving their update gets to choose the sign-off for everyone. So maybe that's like, okay, we'll just go out on a wave, and we all wave. Or maybe it's, you know, like, making a little heart with your hands. And then there's some folks on the team who go really wild and, you know, come up with something totally unexpected. And I think, you know, that spontaneity is so fun. And we all share it in this collective act of...I'm trying to think of a funny one lately, maybe, like, sinking down into your chair until you disappear from the view [laughs]. That's a good one. JOËL: Sometimes it's those, like, small social rituals that can be really meaningful. STEPHANIE: Absolutely. Do you have a favorite sign-off that you have either requested or have done? JOËL: So, I typically just go for the wave if I'm last because I've not thought about it. But I generally think it's fun to have everybody try to mimic an emoji. So, it might be like, oh, everybody do the, you know, See-No-Evil emoji, or everybody do the party parrot. Those are pretty fun to sign off on. STEPHANIE: Oh yeah, [inaudible 29:15] pausing is good. I think another one I like is, "Everyone do your best impression of a tree." [laughs] JOËL: Sometimes, too, it's fun to do something that's relevant to the particular day. If there's something special happening that day, you get something relevant. I've done before, if it's on a Friday, say, "Everybody do your best Rebecca Black impression." STEPHANIE: Yeah, also excellent. JOËL: Because, you know, it's Friday. STEPHANIE: Yeah, like, a little moment of collective celebration for the weekend. On that note, it's a Friday we're recording this episode. Shall we wrap up and look forward to the weekend? JOËL: [laughter] Fun, fun, fun, fun. STEPHANIE: Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeee!!!!!! ANNOUNCER: This podcast is brought to you by thoughtbot, your expert strategy, design, development, and product management partner. We bring digital products from idea to success and teach you how because we care. Learn more at thoughtbot.com.

The Bike Shed
394: Submitting a Conference Talk Proposal from Start to Finish

The Bike Shed

Play Episode Listen Later Jul 25, 2023 38:53


Joël recently had a fascinating conversation with some friends about the power of celebrating and highlighting small wins in their lives. He talks about bringing this into his work life. May Stephanie interest you in a secret she learned regarding homemade pizza? RubyConf is coming! Who's submitting talks?! It's hekkin scary. Don't fret! Joël and Stephannie are here to help. Today, they discussed submitting a conference talk proposal from start to finish. Sheet pan pizza (https://anewsletter.alisoneroman.com/p/may-we-interest-you-in-a-party-of) RubyConf CFP (https://sessionize.com/rubyconf-2023/) Speakerline.io (https://speakerline.io/) WNB.rb (https://www.wnb-rb.dev/) Transcript: STEPHANIE: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Stephanie Minn. JOËL: And I'm Joël Quenneville. And together, we've come here to share a bit of what we've learned along the way. STEPHANIE: So, Joël, what's new in your world? JOËL: I've been having a really interesting conversation with some of my friends recently about the power of celebrating and highlighting small wins in our lives, both in, like, kind of sharing it with each other, like, you know, if something small happens, it's good for me to share it with my friends. But also, where it becomes really cool is where the friend group kind of gets together and celebrates that small win for one person, and how that can be, like, a small step to take, but it's just really powerful and encouraging for a friend group. And I think that applies not just among friends but in a team or other grouping in the workplace. STEPHANIE: That's so fun. How are you celebrating these small wins, like, over text? Is that the main way you're communicating something good that happened? JOËL: It depends on the friend group. I think, like, different friend groups will have, like, a different kind of cadence for the kind of things they do. And do they all hang out together? Do they have a group text, things like that? One of the friend groups I'm a part of, we meet weekly to go climbing at a rock-climbing gym, so that's kind of our hang-out. And [inaudible 01:34], we're there to do stuff at the gym, but it's also a social thing. And it's an opportunity to be like, "Oh, you know, did that thing workout, you know, at work?" "You know, good for you," Or "Did you get this project accepted?" And yeah, when small wins come up, it's a great time to celebrate. STEPHANIE: That's awesome. I think having regular time that you see people and being able to ask them about something that they had mentioned previously is so special and really important to me, like, in bonding and building the relationship. I also love the idea of celebrating milestones. So, this is, I guess, more of a bigger win, but milestones that aren't traditionally celebrated. You know, so, yeah, we'll have, like, a party when someone graduates or someone gets married. But I also have really enjoyed celebrating when someone gets a promotion at work. And, you know, maybe that's not, like, a once-in-a-lifetime thing, but it's still so worthy of going out for dinner or buying them a drink. I also will maybe, like, send my friends a little treat if I know that they did something small but hard for them, right? And sometimes that's even, like, responding to a scary email that they had sitting in their inbox for a while. Yeah, I really love that idea of supporting people, even in the small things in life that they do. JOËL: Yeah, and that's really validating, I think when you've done something hard and then a friend or a colleague reaches out to you. And it's kind of like, hey, I saw that. Good for you. STEPHANIE: How have you been thinking about bringing this into your work life? JOËL: I think it's about being on the lookout for things that other people do. And I think one thing I like to do is kind of publicly calling that out. It sounds like a negative thing, right? But just giving people kind of a public shout-out when they've succeeded at something. I think we're all kind of socialized not to maybe talk too much about accomplishments, especially if they feel kind of small and mundane. Being somebody else, I think, gives you a lot more leeway to say, "Hey, no, Stephanie, I see that you did that thing. And maybe it feels kind of like, oh no, you're just doing your job, but I think that's cool. And I want to, you know, just give you a shout-out in the company Slack channel or something." It doesn't have to be something big. You know, I'm not sending champagne to your home. But having that opportunity to just kind of celebrate something small and say, "Wait a minute, let's pause and acknowledge that you just did something cool." STEPHANIE: Yeah, I was thinking about how that's kind of, like, amplifying the win a little bit. I've definitely done this before, too, when I see someone share a win of theirs, maybe in a smaller Slack channel or kind of a personal level, or even just to me individually. And I really want other people to know that that happened to you and that they, you know, did an awesome job. And so, I have enjoyed, you know, sharing them more publicly on their behalf if they are comfortable with it. JOËL: And I'll say on the other end of that, I think it feels really good to be acknowledged by someone else that you've done something that they recognize. It's fun to share a win with other people because you're excited, but it's doubly fun when somebody else shares it for you. STEPHANIE: I agree. I think one thing that you, Joël, do really well, actually, is sharing your own personal wins in a very casual way. That's something I've always admired about you is how you recognize the small wins for yourself. JOËL: It's taken me, I think, a long time to get to that and find a way where, you know, you are sharing things that are fun for other people to see, things that might be inspiring, things that are kind of cool, and that are not just kind of, like, self-aggrandizing, like, bragging about stuff. It can be a fine line to walk. And, to a certain extent, you're a little bit marketing yourself. But yeah, I think I've kind of hit that right balance. STEPHANIE: Yeah, I think the thing that makes it work is that there's usually, like, a challenge or something that maybe you, like, went through a journey or overcame a little bit. And I think that's what is the inspiring part that makes me feel like, oh, okay, so, like, this is a realistic thing that, you know, Joël went through and, you know, he struggled with it maybe. But then, like, ultimately, you know, had some insights or came out the other side with some learnings. And I like that it's real, right? It's not just, "Hey, like, I did this, like, cool thing." It's like, "I went on this journey." And I find that really motivating when I am in that kind of situation next time. JOËL: There's a power to stories, right? And I think especially when you can make something relatable to other people. So, it's not just like, "Hey, I did a cool thing," which, you know, is also fun. But being able to say, "Hey, I messed up," or "I, you know, had this challenging problem dropped in my lap, and here's the journey I went on to resolve it. Hopefully, it acts a little bit as like a here's a template you could follow if you're ever in that situation." But maybe also a little bit of, like, inspiration for others as well, just being like, hey, Joël, messes up sometimes. So, Stephanie, what is new in your world? STEPHANIE: Speaking of small wins, I have finally perfected our at-home pizza situation for making pizza at home, which I have been struggling with for so long. Because I always was excited by the idea of making pizza and, you know, sometimes we would make our own dough. And sometimes, we would buy store-bought dough, but it never ended up being as crispy and cooked well-done the way that I want it to. It was always, like, a little bit mushy on the inside. The dough wasn't totally baked. And I would inevitably be disappointed when I had been, you know, building that excitement for pizza. And the other week, I found a new recipe to try, and I think it will be my new go-to recipe for making pizza at home. JOËL: I don't know if I'm allowed to ask this on air, but what's the secret? STEPHANIE: The secret? Well, okay, the first secret and/or learning that I've gathered is to not put as much sauce, cheese, and toppings as you think you want to because that's definitely what contributes to the under-doneness of the dough. But I pivoted to trying a more grandma-style crust that is kind of more like focaccia; really, you know, it involves a lot of olive oil. And you're cooking it for a while on pretty high heat to ensure the crispness and, you know, that it's cooked through. And, I mean, I love focaccia bread, so I don't mind it as, you know, the base of my pizza. It is a bit different from, you know, other kinds of pizzas. And if we had, like, a really, you know, fancy pizza oven to do the, like, super high heat, like, Neapolitan-style deal, I would also really enjoy that. But you know what? That's just not the reality of my home kitchen. So, I have really been enjoying this pizza recipe by Alison Roman that I will link in the show notes. But yeah, it has really changed my at-home pizza game. And I hopefully won't have any of my, you know, soggy dough bottom problems anymore. JOËL: So, you mentioned just kind of offhand, like, oh yeah, you know, the crust is just kind of, like, how you make focaccia. It sounds like you've made focaccia yourself before. STEPHANIE: I have made focaccia at home, and so I think applying it to Pizza was a real, like, light bulb moment for me. But, you know, it's not, like, totally effortless. But I think it's a lot more forgiving than other types of bread and, therefore, other types of pizza crust. And the one really enjoyable thing about making focaccia is there's a step where you use your fingers, and you're kind of holding your hands like you're playing a piano. And you, like, press into the dough after it has risen a little bit to create dimples and, you know, lets the oil kind of seep into the little holes. And it's very satisfying. It's a very good feeling. JOËL: The kind of the tactile aspect of it? STEPHANIE: Yeah, exactly. It's very fun. [chuckles] So, yeah, it's just an added bonus to my pizza adventures. JOËL: A win on top of a win. We'll take it. So, there's some news in the Ruby community this week because RubyConf has just opened their CFP, their call for proposals. And so, they're asking for people to submit their ideas for conference talks, and if you're lucky, you get picked to speak at the conference. And, Stephanie, I know that over the course of a year, you have a document where you collect conference talk ideas so that you have ideas to work on when the CFP comes around. Are you looking at any of them to potentially submit to RubyConf this year? STEPHANIE: Joël, I have to be honest with you; so far, I only have one idea on that list. [laughs] But that is one that I suppose could eventually become a conference talk proposal. So, when I heard the news, I definitely went down the rabbit hole of revisiting that idea and kind of starting to think about if it's something I wanted to pursue. I think the answer is yes. I definitely got a big push of motivation when I was like, oh, it's open. Like, now I can just get started if I want to. And then I was like, well, it's open for a month, so I could also just sit on it a little longer, you know, put it aside and revisit it when I have a little more time. But yeah, I was pretty excited because I think it gave me the motivation I needed to really think a little more deeply about this idea that I have. Otherwise, I think it would have continued to sit half-baked in my document for a long time. JOËL: And just for all of our listeners, the CFP just opened on July 12th, and it closes on August 20th. So, if you are listening and it's before August 20th, you still have a shot to submit your idea to be a speaker. STEPHANIE: Something that I've talked about with my other friends who enjoy speaking at conferences is how they come up with proposals, and I found that we all have different approaches. And I am really interested in digging into this further with you. But I realized that, for me, I really struggle with just, like, throwing out ideas and submitting them before I feel really confident that it's something that I have interesting things to say really, or, like, kind of adding a new perspective, or maybe approaching a topic that hasn't been approached before. I feel sometimes a bit hindered by my process, where I need to feel really confident before submitting something. Because a friend of mine she was telling me that her approach is to submit CFP for topic ideas that she wants to explore further. So, maybe it is something that she doesn't know a lot about yet, and she's using this process to learn more and dive deeper, and that, you know, gives her a reason to do that, whereas that seems really scary to me. JOËL: That's really interesting because it sounds like kind of an underlying motivation for your friend for submitting these talks is curiosity, exploration. And thinking back to myself, I think I usually submit ideas that have me excited or passionate, so that's kind of my underlying motivation for a talk. What would you say is maybe your underlying motivation when you're pitching an idea? STEPHANIE: Yeah, I think, for me, it is impact and, like, having an impact, especially for something that I've struggled with and wanting to share my experience and, hopefully, sharing something where other people can relate to. It's funny you mentioned that your motivators are, you know, excitement and passion. Because another person that I kind of had this conversation with mentioned that she writes talks based on experiences that have been very aggravating [chuckles] and painful for her. So, that ends up being, you know, a big motivator because she's so frustrated. [laughs] And, you know, wants to share this journey that she went on from a point of, I guess, maybe similar to me, like, making it easier for someone else who might find themselves struggling with the same problem. JOËL: I kind of like the idea of taking that to an extreme, and you're, like, rage submitting. STEPHANIE: Yeah, I feel like there would just be an infinite number [laughs] of topics that you could come up with in that case. JOËL: Like, I'm so angry at this bug. It cost me a week of my life. And now, it is going to get the spotlight on it at RubyConf. And I get to share that moment with everyone, express a lot of emotions, and, hopefully, save everyone else from having to do the same thing I did. STEPHANIE: Yeah. Or this terrible bug cost me a week of my life, and now you all get to hear about it. [laughter] Let me tell you -- JOËL: Yes. STEPHANIE: Exactly all the problems that I had to deal with. JOËL: And, honestly, as a narrative, it kind of works, right? There are different types of talks. Sometimes you go to a talk because you really want to learn a deep topic. Sometimes I just want to go and listen to, like, a good horror story. If someone's a good storyteller, like, yes, there are lessons I can take away from it, and I can be like, okay, this is what I can do. And I heard Stephanie talk about this bug, and so I'm going to use inspiration from that the next time I hit a bug. But sometimes it's also just good to, like, go there and sit and be, like, yes, I've been there. Yeah, kind of following along with the story and, you know, kind of the ups and downs because it is so relatable. STEPHANIE: Yeah. And I like that you mentioned that there are different types of talks that leave the audience, you know, with different things. Because I know some people who have been interested in speaking in the past maybe feel a bit hesitant to because they don't think they have something to say, or, like, they don't have something to share that other people might find interesting. And to that, I really believe that everyone has something that they are knowledgeable about and something that they can bring to others that is valuable. Even if it's not for every single person at the conference if you give a talk that is meaningful to a handful of people, right? Especially because, you know, there's people of all different kinds of levels at these conferences. Those are really important too. In fact, I think it can be even more powerful because they are targeting a specific audience. JOËL: And I think you've hit on a key point, that is, it's great when you're building the talk, but even when you're pitching the idea is, who is this talk for? Who is the audience for this talk? And if the audience is whoever shows up at the conference center, maybe you need to workshop a little bit more. STEPHANIE: Yeah, because one thing can't really be for everyone. JOËL: Right. You're kind of diffusing its impact at that point. You were talking about how sometimes it's difficult to take an idea, flesh it out, and submit it until you're feeling, like, 100% confident about it. I'm curious how the transition goes from kind of the earlier phase of, like, you have a document, and I assume these are, like, bullet points with, like, one sentence, or maybe even just title idea. How does it go from bullet point to multiple paragraphs that might be submittable? STEPHANIE: Yeah, that's a good question. I think it starts as a bullet point because maybe I notice something that caused me pain or caused a teammate pain, and maybe we had, like, kind of an interesting discussion about it. And, yeah, I write it down as something to explore further as, like, is this an idea that can be a little broader in scope, can have a few more applications beyond this particular instance that sparked it? And so, maybe from there, I will think about, like, okay, like, the pain point that I jotted down was coupling and tests, right? And let me go, you know, jog through my memory of other times where I kind of felt a similar thing or was doing some code review and also noted a similar problem. And I think if I am able to find enough, like, supporting examples that might go along with this, for me, it's really a feeling. [laughs] Then I'll try to extract that a little further and come up with a theme, right? A theme that's a little more encompassing because what I hope to do is to be able to come up with some kind of takeaway that can be a strong thesis for a conference proposal. JOËL: And that's kind of how conference proposals work, right? There's a few different sections you have to fill out. But the really important one is the abstract, which is usually just a few sentences. It's character limited. And that's what is got to sell your talk both to the committee, but then also, that's what's going to be publicly viewable. And so, that's what's going to get people excited to show up at your conference room. So, my kind of secret trick for writing a proposal is to do the abstract last. Even though it's that first section on the form, I struggle to write a compelling abstract. And so, I'll go through and fill out some of the other fields that are only for the committee, and there'll be, you know, a lot of detail in there. And then, sometimes, I find that I put, like, really good compelling sentences in there, and I'll pull them out and put them in the abstract and kind of use that to start. But those other sections, like pitch and all that I think they're a great place to start because you get to go a little bit more into detail. And you can talk about here are the themes I want to address. Here are maybe the examples I'm going to be building around. Here's the audience that I want to speak to. STEPHANIE: Audience is interesting for me because I tend to write the kind of talks that I wish I had watched earlier or, like, what really speaks to me. In fact, one of my first conference talks was literally called The Intro to Abstraction I Wish I'd Received. [laughs] So, that is a good place for me to start, is thinking about like, well, like, who was I at the time? Like, what kind of developer was I at the time that I, like, really needed this information or really wished for this information? And similarly, I had mentioned, you know, like, maybe my ideas are coming from conversations I've had with other people. So, I'm imagining those other people, and I'm asking myself, like, who are they? Like, where are they in their development careers? And is there a specific demographic or audience persona that kind of fits them, and, you know, usually there is, right? And what is nice is I can kind of go to them as well and be like, "Hey, like, I have this idea. Do you think this would be helpful for you? Or is this something you would be interested in watching?" And that at least helps me ground it in an audience that is real to me as opposed to kind of trying to imagine who might show up without a clear idea, like, of what they might get a takeaway or, like, be wanting in a conference talk. JOËL: Would it be fair to say that when you're coming up with an idea for a presentation, the audience you have in mind is you or maybe a particular version of you, so you two years ago or you five years ago? STEPHANIE: Yeah, I think that's a really compelling way for me to write these because, you know, I almost think it kind of goes back to the idea that everyone has something to say, right? It's like I have something to say to me, my past self. And I believe that other people, you know, are in that position as well. And so, that's been my approach. But I'm curious about yours because I think the types of talks that you write are maybe less about, like, what you wished you had learned earlier and more for a different kind of audience. JOËL: Yeah, I think they are...I start with a topic that I'm excited about. And then, sometimes, I have to find what element of it that I want to pull out because it can be kind of a whole kind of cloud of themes, and I have to pick one to commit to. Depending on the one I commit to and the approach I want to take, it will define the audience that...or vice versa. I can say, okay, this is specifically for this audience, and that will show how I want to approach it. So, for example, I gave a talk at RailsConf this past spring on the math every programmer needs, talking a little bit about discrete math and how it's applicable in day-to-day programming. And I think I very quickly came to the realization that I wanted this talk to be for people who had never done a formal, like, discrete math class, likely people who don't have a traditional, like, CS background. And so, once I knew this is the audience I'm speaking to, that really shaped how I pitched the talk, what elements I want to bring in, what examples I'm using, what do I want to emphasize during this talk. Finding that audience really helped that proposal come together. Even though I knew...before I found the audience, I knew I wanted to talk about discrete math and how cool and relevant it was to day-to-day programming. But that's not enough. I needed to really fit it to an audience. STEPHANIE: Yeah, I have two thoughts about this. One was that when you were writing the proposal for this talk, I remember you had shared a bunch of your different ideas about the topic to your co-workers. And it was almost kind of, like, a buffet of topics. And you were asking for feedback about, like, hey, like, what is interesting to you? Like, what would be, like, helpful for you to know? And I think that ended up really helping you focus on, like, what your audience would want. But I'm curious, do you recall, like, how you decided that you wanted to target people who didn't have that traditional CS background? Like, why was that important to you? JOËL: I think I'm generally most excited about taking some, like, larger technical insights and bringing them to people who maybe have some of the intuition but don't always know why the things they do work the way they do and kind of bridging a little bit of that, like, practical, theoretical gap. That's the space that I'm probably most excited about when it comes to sharing and teaching, helping people go from things that are really practical and then just throwing just enough theory at them. But keeping it really grounded so that they can kind of hit the next level of where they want to be. Because that's an area that I think I thrive in, an area that gets me most excited to share about. And so, I think, naturally, I'm kind of moving in that direction. But also, like you said, it's talking to other people and seeing, like, what are the elements that are interesting to you? And then, like, once you start seeing some of these, it's like, okay, well, what is exciting in talking about Boolean algebra? Do I want to go really deep on some of the theory? Do I want to say, you know, if someone has a vague notion of this because they've been writing code for several years but don't know the theoreticals behind it? That interaction, I think, was more compelling to me. STEPHANIE: Got it. It's almost like knowledge sharing at just this really high level, or, like, at a really large scale. I like that a lot. JOËL: So, you highlighted something interesting, and that is that writing a proposal doesn't have to be a solo activity, and getting feedback on ideas can totally transform your proposal. Do you find that you reach out to a lot of people to get feedback on your proposals? And what does that look like in practice? STEPHANIE: Oh yeah, I definitely need someone to rubber-duck an idea for me. [laughs] JOËL: So, even at the idea stage. So, you've got that topic sentence or whatever, and then you say, "Someone, can you sit down with me, and we'll just talk through places this might go?" STEPHANIE: Yeah. I have found that really helpful for me. Otherwise, I think I get a little too precious about it, right? If I've just been working on it by myself. And then it feels really scary to submit it and be like, okay, I don't know if this is any good. It might get rejected. But the first time that I did a conference talk, WNB.rb, the women and non-binary Ruby group I'm in, they had organized a CFP working group channel. And so, there were, you know, a handful of people, some of them writing conference talks for the first time, some of them having done it before, just getting together and holding each other accountable, and checking in and asking for feedback. And, yeah, I think finding other people who either have done it before. I've also, you know, reached out to people whose conference talks I loved and felt really inspired by. And if they were available, like, kind of asking them how to get started. But also, like, peer support as well, other people doing it for the first time can be really important in just making it feel a little more manageable, a little less lonely. I think there are, like, more people out there who are interested in dipping their toe in conference speaking than one might think because it can definitely feel very overwhelming. But with a support group, I think it makes it a lot easier. JOËL: So, you've gotten feedback. You've gotten support. You've put this idea together. You're feeling pretty confident. You hit that submit button. And now you can't take it back. [laughs] How does that feel at that point? STEPHANIE: Terrifying. [laughter] Like, for me, I have to exercise it from my mind and not think about it, not dwell on it at all. And like, ideally, you know, when I hear back, I will have forgotten all about it so that, you know, I didn't spend the whole month or however many weeks, like, ruminating about whether or not it was accepted. Yeah, I really struggle with that part, I think, because I, yeah, have a hard time with rejection, you know, I'm just going to say it. [laughs] And, you know, it's hard for me not to take it personally. But I think that's actually one area that I want to get better at is to feel a little less, like, personally attached. And I think working with others helps me with that because it's not just something I've, you know, like, squirreled away and feel very attached to. Working with others and then, like, hopefully, coming up with other ideas along the way, right? Within conversations that we have that might spark ideas for the future. So, knowing that if this one doesn't end up being submitted, there's always next time. There's always another conference season. And also, you know, celebrating others when their conference talks do get accepted that is also really buoying because it helps me direct that energy into wanting to celebrate my friends and inspiring me for next time. Joël, I know you oftentimes submit more than one proposal, and I'm wondering if that helps with those feelings of being too attached to a topic idea or, you know, worrying about whether they will be accepted. JOËL: I think it definitely helps with the attachment thing that I've not kind of put all of my work and all of my...like, pinned all of my hopes on one topic idea. Sometimes it can hurt, you know, if you've got, like, you know, two or three and, like, you just get multiple rejection notices in a day. That kind of sucks sometimes. But I think, in some ways, yes, it does help with that feeling of rejection because you've not tied yourself emotionally so much to a single idea that has to, like, succeed or fail. STEPHANIE: Do you then submit those ideas to other conferences? JOËL: The ones that get rejected? Yes. I've definitely resubmitted ideas. In fact, I plan to resubmit a rejection to RubyConf this year, so we'll see how that goes. Actually, now that I think of it, that could be a really fun opening line for a talk. Like, let's say it gets accepted. And, like, you know, you're on the stage, and you open it, and you're just like, "This talk got rejected." That'd be a fun intro. STEPHANIE: Yeah, it would be. I think, oftentimes, you know, it's not always even about the idea itself, right? It's just about maybe the theme of the conference that year, and what they were looking for, and the direction they wanted to go. And there are other conferences or other another year, right? Where maybe there isn't another talk that touches on the same, like, area. And that will be the opportunity that it is a fit for the conference. JOËL: Yeah, definitely. It is a little bit haphazard to get in. And just because your talk gets rejected does not mean it's a bad idea. It just means that it wasn't the best fit for that conference at that time. STEPHANIE: I actually want to plug a website, speakerline.io, where people can post all of their, you know, proposals that they've submitted, whether they were accepted or rejected. And I found that resource really helpful in, you know, just knowing that, like, very good ideas get rejected sometimes, and that's okay. As well as, you know, kind of trying to get a sense of, you know, for the ones that were accepted, okay, like, what about these proposals really stood out or, like, really shine? And how might I get some inspiration from that to incorporate next time around? JOËL: So, you've submitted a proposal. Terrifying. You're trying to not think about it for a couple of weeks, assuming you're submitting ahead a couple of weeks, I don't know. Are you a last-minute kind of submitter? STEPHANIE: I'm a probably two or three days before the deadline kind of submitter. JOËL: So, you've submitted the talk two or three days to the deadline. I guess, like, a couple of weeks after that to get review. And then, you get that notification that says, you know, you've got a response on your talk from the committee. Are you the kind of person that, like, drops everything and immediately looks at it? Do you kind of, like, wait for, like, maybe a moment where you're, like, more in a good zone emotionally before you open that email to find out if you're accepted or rejected? What's your strategy? STEPHANIE: Oh God, I don't think I have the willpower to wait until I'm, you know, in an emotionally good state. I will just click on that thing. And yeah, I think, I mean, having been on the receiving end of accepting those rejections and once waitlisted, [laughs] which was a real doozy because it's like, great, like, now I have to write a talk. But, like, I don't know if it will actually be given or not. I think this is also where the support group really shines as well because maybe some of my other friends are also sharing the results and making it okay, like, sharing a rejection, right? And I think it's nice to just have, like, an outlet for that, whatever the outcome is, and not having to just, like, sit alone in either the sadness or the happiness, right? Like, we're talking about celebrating small wins. Like, it really is even more special when someone else can validate your success. JOËL: Have you ever had to navigate kind of, like, slight feelings of jealousy where it's, like, another friend gets in? Or maybe somebody else gets in with, like, your topic, and their talk got picked instead of yours? STEPHANIE: Yeah, for sure. I think it's totally natural and human. I think one nice thing, though, is that there are so many conferences all of the time. You know, this is not a once-in-a-lifetime situation, right? And maybe the next conference, you know, the people who submit will be different, the people who review will be different. And you've kind of already done the hard part of writing the thing. I actually was just thinking about a few of my friends are writers, and the submission process for them, you know, of spinning a book proposal or short stories for, like, a magazine or something like that, it's, like, fraught with rejections. And they've really built that muscle of acceptance and, like, knowing that it's not a reflection of their value, and building the resilience to keep trying. And so, yeah, I think definitely going through that process has helped me feel a little bit more comfortable with that, not completely, but I guess it's like exposure therapy, [laughs], isn't it? JOËL: I think that the not helpful answer here is that it gets better when you've given more talks. When you're trying to break in and give your first talk, right? It is such a big deal. And, you know, the high of getting accepted is just, you know, mountain top. But the feelings of rejection are also similarly intense. As opposed to when you've done a few, then it's like, you know what? Win some, lose some. And it's much easier to move on. STEPHANIE: I think another suggestion that I might have would be to maybe start smaller, right? Even giving a talk at work for your co-workers, or even the next step is giving a talk at your local meetup or then a small regional conference. There are so many in-between steps, I think, that exist that bestow the benefits of giving a conference talk, and meeting new people, and feeling good about the impact you're having beyond some of the bigger, more traditional conferences. So, if that does seem really scary or, you know, maybe you've given it a shot and feel a little bit demoralized from trying again, there is a group out there who will benefit and be interested in hearing what you have to say. JOËL: That's a really important reminder because just because a conference rejected your talk doesn't mean that it's a bad idea. And yes, you can shop it around and bring it to other conferences, but maybe think about other venues for the idea. You've already done the hard work of crafting a pitch, so maybe turn it into a blog post and share it that way. Maybe turn it into a pitch to be a guest on a podcast that you enjoy. Podcasts that do weekly guests are constantly looking for interesting people to talk to. And you've kind of, like, done all the work for them, where you can say, "Hey, here's the thing I'm an expert on. Ask me questions about this." And most places will gladly bring you on. STEPHANIE: Yeah, I like to think of conference talks as really, like, a supplement of what you're learning and investing in in your career, right? You know, it is nice to be able to share all of those things in a perfectly wrapped package. But also, there are so many different ways for that to manifest. And there are people who know that speaking is not for them and really focus on writing, and that's, like, their avenue. But yeah, it's not...I don't think it's, like, a pinnacle of, like, something you have to do in your career at all. It's just something that can be fun. JOËL: Yeah, and sharing takes many different forms. It can be a talk in a conference room, but it can just as easily turn into maybe some kind of video, some kind of written work. Like I said, it could be an interview on a podcast. There are so many different ways that you can share your ideas. And just because it didn't fit in one place, now that you've done the work to kind of polish that gem a little bit, oftentimes, it's very little additional work to just convert it to a different form. STEPHANIE: Yeah, I like what you just said about polishing a gem. Really, I think the value for me is having a channel to funnel and reflect on my experiences, and, you know, conference talks happen to be, like, one form of that for me. But I hate to say it's about the journey, not the destination, but sometimes it is. And, yeah, I think everyone kind of has to, like, figure that out for themselves. JOËL: That being said, sometimes the destination is pretty exciting. And when you open that email that says, "Congratulations, your talk has been accepted," wow, what a rush. STEPHANIE: On that note, shall we wrap up? JOËL: Let's wrap up. STEPHANIE: Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeeee!!!! ANNOUNCER: This podcast is brought to you by thoughtbot, your expert strategy, design, development, and product management partner. We bring digital products from idea to success and teach you how because we care. Learn more at thoughtbot.com.

The Bike Shed
393: Is REST the Best? APIs and Domain Modeling

The Bike Shed

Play Episode Listen Later Jul 18, 2023 33:49


It's updates on the work front today! Stephanie was tasked with removing a six-year-old feature flag from a codebase. Joël's been doing a lot of small database migrations. A listener question sparked today's main discussion on gerunds' interesting relationship to data modeling. Episode 386: Value Objects Revisited: The Tally Edition (https://www.bikeshed.fm/386) RailsConf 2017: In Relentless Pursuit of REST by Derek Prior (https://www.youtube.com/watch?v=HctYHe-YjnE) REST Turns Humans Into Database Clients (https://chrislwhite.com/rest-contortion/) Parse, don't validate (https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/) Wikipedia Getting to Philosophy (https://en.wikipedia.org/wiki/Wikipedia:Getting_to_Philosophy) Transcript: JOËL: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Joël Quenneville. STEPHANIE: And I'm Stephanie Minn. And together, we're here to share a bit of what we've learned along the way. JOËL: So, Stephanie, what's new in your world? STEPHANIE: So, this week, I've been tasked with something that I've been finding very fun, which is removing a six-year-old feature flag from the codebase that is still very much in use in the sense that it is actually a mechanism for providing customers access to a feature that had been originally launched as a beta. And that was why the feature flag was introduced. But in the years since, you know, the business has shifted to a model where you have to pay for those features. And some customers are still hanging on to this beta feature flag that lets them get the features for free. So one of the ways that we're trying to convert those people to be paying for the feature is to, you know, gradually remove the feature flag and maybe, you know, give them a heads up that this is happening. I'm also getting to improve the codebase with this change as well because it has really been propagating [laughs] in there. There wasn't necessarily a single, I guess, entry point for determining whether customers should get access to this feature through the flag or not. So it ended up being repeated in a bunch of different places because the feature set has grown. And so, now we have to do this check for the flag in several places, like, different pages of the application. And it's been really interesting to see just how this kind of stuff can grow and mutate over several years. JOËL: So, if I understand correctly, there's kind of two overlapping conditions now around this feature. So you have access to it if you've either paid for the feature or if you were a beta tester. STEPHANIE: Yeah, exactly. And the interesting thought that I had about this was it actually sounds a lot like the strangler fig pattern, which we've talked about before, where we've now introduced the new source of data that we want to be using moving forward. But we still have this, you know, old limb or branch hanging on that hasn't quite been removed or pruned off [chuckles] yet. So that's what I'm doing now. And it's nice in the sense that I can trust that we are already sending the correct data that we want to be consuming, and it's just the cleanup part. So, in some ways, we had been in that half-step for several years, and they're now getting to the point where we can finally remove it. JOËL: I think in kind of true strangler fig pattern, you would probably move all of your users off of that feature flag so that the people that have it active are zero, at which point it is effectively dead code, and then you can remove it. STEPHANIE: Yeah, that's a great point. And we had considered doing that first, but the thing that we had kind of come away with was that removing all of those customers from that feature flag would probably require a script or, you know, updating the production data. And that seemed a bit riskier actually to us because it wasn't as reversible as a code change. JOËL: I think you bring up a really interesting point, which is that production data changes, in general, are just scarier than code changes. At least for me, it feels like it's fairly easy generally to revert a code change. Whereas if I've messed up the production database, [laughs] that's going to be unpleasant few days. STEPHANIE: What's interesting is that this feature flag is not really supported by a nice user interface for managing it. And so, we inevitably had to do a more developer-focused solution to remove these customers from being able to access this feature. And so, the two options, you know, that we had available were to do it through data, like I mentioned, or do it through that code change. And again, I think we evaluated both options. But what's kind of nice about doing it with the code change is that when we eventually get to delete those feature flag records, it will be really nice and easy. JOËL: That's really exciting. One thing that's different about kind of more mature projects is that we often get to do some kind of change management, unlike a greenfield app where you just get to, oh, let's introduce this new thing, cool. Oftentimes, on a more mature project, before you introduce the new thing, you have to figure out, like, what is the migration path towards that? Is that a kind of work that you enjoy? STEPHANIE: I think this was definitely an exercise in thinking about how to break this down into steps. So, yeah, that change management process you mentioned, I, like, did find a lot of satisfaction in trying to break it up, you know, especially because I was also thinking that you know, maybe I am not able to see the complete, like, cleanup and removal, and, like, where can someone pick up after me? In some ways, I feel like I was kind of stepping into that migration, you know, six years [laughs] in the making from beta to the paid product. But I think I will feel really satisfied if I'm able to see this thing through and get to celebrate the success of saying, hey, like, I removed...at this point, it's a few hundred lines of code. [laughs] And also, you know, with the added business value of encouraging more customers to pay for the product. But I think I also I'm maybe figuring out how to accept like, okay, like, how could I, like, step away from this in the middle and be able to feel good that I've left it in a place that someone else could see through? JOËL: So you mentioned you're taking this over from somebody else, and this has been kind of six years in the making. I'm curious, is the person who introduced this feature flag six years ago are they even still at the company? STEPHANIE: No, they are not, which I think is pretty typical, you know, it's, like, really common for someone who had all that context about how it came to be. In fact, I actually didn't even realize that the feature flag was the original beta version of the product because that's not what it's called. [laughs] And it was when I was first onboarding onto this project, and I was like, "Hey, like, what is this? Like, why is this still here?" Knowing that the canonical, you know, version that customers were using was the paid version. And the team was like, "Oh, yeah, like, that's this whole thing that we've been meaning to remove for a long time." So it's really interesting to see the lifecycle, like, as to some of this code a little bit. And sometimes, it can be really frustrating, but this has felt a little more like an archaeology dig a little bit. JOËL: That sounds like a really interesting project to be on. STEPHANIE: Yeah. What about you, Joël, what's new in your world? JOËL: So, on my project, I've been having to do a lot of small database migrations. So I've got a bunch of these little features to do that all involve doing database migrations. They're not building on each other. So I'm just doing them all, like, in different feature branches, and pushing them all up to GitHub to get reviewed, kind of working on them in parallel. And the problem that happens is that when you switch from one branch where you've run a migration to another and then run migrations again, some local database state persists between the branch switch, which means that when you run the migrations, then this app uses a structure.sql. And the structure.sql has a bunch of extra junk from other branches you've been on that you don't want as part of your diff. And beyond, like, two or three branches, this becomes an absolute mess. STEPHANIE: Oh, I have been there. [laughs] It's always really frustrating when I switch branches and then try to do my development and then realize that I have had my leftover database changes. And then having to go back and then always forgetting what order of operations to do to reverse the migration and then having to re-migrate. I know that pain very well. JOËL: Something I've been doing for this project is when I switch branches, making sure that my structure SQL is checked out to the latest version from the main branch. So I have a clean structure SQL then I drop my local database, recreate an empty one, and run a rake db:schema:load. And that will load that structure file as it is on the main branch into the database schema. That does not have any of the migrations on this branch run, so, at that point, I can run a rake db:migrate. And I will get exactly what's on main plus what gets generated on this branch and nothing else. And so, that's been a way that I've been able to kind of switch between branches and run database operations without getting any cross-contamination. STEPHANIE: Cross-contamination. I like that term. Have you automated this at all, or are you doing this manually? JOËL: Entirely manually. I could probably script some of this. Right now...so it's three steps, right? Drop, create, schema load. I just have them in one command because you can chain Unix commands with a double ampersand. So that's what I'm doing right now. I want to say there's a db:reset task, but I think that it uses migrate rather than schema load. And I don't want to actually run migrations. STEPHANIE: Yeah, that would take longer. That's funny. I do love the up arrow key [laughs] in your terminal for, you know, going back to the thing you're running over and over again. I also appreciate the couple extra seconds that you're spending in waiting for your database to recreate. Like, you're paying that cost upfront rather than down the line when you are in the middle of doing [laughs] what you're trying to do and realize, oh no, my database is not in the state that I want it to be for this branch. JOËL: Or I'm dealing with some awful git conflict when trying to merge some of these branches. Or, you know, somebody comments on my PR and says, "Why are you touching the orders table? This change has nothing to do with orders." I'm like, "Oh, sorry, that actually came out of a different thing that I did." So, yep, keeping those diffs small. STEPHANIE: Nice. Well, I'm glad that you found a way to manage it. JOËL: So you mentioned the up arrow key and how that's really nice in the terminal. Something that I've been relying on a lot recently is reverse history search, CTRL+R in the terminal. That allows me to, instead of, like, going one by one in order of the history, filter for something that matches the thing that I've written. So, in this case, I'll hit CTRL+R, type, you know, Rails DB or whatever, then immediately it shows me, oh, did you want this long command? Hit enter, and I'm done. Even if I've done, you know, 20 git commands between then and the last time I ran it. STEPHANIE: Yeah, that's a great tip. So, a few weeks ago, we received a listener question from John, and he was responding to an episode where I'd asked about what the grammatical term is for verbs that are also nouns. He told us about the phrase, a verbal noun, for which there's a specific term called gerund, which is basically, in English, the words ending in ING. So, the gerund version of bike would be biking. And he pointed out a really interesting relationship that gerunds have to data modeling, where you can use a gerund to model something that you might describe as a verb, especially as a user interaction, but can be turned into a noun to form a resource that you might want to introduce CRUD operations for in your application. So one example that he was telling us about is the idea of maybe confirming a reservation. And, you know, we think of that as an action, but there is also a noun form of that, which is a confirmation. And so, confirmation could be a new resource, right? It could even be backed at the database level. And now you have a simpler way of representing the idea of confirming a reservation that is more about the confirmation as the resource itself rather than some kind of append them to a reservation itself. JOËL: That's really cool. We get to have a crossover between grammar terms and programming, and being able to connect those two is always a fun day for me. STEPHANIE: Yeah, I actually find it quite difficult, I think, to come up with noun forms of verbs on my own. Like, I just don't really think about resources that way. I'm so used to thinking about them in a more tangible way, I suppose. And it's really kind of cool that, you know, in the English language, we have turned these abstract ideas, these actions into, like, an object form. JOËL: And this is particularly useful when we're trying to design RESTful either APIs or even just resources for a Rails app that's server-rendered so that instead of trying to create all these, like, extra actions on our controller that are verbs, we might decide to instead create new resources in the system, new nouns that people can do the standard 7 to. STEPHANIE: Yes. I like that better than introducing custom controller actions or routes that deviate from RESTful conventions because, you know, I probably have seen a slash confirm reservation [laughs] URL. And, you know, this is, I think, an interesting way of avoiding having too many of those deviating endpoints. JOËL: Yeah, I found that while Rails does have support for those, just all the built-in things play much more nicely if you're restricting yourself to the classic seven. And I think, in general, it's easier to model and think about things in a Rails app when you have a lot of noun resources rather than one giant controller with a bunch of kind of verb actions that you can do to it. In the more formal jargon, I think we might refer to that as RESTful style versus RPC style, a Remote Procedure Call. STEPHANIE: Could you tell me more about Remote Procedure Calls and what that means? JOËL: The general idea is that it's almost like doing a method call on an object somewhere. And so, you would say, hey, I've got an account, and I want to call the confirm method on it because I know that maybe underlying this is an ActiveRecord account model. And the API or the web UI is just a really thin layer over those objects. And so, more or less, whatever your methods on your object are, can be accessed through the API. So the two kind of mirror each other. STEPHANIE: Got it. That's interesting because I can see how someone might want to do that, especially if, you know, the account is the domain object they're using at the, you know, persistence layer, and maybe they're not quite able to see an abstraction for something else. And so, they kind of want to try to fit that into their API design. JOËL: So I have a perhaps controversial opinion, which is that the resources in your Rails application, so your controllers, shouldn't map one-to-one with your database tables, your models. STEPHANIE: So, are you saying that you are more likely to have more abstractions or various resources than what you might have at the database level? JOËL: Well, you know what? Maybe more, but I would say, in general, different. And I think because both layers, the controller layer, and the model layer, are playing with very different sets of constraints. So when I'm designing database tables, I'm thinking in terms of normalization. And so, maybe I would take one big concept and split it up into smaller concepts, smaller tables because I need this data to be normalized so that there's no ambiguity when I'm making queries. So maybe something that's one resource at the controller layer might actually be multiple tables at the database layer. But the inverse could also be true, right? You might have, in the example that John gave, you know, an account that has a single table in the database with just a Boolean field confirmed yes or no. And maybe there's just a generic account resource. But then, separately, there's also a confirmation resource. And so, now we've got more resources at the controller layer than at the database layer. So I think it can go either way, but they're just not tightly coupled to each other. STEPHANIE: Yeah, that makes sense. I think another way that I've seen this manifest is when, like you said, like, maybe multiple database tables need to be updated by, you know, a request to this endpoint. And now we get into [chuckles] what some people may call services or that territory of basically something. And what's interesting is that a lot of the service classes are named as verbs, right? So order, creator. And, like, whatever order of operations that needs to happen on multiple database objects that happens as a result of a user placing an order. But the idea that those are frequently named as verbs was kind of interesting to me and a bit of a connection to our new gerund tip. JOËL: That's really interesting. I had not made that connection before. Because I think my first instinct would be to avoid a service object there and instead use something closer to a form object that takes the same idea and represents it as a noun, potentially with the same name as the resource. So maybe leaning really heavily into that idea of the verbal noun, not just in describing the controller or the route but then also maybe the object backing it, even if it's not connecting directly to a database table. STEPHANIE: Interesting. So, in this case, would the form object be mapped closer to your controller resource? JOËL: Potentially, yes. So maybe I do have some kind of, like, object that represents a confirmation and makes it nicer to render the confirmation form on the edit page or the new page. In this case, you know, it's probably just one checkbox, so maybe it's not worth creating an object. But if there were multiple fields, then yes, maybe it's nice to create an in-memory object that has the same name as the resource. Similar maybe for a resource that represents multiple underlying database tables. It can be nice to have kind of one object that represents all of them, almost like a facade, I guess. STEPHANIE: Yeah, that's really interesting. I like that idea of a facade, or it's, like, something at a higher level representing hopefully, like, some kind of meaning of all of these database objects together. JOËL: I want to give a shout-out to talk from a former thoughtboter, Derek Prior—actually, former Bike Shed host—from RailsConf 2017 called In Relentless Pursuit of REST, where he digs into a lot of these concepts, particularly how to model resources in your Rails app that don't necessarily map one to one with a database table, and why that can be a good thing. Have you seen that talk? STEPHANIE: I haven't, but I love the title of it. It's a great pun. It's very evocative, I think because I'm really curious about this idea of a relentless pursuit. Because I think another way to react to that could be to be done with REST entirely and maybe go with something like GraphQL. JOËL: So instead of a relentless pursuit, it's a relentless...what's the opposite of pursuing? Fleeing? STEPHANIE: Fleeing? [laughs] I like how we arrived there at the same time. Yes. So now I'm thinking of I had mentioned a little bit ago on the show we had our spicy takes Lightning Talks on our Boost Team. And a fellow thoughtboter, Chris White, he had given a talk about Why REST Is Not the Best and for -- JOËL: Also, a great title. STEPHANIE: Yes, also, a great title. JOËL: I love the rhyming there. STEPHANIE: Yeah. And his reaction to the idea of trying to conform user interactions that don't quite map to a noun or an obvious resource was to potentially introduce GraphQL, where you have one endpoint that can service really anything that you can think of, I suppose. But, in his example, he was making the argument that human interactions are not database resources, right? And maybe if you're not able to find that abstraction as a noun or object, with GraphQL, you can encapsulate those ideas as closer to actions, but in the GraphQL world, like, I think they're called mutations. But it is, I think, a whole world of, like, deciding what you want to be changed on the server side that is a little less constrained to having to come up with the right abstraction. JOËL: I feel like GraphQL kind of takes that, like, complete opposite philosophy in that instead of saying, hey, let's have, like, this decoupling between the API layer and the database, GraphQL almost says, "No, let's lean into that." And yeah, you want to traverse the graph of, like, tables under the hood? Absolutely. You get to know the tables. You get to know how they're related to each other. I guess, in theory, you could build a middle layer, and that's the graph that gets traversed rather than the graph of the tables. In practice, I think most people build it so that the API layer more or less has access directly to tables. Has that been your experience? STEPHANIE: That's really interesting that you brought that up. I haven't worked with GraphQL in a while, but I was reading up on it before we started recording because I was kind of curious about how it might play with what we're talking about now. But the idea that it's graphed based, to me, was like, oh, like, that naturally, it could look very much like, you know, an entity graph of your relational database. But the more I was reading about the GraphQL schema and different types, I realized that it could actually look quite different. And because it is a little bit closer to your UI layer, like, maybe you are building an abstraction that is more for serving that as that middle layer between your front end and your back end. JOËL: That's really interesting that you mentioned that because I feel like the sort of traditional way that APIs are built is that they are built by the back-end team. And oftentimes, they will reflect the database schema. But you kind of mentioned with GraphQL here, sometimes it's the opposite that happens. Instead of being driven kind of from the back towards the front, it might be driven from the front towards the back where the UI team is building something that says, hey, we need these objects. We need these connections. Can you expose them to us? And then they get access to them. What has been your experience when you've been working with front ends that are backed by a GraphQL API? STEPHANIE: I think I've tended to see a GraphQL API when you do have a pretty rich client-side application with a lot of user interactions that then need to, you know, go and fetch some data. And you, like, really, you know, obviously don't want a page reload, right? So it's really interesting, actually, that you pointed out that it's, like, perhaps the front end or the UI driving the API. Because, on one hand, the flexibility is really nice. And there's a lot more freedom even in maybe, like, what the product can do or how it would look. On the other hand, what I've kind of also seen is that eventually, maybe we do just want an API that we can talk to separate from, you know, any kind of UI. And, at that point, we have to go and build a separate thing [laughs] for the same data. JOËL: So we've been talking about structuring APIs and, like, boundaries and things like that. I think my personal favorite feature of GraphQL is not the graph part but the fact that it comes with a built-in schema. And that plays really nicely with some typed technologies. Particularly, I've used Elm with some of the GraphQL libraries there, and that experience is just really nice. Where it will tell you if your front-end code is not compatible with the current API schema, and it will generate some things based off the schema. So you have this really nice feedback cycle where somebody makes a change to the API, or you want to make a change to the code, and it will tell you immediately is your front end compatible with the current state of the back end? Which is a classic problem with developing front-end code. STEPHANIE: First of all, I think it's very funny that you admitted to not preferring the graph part of GraphQL as a graph enthusiast yourself. [laughs] But I think I'm in agreement with you because, like, normally, I'm looking at it in its schema format. And that makes a lot of sense to me. But what you said was really interesting because, in some ways, we're now kind of going back to the idea of maybe boundaries blurring because the types that you are creating for GraphQL are kind of then servicing both your front end and your back end. Do you think that's accurate? JOËL: Ooh. That is an important distinction. I think you can. And I want to say that in some TypeScript implementations, you do use the types on both sides. In Elm, typically, you would not unless there's something really primitive, like a string or something like that. STEPHANIE: Okay, how does that work? JOËL: So you have some conversion layer that happens. STEPHANIE: Got it. JOËL: Honestly, I think that's my preference, and not just at the front end versus API layer but kind of all throughout. So the shape of an object in the database should not be the same shape as the object in the business logic that runs on the back end, which should not be the same shape as the object in transport, so JSON or whatever, which is also not the same shape as the object in your front-end code. Those might be similar, but each of these layers has different responsibilities, different things it's trying to optimize for. Your code should be built, in my opinion, in a way that allows all four of those layers to diverge in their interpretation of not only what maybe common entities are, so maybe a user looks slightly different at each of these layers, but maybe even what the entities are to start with. And that maybe in the database what, we don't have a full user, we've got a profile and an account, and those get merged somehow. And eventually, when it gets to the front end, all we care about is the concept of a user because that's what we need in that context. STEPHANIE: Yeah, that's really interesting because now it almost sounds like separate systems, which they kind of are, and then finding a way to make them work also as one bigger [laughs] system. I would love to ask, though, what that conversion looks like to you. Or, like, how have you implemented that? Or, like, what kind of pattern would you use for that? JOËL: So I'm going to give a shout-out to the article that I always give a shout-out to: Parse, Don't Validate. In general, yeah, you do a transformation, and potentially it can fail. Let's say I'm pulling data from a GraphQL API into an Elm app. Elm has some built-in libraries for doing those transformations and will tell you at compile time if you're incorrectly transforming the data that comes from the shape that we expect from the schema. But just because the schema comes in as, like, a flat object with certain fields or maybe it's a deeply nested chain of objects in GraphQL, it doesn't mean that it has to be that way in your Elm app. So that transformation step, you get to sort of make it whatever you want. So my general approach is, at each layer, forget what other people are sending you and just design the entities that you would like to. I've heard the term wish-driven development, which I really like. So just, you know, if you could have, like, to make your life easy, what would the entities look like? And then kind of work backwards from there to make that sort of perfect world a reality for you and make it play nicely with other systems. And, to me, that's true at every layer of the application. STEPHANIE: Interesting. So I'm also imagining that the transformation kind of has to happen both ways, right? Like, the server needs a way to transform data from the front end or some, you know, whatever, third party. But that's also true of the front end because what you're kind of saying is that these will be different. [laughs] JOËL: Right. And, in many ways, it has to be because JSON is a very limited format. But some of the fancier things that you might have access to either on the back end or on the front end might be challenging to represent natively in JSON. And a classic one would be what Elm calls a custom type. You know, they're also called tagged unions, discriminated unions, algebraic data types. These things go by a bajillion names, and it's confusing. But they're really kind of awkward and hard, almost impossible to represent in straight-up JSON because JSON is a very limited kind of transportation format. So you have to almost, like, have a rehydration step on one side and a kind of packing down step on the other when you're reading or writing from a JSON API. STEPHANIE: Have you ever heard of or played that Wikipedia game Getting to Philosophy? JOËL: I've done, I think, variations on it, the idea that you have a start and an end article, and then you have to either get through in the fewest amount of clicks, or it might be a timed thing, whoever can get to the target article first. Is that what you're referring to? STEPHANIE: Yeah. So, in this case, I'm thinking, how many clicks through Wikipedia to get to the Wiki article about philosophy? And that's how I'm thinking about how we end up getting to [laughs] talking about types and parsing, and graphs even [laughs] on the show. JOËL: It's all connected, almost as if it forms a graph of knowledge. STEPHANIE: Learning that's another common topic on the show. [laughs] I think it's great. It's a lot of interesting lenses to view, like, the same things and just digging further and further deeper into them to always, like, come away with a little more perspective. JOËL: So, in the vein of wish-driven development, if you're starting a brand-new front-end UI, what is your sort of dream approach for working with an API? STEPHANIE: Wish-driven development is very visceral to me because I often think about when I'm working with legacy code and what my wishes and dreams were for the, you know, the stack or the technology or whatever. But, at that point, I don't really have the power to change it. You know, it's like I have what I have. And that's different from being in the driver's seat of a greenfield application where you're not just wishing. You're just deciding for yourself. You get to choose. At the end of the day, though, I think, you know, you're likely starting from a simple application. And you haven't gotten to the point where you have, like, a lot of features that you have to figure out how to support and, like, complexity to manage. And, you know, you don't even know if you're going to get there. So I would probably start with REST. JOËL: So we started this episode from a very back-end perspective where we're talking about Rails, and routes, and controllers. And we kind of ended it talking from a very front-end perspective. We also contrasted kind of a more RESTful approach, versus GraphQL, versus more kind of old-school RPC-style routing. And now, I'm almost starting to wonder if there's some kind of correlation between whether someone primarily works from the back end and maybe likes, let's say, REST versus maybe somebody on the front end maybe preferring GraphQL. So I'd be happy for any of our listeners who have strong opinions preferring GraphQL, or REST, or something else; message us at hosts@bikeshed.fm and let us know. And, if you do, please let us know if you're primarily a front-end or a back-end developer because I think it would be really fun to see any connections there. STEPHANIE: Absolutely. On that note, shall we wrap up? JOËL: Let's wrap up. STEPHANIE: Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeee!!!!!! ANNOUNCER: This podcast is brought to you by thoughtbot, your expert strategy, design, development, and product management partner. We bring digital products from idea to success and teach you how because we care. Learn more at thoughtbot.com.

The Bike Shed
392: Managing Changing Business Requirements

The Bike Shed

Play Episode Listen Later Jul 11, 2023 39:14


Joël has a fascinating discovery! He learned a new nuance around working with dependency graphs. Stephanie just finished playing a 100-hour video game on Nintendo Switch: a Japanese role-playing game called Octopath Traveler II. On the work front, she is struggling with a lot of churn in acceptance criteria and ideas about how features should work. How do these get documented? What happens when they change? What happens when people lose this context over time? Strangler Fig Pattern (https://shopify.engineering/refactoring-legacy-code-strangler-fig-pattern) Octopath Traveler 2 (https://octopathtraveler2.square-enix-games.com/en-us/) Empowering other departments (https://www.bikeshed.fm/388) Transcript: JOËL: You're the one who controls the pacing here. STEPHANIE: Oh, I am. Okay, great. Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Stephanie Minn. JOËL: And I'm Joël Quenneville. And together, we're here to share a bit of what we've learned along the way. STEPHANIE: So, Joël, what's new in your world? JOËL: So long-time Bike Shed listeners will know that I'm a huge fan of dependency graphs for modeling all sorts of problems and particularly when trying to figure out how to work in an iterative fashion where you can do a bunch of small chunks of work that are independent, that can be shipped one at a time without having your software be in a breaking state in all of these intermediate steps. And I recently made a really exciting discovery, or I learned a new nuance around working with dependency graphs. So the idea is that if you have a series of entities that have dependencies on each other, so maybe you're trying to build, let's say, some kind of object model or maybe a series of database tables that will reference each other, that kind of thing, if you draw a dependency graph where each bubble on your graph points to other bubbles that it depends on, that means that it can't be created without those other things already existing. Then, in order to create all of those entities for the first time, let's say they're database tables, you need to work your way from kind of the outside in. You start with any bubbles on your graph that have no arrows going out from them. That means they have no dependencies. They can be safely built on their own, and then you kind of work your way backwards up the arrows. And that's how I've sort of thought about working with dependency graphs for a long time. Recently, I've been doing some work that involves deleting entities in such a graph. So, again, let's say we're talking about database tables. What I came to realize is that deleting works in the opposite order. So, if you have a table that have other tables that depend on it, but it doesn't depend on anything, that's the first one you want to create. But it's also the last one you want to delete. So, when you're deleting, you want to start with the table that maybe has dependencies on other tables, but no other tables depend on it. It is going to be kind of like the root node of your dependency graph. So I guess the short guideline here is when you're creating, work from the bottom up or work from the leaves inward, and when you're deleting, work from the top-down or work from the root outward or roots because a graph can have multiple roots; it's not a tree. STEPHANIE: That is interesting. I'm wondering, did you have a mental model for managing deleting of dependencies prior? JOËL: No. I've always worked with creating new things. And I went into this task thinking that deleting would be just like creating and then was like, wait a minute, that doesn't work. And then, you know, a few cycles later, realized, oh, wait, deleting is the opposite of creating when you're navigating the graph. And, all of a sudden, I feel like I've got a much clearer mental model or just another way of thinking about how to work with something like this. STEPHANIE: Cool. That actually got me thinking about a case where you might have a circular dependency. Is that something you've considered yet? JOËL: Yes. So, when you have a dependency graph, and you've got a circular dependency, that's a big problem because...so, in the creating model, there is no leaf node, if you will, because they both reference each other. So that means that each of these entities cannot be created on its own, the entire cycle. And maybe you've got only two, but maybe your cycle is, you know, ten entities big. The entire cycle is going to be shipped as one massive change. So something that I often try to do is if I draw a dependency graph out and notice, wait a minute, I do have cyclical dependencies, the question then becomes, can I break that cycle to allow myself to work iteratively? Because otherwise, I know that there's a big chunk that can't be done iteratively. It just has to be done all at once. STEPHANIE: Yeah, that's really interesting because I've certainly been in that situation where I don't realize until it's too late, where I've started going down the path thinking that, you know, I could just remove this one thing, or make this one change, and then find myself suddenly, you know, coming to the realization, oh, this other thing is now going to have to change. And then, at that point, there's almost kind of like the sunken cost fallacy [laughs] a little bit where you're like, well, I'm already in it. So, why don't I keep going? But your strategy of trying to find a way to break that cyclica...that is two words combined. [laughs] I meant to say circular dependency [laughs] is the right way to avoid just having to do it all in one go. Have you had to break up a cycle like that before? JOËL: Yes. I do it on a semi-frequent basis. The fancy term here for what I'm looking for when I'm building out a dependency graph is a directed acyclic graph. That's a graph theory or a computer science term that you'll hear thrown around a lot, DAG. I often like to...when building out a series of tasks that might also form a graph because you don't just model entities in your system; you might model a series of tasks as a graph. If there's a cycle in the graph, typically, I can break that using something like the strangler fig pattern, which is a way to kind of have some intermediate steps that are non-breaking that then lead you to the refactor that you want. And I've used the strangler fig pattern for a long time, never realizing until later that, oh, what I'm actually doing is breaking cycles in my task dependency graph. STEPHANIE: Hmm. I'm curious if you have noticed how these cycles come to be because I almost imagine that they get introduced over time, where you maybe did start with a parent and then you, you know, had dependencies. But then, over time, somehow, that circular dependency gets introduced. And I'm wondering if part of figuring out how to break that cycle is determining how things were introduced, like, over time. JOËL: In my experience, this happens in a lot of different ways because I'm using dependency graphs like this to give myself a mental model for a lot of different kinds of things. So maybe I'm thinking in terms of database tables. And so those might get a circular dependency that gets added over time as the system grows. But I'm also using it sometimes to model maybe a series of tasks. So I take a large task, and I break it down into subtasks that are all connected to each other. And that doesn't tend to sort of evolve over time in the same way that a series of database tables do. So I think it's very context-dependent. But there are definitely situations where it will be like you said, something that kind of evolves over time. STEPHANIE: That makes sense. Well, I'm excited for you to get to deleting some potential code or database tables that are no longer in use. That sounds like a developer's dream [laughs] to clean up all that stuff. JOËL: It's interesting because it's...a move operation is effectively what's happening. So I'm recreating tables in another system, pointing the ActiveRecord to this new system, and then deleting the existing ones in the local database. So, in a sense, I'm kind of traveling up this dependency graph from the leaf nodes into the root and then back down from the root to the leaves as I'm creating and then deleting everything or creating in one system, and then going back and deleting in the other system. STEPHANIE: Got it. Okay, so not necessarily a net negative but, like you said, a move or just having to gradually replace to use a new system. JOËL: That's right. And we're trying not to do this as, you know, okay, we're going to take the system down and move 50 tables from one system to another. But instead, saying, like, you know, one at a time, we're going to move these things over. And it's going to be small, incremental change over the course of a couple of weeks. And they're all pretty safe to deploy, and we feel good about them. STEPHANIE: That's good. I'm glad you feel good. [laughs] We should all be able to feel good when we make changes like that. JOËL: It's going to make my Fridays just so much more low-key just, like, yeah, hit that deploy button. It's okay. So, Stephanie, what is new in your world? STEPHANIE: So this is not work-related at all. But I just finished playing a 100-hour video game on my Nintendo Switch. [laughs] I finished a Japanese role-playing game called Octopath Traveler II. And I have never really played a game like this before. I've not, you know, put in many, many hours into something that then had an end, like, a completion. So, at the end of this very long game that had a very, you know, compelling and engaging story and I was invested in all of these characters, and by the time the credits were rolling, I felt a little sad to be leaving this world that I have been in many evenings over the last couple of months. Yeah, I don't know, I'm feeling both a little sad because, you know like I said, I got really invested in this game, but now I'm also kind of glad to have some free time back in [laughs] my life because that has definitely been the primary, like, evening activity that I've been doing to relax. JOËL: It sounds like this game had a very, like, a particularly immersive world that really pulled you in. STEPHANIE: It did. It did. It has these eight, like, different characters that you follow, like, different chapters and all of their stories, and then they all kind of come together as well. And the world was huge in this game. There were so many little towns to explore. And I didn't realize I was a completionist type. But I found myself running around opening every chest, talking to every NPC, and making sure that I, you know, collected all of my items [chuckles] before moving on. I also finished all of the side quests, which is, I think, you know, how I managed to put in over 100 hours into it. But yeah, it was very immersive, and I really enjoyed it. I don't know if this will become a norm for me. I know there are some people who are, you know, JRPG diehards and play a lot of these kinds of games, but they're a real, like, time investment for sure. JOËL: Are there achievements for completing everything? STEPHANIE: Not that I can tell on the Switch. I do know that, like, on other systems, you can see your progress on having done all of the things there are to do. But I think it's actually kind of better for me to just play [laughs] to just, like, think that I've done it all but not really, like, have something that tells me whether or not I've done it because then I would feel a lot more neurotic, I think, about being able to let it go where I am now. [laughs] JOËL: Right. If we've got, like, an explicit checklist of things or a progress bar, then it feels like you got to get to all the things. STEPHANIE: Yeah, exactly. I think there are still, you know, a couple more things that I wrote down on my little checklist of tasks that I would want to do once I feel like I want to come back to the game. But for now, like I said, I watched the credits roll. I teared up a little bit, you know, thinking about and reminiscing on my adventure with these characters, and I'm ready to put it down for a bit. JOËL: Did I hear correctly that you made a checklist for this game of things you wanted to do? STEPHANIE: Yes, [laughs] I did. JOËL: That's amazing. I love that. STEPHANIE: Yeah, you know, there are just so many things almost kind of like work where I had to, like, break down some of my goals. I wanted to, like, hit a certain level. I wanted to, you know, make sure I defeat these bosses that would help me get to those levels. And yeah, I got very into it. It was definitely a big part of my life for a couple of months. I got it originally because I needed a game to play on my flight to Asia back when I went to Japan. And I'm like, oh, like, this looks, you know, fun and engaging, and it will distract me for my, you know, over 10-hour flight. Turns out it distracted me for many, many more hours over several months [laughs] since then. But I had a great time. So yeah, that's what's new for me. Again, it's something I'd never really done before. I will say though I am very behind on my reading goal as a result. [chuckles] JOËL: I feel like this is a classic developer thing to do is, like, use the tools that we're used to in our job and then apply them to other parts of our life. And now it's just like, okay, well, I made a Kanban board to track my progress in this video game. You know, or, in my case, I'm definitely guilty of having drawn a dependency graph for the crafting tree for some video game. So I feel you really strongly there. STEPHANIE: Yes, I'm nodding heavily in agreement. I think it just scratches the same kind of itch of, you know, achieving, like, little things and then achieving one big thing. JOËL: So, speaking of places that are nice to have checklists and, like, well-defined requirements, you and I were talking earlier, and you have recently found some frustration around having user stories be defined well on your current project. STEPHANIE: Yes. So I've been reflecting a little bit about my current project and noticing what I think I might call product smells; I'm not quite sure, just some things I'm seeing in our day-to-day workflow that is getting me thinking. And I'm curious to hear if you've experienced something similar. But I find myself being tasked with a ticket that is quite vague. And maybe this was written by a product owner, or maybe it was written by another developer. And it is not quite actionable yet, so I have to go through the process of figuring out what I'm really needing to do here. I think another thing that has been quite frustrating is, you know, maybe we do find out what we want to do. And, like, I'll go back into the ticket, write down the requirements that I gathered, and do the ticket. I'll ship whatever change was required, and then I'll hear back from someone in a meeting or either as a one-off request in Slack. And it'll be like, "Hey, like, actually, you know, we want this to be different." And maybe you previously said that "Oh, the value for something would be 30. But now we found out more information; it should be 20. And so could you, like, make that change?" And then I'm not really sure what the best way to document a change like that is because it, you know, maybe existed in the previous ticket, but now it has changed. And do I create a new ticket for this, or do I just go ahead and make the code change? Like, who would know this information that we're now carrying about 20 being the value for, let's say, like, days or not meaning something in the code that we're writing? And I guess I've just been really curious about how to make sure that this doesn't become the norm where a lot of these conversations are just happening, and, you know, the people who happen to be in them know that this change happened. But then later on, someone is asking questions about, like, hey, like, when did this change? Or I expected this to be 30. But is this, you know, behaving as expected? So that was [laughs] a bit of a nebulous way of describing just, like, this churn that I feel with being the executor of work. But then, like, a lot of these things changing above me or separate from me and figuring out how to manage that. JOËL: When you were describing this scenario where you've done the work, and then someone's like, "Oh, could we change this value from, like, 30 to 20?" I'm thinking in my mind of the sort of beam that a lot of our designers face where it's like, you know, they have a design. They work on it; they do it. And then show it to a client, and the client is like, "I love this design. But could we just shift this box over, like, one pixel?" Like, they're, like, tiny, tiny, little changes that are kind of requested for change after you've done, like, this big thing. And, oftentimes, those pile-up. It's like, you shift it one pixel. It's like, oh, actually, you know what? Why don't we do it two pixels? And then it's like never-ending cycles, sometimes of, like, minute little changes. STEPHANIE: Yeah. But the minute changes really add up into, I think, really different behavior than what you maybe had decided as a team originally. And in the process of changing and evolving, I don't really know where documentation fits in. I've been working on this project that had a pretty comprehensive product design doc, where they had decided upfront on, you know, how the application is going to behave in many different scenarios. But again, like, that has changed over time. And when I recently had to onboard someone new to this project, you know, we sent over this document, and we're like, yeah, you can, you know, feel free to peruse it. But it's actually quite outdated. And then, similarly, right now, since the features that I'm working on are going through QA, there's been a lot of back and forth about, I'm seeing this, but the doc said that Y is supposed to happen, and I'm not sure if that's a bug or not. And I or someone else has to respond with that context that we were holding in our head about when that change happened. JOËL: That's really interesting. And I think it varies a lot based off the size of the organization. In a smaller organization, you're probably doing a lot of the requirements gathering yourself. You're talking to all the stakeholders. You're probably doing the QA yourself, or you're walking somebody else through QA. Versus a large organization, there might be an entirely separate product team, and a separate QA team, and a separate dev team. And a danger that I've often seen is where all of these teams are just kind of tossing work over the fence. And all you're given is a, you know, a ticket of, like, execute on this. Basically, turn these specs into code. And then you do that, and then you toss it over the fence to the QA team. And they check does the code do these things? And there's so much context that can easily get lost from one step to another. That being said, I think a lot of devs find it frustrating to do some of the requirements gathering work. How do you feel in general about scoping out a ticket or doing follow-up conversations with the product team about, like, "Hey, your idea for the ticket is this. How do you feel about doing these things? Or what if we cut these things?" Are those conversations that you enjoy having? Is that a fun part of the developer role for you? Or do you kind of wish that, like, somebody else did all of that so that you could, like, go heads down just writing code? STEPHANIE: I think it depends. That's a great question. Actually, I have so many thoughts in response. So let me try to figure out where I want to go from here. But I think I used to not like it. I used to be stressed out by it, and sometimes I still am. But when I thought my role was purely executing, to receive a ticket that is a bit vague, you know, I might have been left feeling, like, stuck, like, not knowing where to go from there. But now that has changed a bit because I received some really helpful feedback from an old manager of mine who was kind of invested in my growth. And she really suggested learning to become more comfortable with ambiguity because that just becomes more and more your job, I think, as you progress in your career. And so now I at least know what information I need to go get and have, you know, strategies for doing so. And also knowing that it's my job, like, knowing that no one else might be doing it, and it might just be me so that I can therefore get this ticket done. Because, like you said, that problem of throwing the work over the fence to someone else, at some point, that doesn't work because everyone has too much on their plates. And you have to just decide to be the one to seek the information that you need. JOËL: I think one way that, as developers, we bring a lot of value is that we help to cut through a lot of that ambiguity. I think if we see our role as merely translating a requirements document into code, that's a very simplistic point of view of what a talented developer does. So, like you said, as we grow in our careers, we start dealing with less and less defined things. We often have to start defining the problems that we're given. And we have to have these conversations with other teams to figure out what exactly we want to do. And maybe better understand why is it that we want to do this thing. What is the purpose of it? How are we going to get there? And my favorite: Do we have to do all of these things to hit the minimum value of this goal? Can I split this into multiple tickets? I love breaking down work. If I can make the ticket smaller, I'm all about that. STEPHANIE: Yes. I'm well aware. It's interesting about what you said, though, is that, like, yes, that becomes, in some ways, our superpower. But, for me, where the pain comes in is when that's not part of the expectations, where I am maybe tasked with something that is not clear enough, and yet, the time that I need to find that clarity is not given the respect that it, I think, deserves to build a good product because the expectation is that I should already be making progress on this ticket and that it will be delivered soon. You know, in that situation, I wish I had been in the room earlier. I wish I had been part of the process for developing the product strategy, or even just, like, have come in earlier to be able to ask, you know, why are we building this? And, like, what are some of the limitations on the technical side that we have? Because often, I find that it is a little too...not necessarily too late, but it is quite down the road that we then have to have these conversations, and it doesn't feel good. JOËL: I think that's one of the powerful things that came out of the agile movement was the idea that you have these cross-functional teams, that you don't have a separate product team, a separate dev team, a separate QA team, a separate design team that are all these isolated islands. But instead, you say, okay, we have a cross-functional team that is working on this aspect of the product. And it will be some product people, some dev people, some designers kind of all working together and communicating with each other. I know, shocking concept. And even depending on the context, a big idea is that the client or the customer is a part of that team. So, when we at thoughtbot work with a client, especially when they are maybe a smaller client like a startup founder, we make sure that they feel like they are a part of the team. They are involved in various meetings where we decide things. They have input. You know, they're part of that feedback cycle that we build. But that can also be the case for a larger company where your internal stakeholders are kind of built-in to be sort of part of your team. STEPHANIE: I've seen so many different flavors of trying to do Agile [laughs] that it has lost a little bit of meaning for me these days. And maybe we've incorporated some aspects of it. But then that idea of the tight feedback loops and then a cross-functional team where everyone is communicating that part has gotten a little bit lost, at least on my project. And I imagine that this is common, and our listeners might be finding themselves in a similar situation where things are starting to feel a little more like handing off and a little more like waterfall. [laughs] I'm curious, though, if you found yourself being requested to make a change from what the original decision was, how would you go about documenting that or not documenting it? Where do you think the best place for that information about how this feature now is supposed to work where should that live? JOËL: Are you talking about where do we document that a decision was made to change the original requirements of a task? STEPHANIE: Yes. JOËL: In general, I think that should live on the ticket just because as long as the ticket is live, I think it's good to have all the context on that ticket for whoever's working on it to have access at a glance. Sometimes it's worth it to say, you know what? We don't want to just keep this ticket live for weeks or maybe months on end. Let's ship this ticket, and create a follow-up to make a change later, especially if it's a change that's less important where it's like, you know what? It would be nice to have if...but, again, like, scope creep is a real danger. And so, again, me with the aggressive breaking up of tickets, I love to say, "That's a great idea. It would make a great change, not part of this ticket." So oftentimes, those changes I will push them into another ticket. STEPHANIE: That's interesting. What about documentation beyond the current work? So I'm thinking about once, you know, a feature is delivered, how do people in the organization then know how this feature is supposed to work? Like moving forward as something that is customer-facing. JOËL: That can vary a lot by organization, I think because there's a couple of different aspects to this. You have maybe some internal-facing documentation; maybe some customer support people need to know about the way the interface has changed. And then you also have customer-facing documentation where maybe you want some sort of, you know, you want a blog post talking about the new feature or some kind of release notes or something like that to be shared with your customers. And compiling that might look very different than what you do for your internal service reps. STEPHANIE: Yeah, I like that. It's true that the customer documentation is really helpful. At least for, the product that I'm working on, it has very comprehensive documentation about how to use that for its customers. And that has been really helpful because, hopefully, that should be the truest [laughs] information out there. But sometimes, you know, I find myself in meetings where none of us really know what happens. For example, a question that was asked recently is our product has a free trial capability. But it was unclear what happens to all of the data that the customer is getting access to as a feature. Like, what happens to that data after the free trial ends? Like, if they then have purchased a license, do they still have access to their free trial data? If, you know, there's a lapse between then, does it just get deleted, or will it show up again? And no one really knew the answer to that. And I think that was another area that got my spidey senses tingling a little bit; I think because it reminded me of...there was a definition I read somewhere of legacy code that is basically when the person who has the most context about how a piece of code works and then they leave the company and that institutional knowledge no longer exists, like, that is legacy code. And I almost think that that also applies to product a little bit where a legacy product is something where no one quite knows what is supposed to happen, but it's still being used by users. JOËL: That's a really fun definition there. I think there's sort of two related questions that are slightly different here, which is, one, how does the code behave? So, what happens when someone's trial period expires? And it's quite possible that no one on the team knows what actually happens when that time expires. And then the second question is, what should happen when a trial expires? And it's possible, again, that the product team didn't think through any of the edge cases. They only went for the happy path. And so it's possible if that is also fully undefined and no one knows. STEPHANIE: Yeah, I like that distinction you made a lot because they definitely go hand in hand, where someone realizes that some weird edge case happened, and then suddenly, they're asking those questions. And, you know, we realized, like, oh, like, that just didn't have enough, like, intention or thought behind how it was coded. So, like, it really is; who knows, right? Just whatever seems to happen. And I think that this actually kind of reminds me of a previous episode we did about empowering other departments in the company because, ultimately, a lot of those questions about, like, how does this work? What happens? Ends up going to a developer who has to go and read the code and report back. And while, you know, we do have that power, it can also be a bit of a curse, I think. [laughs] JOËL: I think this is an area where, as developers, we're maybe particularly skilled. Because of the work that we do, our brains are kind of wired to think about all of the edge cases, and sometimes they can be really annoying. But I think there's a lot of value sometimes when maybe the product team comes to us with a maybe somewhat nebulously scoped ticket or a series of tickets for, let's say, a free trial period feature that only goes through the happy path. And then sometimes it's up to us to push back or to follow up and say, "Okay, great. We've got a bunch of tickets for a free trial period. Have you thought about what happens after a trial expires but the person hasn't converted to a paying customer?" And then, oftentimes, the answer is like, "Oh, no, we didn't think about that." And I think oftentimes, as developers, our job is to kind of, like, seek out a lot of those edge cases. And we have a lot of techniques and methodologies that we use to try to find edge cases, things like test-driven development, various modeling tools that we'll try to use to make sure that we don't just crash or do something bad in our code. But what should the actual behavior be? That's a conversation that we need to have. And hopefully, that's one that maybe the product team has already had on their own. But oftentimes, the benefit of having that cross-functional team is the ability to kind of have that back and forth and say, "Hey, what about this edge case? Have we thought about that? How do we want that to behave?" STEPHANIE: Yeah, that actually made me think about the idea of tech debt but almost at a product level, where, hey, it turns out that we have all of these things that we didn't quite think through, and it's now causing problems. But how much do we invest in revisiting it? Because, you know, maybe this feature is several years old, and it was working just okay enough for it to, you know, be valuable. But we're now discovering these things and, you know, like, do we invest in them? Or are we more focused on, you know, coming up with new things and new features for our customers? JOËL: That's a classic prioritization problem. It also kind of reminds me of the idea of an MVP. What are the actual, like, minimum set of features that you need in order to try out something or to ship something to customers? And, you know, maybe we don't need some special behavior if your trial account doesn't convert. Maybe we're okay [laughs] that you log in, and the app just crashes. Probably not, because we would probably want you to convert to a paying customer at some point. But maybe we're okay if you just get a screen that says, "You have no projects," when, in fact, you did have projects. It's just that you're no longer on the free trial. Again, for business reasons, probably we want a call to action there that says, "You have five projects. They are not available to you. Please pay to unlock your projects again." That probably converts better. But, again, now that is a business decision. And that becomes a prioritization question that the team as a whole gets to address. Sometimes it can also be some really fun prioritization things where if you're on a really tight schedule, you might ship some features live knowing that you have a time limit, but you don't have to necessarily ship other things. So let's say you've got a 30-day trial, and maybe you ship that before you've even implemented what the dashboard will look like after your free trial has expired, and that's fine because no one's going to hit that condition for 30 days. So now you've got 30 days to go out and handle that condition. And maybe that's okay because it allowed you to get to market a little bit faster, allowed you to cut scope, break those tickets, yes, and just move that much faster. But it does require discipline because now you're on the clock. You've got 30 days to fix that edge case or potentially face some unhappy customers. STEPHANIE: Yeah, I think that's quite a funny way to handle it. It's really ruthless prioritization [laughs] there. But what you said was very interesting to me because I was thinking about how there is such a focus on new feature development and that being the thing that will attract customers or generate more money. But there is something to be said about investigating some of our old features of our existing system and finding opportunities there. And oftentimes, revisiting them will reduce the amount of pain [chuckles] that, you know, developers feel having to kind of keep track or have an eye on, like, where things are airing out, but then don't have the time to really invest in making it better or making that part of the product better. JOËL: I think that's a great opportunity then to have a conversation with other parts of the team. Typically, I think you have to convert some of those into more of a business case. So the business people in the company or the product people might not care about the sort of raw metrics that you see as a developer. Oh, we got an exception with a stack trace in this part of our app. What does that even mean? But if you say, hey, people who signed up for a free trial and then didn't immediately convert within 30 days who want to come back a month later and convert are unable to do so. And we've seen that that's about 10% of the people who signed up for a free trial. Well, now that's an interesting business question. Are we losing out on potentially 10% of customer acquisition? I'll bet the sales and marketing people care a lot about that. I'll bet the business people care a lot about that. The product people probably care a lot about that. And now we can have a conversation about should we prioritize this thing? Are these metrics that we should improve? Is this a part of our code that's worth investing in? STEPHANIE: Yeah, I like that because, in some ways, asking those questions about how does it work? Like, that is really an opportunity because then you can find out, and then you can make decisions about whether it's currently providing enough value as is or if there is something hiding under there to leverage. JOËL: And I think that's one of the other places where, as developers, we provide value to clients is that we can sort of talk both languages. We can talk product language. We can talk business language. But we can also talk code. And so when we see things like that in code, sort of translate that into, like, what are the business impacts of this code change? Which then allows everyone to make the best possible decisions for the mission of the organization that you're a part of. So we've talked about a variety of sort of patterns and anti-patterns that surround working through some of this churn on a product. I'm curious, Stephanie, for you, what's maybe one concrete thing that you've done recently that you've found has really helped you navigate this and maybe help reduce some of the stress that you feel as you navigate through this? STEPHANIE: Yeah, I think, for me, one of the worst things is when that discussion is had in a meeting or a [inaudible 35:45] and then is not put anywhere. And so, one thing I've been making sure to do is either asking the person who made the request to write it down, either on the ticket or in Slack. Or I will write it down, you know, I will document the outcomes of what we talked about and putting it in a public space so that people are aware. I think that small action has been helpful because we hold so much of this in our heads. And I've been finding that it ends up being hard for people to rotate onto different projects and, you know, get onboarded and up to speed effectively because there's so much knowledge and context transfer happening. But even just putting it in a place where maybe it's not relevant to everyone, but at least they see it. And then the next time that they're asked or maybe, like, do come around to working on this, they, like, have some fragment of a memory that they saw something about this. So that has been really helpful. It actually dovetails really nicely into what we were talking about with opportunities, too, because once it's out there, like, maybe someone else will see it and have an idea about how it could be better or that change not being what they expected, and they can weigh in a little more. So that's what I'm trying to do. And I think it's also nice to see how often that happens, right? If we're constantly seeing things changing because we have a written record of it, that could be helpful in bringing up and investigating further as to, like, why is this happening? Like, why do we experience this churn? And is that something we want to address? JOËL: Yeah, because an element that we haven't talked at all about is any sort of feedback cycle or retrospective, where we can talk about these things and having that written trail and saying, "Oh, we changed this decision five times in the past week, like, really churned there." Now maybe that prioritizes it to be an important thing to talk about and to improve for the next cycle. STEPHANIE: What I feel really strongly about is when, you know, each individual on a team is feeling this pain, but it not being known that it's actually a collective issue. Because maybe these things are happening in one-on-one conversations, and we don't realize that, like, oh, maybe there is something bigger here that we could improve on. And so the more eyes on it there are, the more visible it is, I think, that the easier it is to address. JOËL: I love that, the power of writing things down. On that note, shall we wrap up? STEPHANIE: Let's wrap up. Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeee!!!!!! ANNOUNCER: This podcast is brought to you by thoughtbot, your expert strategy, design, development, and product management partner. We bring digital products from idea to success and teach you how because we care. Learn more at thoughtbot.com.

The Bike Shed
390: The Truth about Truthiness

The Bike Shed

Play Episode Listen Later Jun 27, 2023 39:58


Joël's new work project involves tricky date formats. Stephanie has been working with former Bike Shed host Steph Viccari and loved her peer review feedback. The concept of truthiness is tough to grasp sometimes, and JavaScript and Ruby differ in their implementation of truthiness. Is this a problem? Do you prefer one model over the other? What can we learn about these design decisions? How can we avoid common pitfalls? [EDI](https://www.stedi.com/blog/date-and-time-in-edi](https:/www.stedi.com/blog/date-and-time-in-edi) [Booleans don't exist in Ruby](https://thoughtbot.com/blog/what-is-a-boolean](https://thoughtbot.com/blog/what-is-a-boolean) [Rails valid? method](https://api.rubyonrails.org/classes/ActiveRecord/Validations.html#method-i-valid-3F](https://api.rubyonrails.org/classes/ActiveRecord/Validations.html#method-i-valid-3F) Parse, don't validate (https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/) Javascript falsiness rules (https://www.sitepoint.com/javascript-truthy-falsy/) Transcript: STEPHANIE: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Stephanie Minn. JOËL: And I'm Joël Quenneville. And together, we're here to share a little bit of what we've learned along the way. STEPHANIE: So, Joël, what's new in your world? JOËL: So I'm on a new project at work. And I'm doing some really interesting work where I'm connecting to a remote database third-party system directly and pulling data from that database into our system, so not via some kind of API. And one thing that's been really kind of tricky to work with are the date formats on this third-party database. STEPHANIE: Is the date being stored in an unexpected format or something like that? JOËL: Yes. So there's a few things that are weird with it. So this is a value that represents a point in time, and it's not stored as a date-time value. Instead, it's stored separately as a date column and a time column. So a little bit of weirdness there. We can work with it, except that the time column isn't actually a time value. It is an integer. STEPHANIE: Oh no. JOËL: Yeah. And if you're thinking, oh, okay, an integer, it's going to be milliseconds since midnight or something like that, which is basically how Postgres' time of day works under the hood, nope, that's not how it works. It's a positional digit thing. So, if you've got the number, you know, 1040, that means 10:40 a.m. STEPHANIE: Oh my gosh. Is this in military time or something like that, at least? JOËL: Yes, it is military time. But it does allow for all these, like, weird invalid values to creep in. Because, in theory, you should never go beyond 2359. But even within the hours that are allowed, let's say, between 1000 and 1100, so between 10:00 and 11:00 a.m., a clock only goes up to 59 minutes. But our base 10 number system goes up to 99, so it's possible to have 1099, which is just an invalid time. STEPHANIE: Right. And I imagine this isn't validated or anything like that. So it is possible to store some impossible time value in this database. JOËL: I don't know for sure if the data is validated or not, but I'm not going to trust that it is. So I have to validate it on my end. STEPHANIE: That's fair. One thing that is striking me is what time is zero? JOËL: So zero in military time or just 24-hour clocks in general is midnight. So 0000, 4 zeros, is midnight. What gets interesting, though, is that because it's an integer, if you put the number, you know, 0001 into the database, it's just going to store it as 1. So I can't even say, oh, the first two digits are the hours, and the second two digits are the minutes. And I'm actually dealing with, I think, seconds and then some fractional part of seconds afterwards. But I can't say that because the number of digits I have is going to be inconsistent. So, first, I need to zero pad. Well, I have to, like, turn it into a string, zero pad the numbers so it's eight characters long. And then, start slicing out pairs of numbers, converting them back into integers, validating them within a range of either 0 to 23 or 0 to 59, and then reconstructing a time object out of that. STEPHANIE: That sounds quite painful. JOËL: It's a journey for sure. STEPHANIE: Do you have any idea why this is the case or why it was created like this originally? JOËL: I'm not sure. I have a couple of theories. I've seen this kind of thing happen before. And I think it's a common way for developers who maybe haven't put a lot of thought into how time works to just sort of think, oh, the human representation. I need something to go in the database. On my digital clock, I have four digits, so why not put four digits in the database? Simple enough. And then don't always realize that there's all these edge cases to think about and that human representations aren't always the best way to store data. STEPHANIE: I like how you just said that that, you know, we as humans have developed systems that are not quite, you know, the same as how a computer would. But what was interesting to me...something you said earlier about time being a fixed point. And that is different from time being a value, right? And so here in this situation, it sounds like we're storing time as a value, but really, it's more of the idea of, like, a point. JOËL: Interesting. What is the difference for you between a point and a value? STEPHANIE: I suppose a value to me...And I think we talked about this a little bit on a previous episode about value objects and also how we stored numbers, like phone numbers and credit card numbers and stuff like that. But a value, like, I might want to do math on. But I don't really want to do math on time. Or, specifically, if I have this idea of a specific point in time, like, that is fixed and not something that I could mutate and expect it to be the same thing that I was trying to express the first time around. JOËL: Oh, that's interesting because I think when it comes to time and specifically points in time, I sometimes do want to do math on them. And so, specifically, I might want to say, what is the time that has elapsed between two points in time? Maybe I have a start time and an end time, and I want to say how much distance is there between the two? If you use this time system where you're storing it as an integer number where the digits have positional values, because there's all those gaps between, you know, 59 and 99 that are not valid, math breaks down. You've broken math by storing it that way. So you can't get an accurate difference by doing math on that, as opposed to if you store it as a counter, which is what databases do under the hood, but you could do manually. If you just wanted to use an integer column, then you can do math because it's just a number of seconds since the beginning of the day. And you can subtract those from each other. And now you have these number of seconds between the two of them. And if you want them in minutes or hours, you divide by six here, 3600, and you get the correct response. STEPHANIE: Yeah, that is really interesting because [chuckles] in this situation, you have the worst of both worlds, it seems like. [laughs] JOËL: The one potential benefit is, I think, it's maybe more human-readable. Although, at that point, I would say if you're not doing math on it and you want something human-readable, you probably don't want an integer. You probably want a string. And maybe you even store it as, like, ISO 8601 time string in the database, or even just hour:minute:second split by a colon or whatever it is but just as a string. Now it's human-readable. You can still sort by it if you go from largest to smallest increment in your format. You can't do math, but then you weren't doing math on it anyway. So that's probably a nice compromise solution. But, ideally, you'd use a native, you know, time of day column or a date-time or something like that. STEPHANIE: For sure. Well, it sounds like something fun to contend with. [laughs] JOËL: One thing that was brought to my attention that I'd never heard about before is that potentially a reason it's stored that way is because of an old data format called EDI—I think it's Electronic Data Interchange—that dates from ages ago, you know, the '60s or '70s, something like that. Before, we had a lot of standards for data; this is how...an emerging standard that came for moving data between systems. And it has a lot of, like, weird things with the way it's set up. But if you're dealing with any sort of older data warehouses or older business systems, they will often exchange. And sometimes, you're going to store data in something that approximates this older EDI format. And, apparently, it has some weirdness around dates where it kind of does something like this. So someone was suggesting, oh, well, if you're interacting with maybe an older, you know, a lot of, like, e-commerce platforms or banking systems, probably airline systems, the kind of things you'd expect to be written in, let's say, COBOL... STEPHANIE: [laughs] JOËL: Have a system that's kind of like this. So maybe that wouldn't be quite as surprising. STEPHANIE: Yeah, that is really interesting. It just sounds like sometimes you're limited by the technology that you're interacting with. And I guess the one plus side is that, in your system, you can make the EDI work for you, hopefully. [laughs] Whereas perhaps if you are talking to some of those older technologies that don't know how else to convert date types and things like that, like, you just kind of have to work with what's available to you. JOËL: Yeah. And that's got me realizing that a lot of these older, archaic systems are still online and very much a part of our software ecosystem and that there's a lot of value in learning some software history so that I'm able to recognize them and sort of work constructively with them when I have to interact with that kind of system. STEPHANIE: Yeah, I really like that mindset. JOËL: So, Stephanie, what's new in your world? STEPHANIE: So, last week, we talked about writing reviews for ourselves and our peers. And one thing that happened in between the last episode and this one is Steph Viccari, former co-host of this podcast, who I've been working with really closely on this project of mine; she was writing a peer review for me. And one thing that she did that I really loved was she sent me a message and asked me a few questions about the direction of the review that I was wanting and what kind of feedback would be helpful for me. And some of the things she asked were, you know, "Is there a skill that you're actively working on? Is there a skill you'd like to start working on?" And, like, what my goals are for the feedback. Like, how can she tailor this feedback to things that would help my progression and what I hope to achieve? And then my favorite question that she asked was, "What else should I know but didn't think to ask?" And I thought that was a really cool way of approaching. You know, she's coming to this, like, wanting to be helpful, but then even still, like, there are things that she knows that I am kind of the expert on in my own career progression, and I really liked that. I think I'd mentioned last week that part of the feedback you want to be giving is, you know, something that will be helpful for that person, and centering them in it, instead of you is just a really awesome way to do that. So I was very appreciative that she asked me those questions. JOËL: That's incredibly thoughtful. I really appreciate that she sent that out to you. What did you respond for the is there something else I should know but didn't know to ask? STEPHANIE: Yeah. I mentioned that more and more, I'm realizing that I am not interested in management. And so what would be really helpful for me was to ground most of the feedback in terms of my, like, technical contributions. And also, that one thing that I'm thinking about a lot is how to be an individual contributor and still have an impact on team health and culture because that is something I care about. And so I wanted to share that with her because if there are things that she can identify in those aspects, that would be really awesome for me. And that can kind of help guide her away from a path that I'm not interested in. JOËL: I think having that kind of self-awareness is really powerful for yourself. But then, when you can leverage that to get better reviews that will help you get even further down the path that you're hoping to go, and, wow, isn't that just, like, a virtuous cycle right there that's just building on itself? STEPHANIE: Yeah, for sure. I think the other thing I wanted to share about what's new in my world that has been just a real boost to my mood is how long the days are right now because it's summer in North America. And yesterday was the summer solstice, and so we had the longest day of the year. The sun didn't set until 8:30 p.m. And I just took the opportunity to be outside. I took a swim in the lake, which was my first swim of the season, which was really special. And my friend had just a nice, little, like, backyard campfire hang out. And we got to roast some marshmallows and just be outside till the sunset. And that was really nice. JOËL: When you say the lake, is that Lake Michigan? STEPHANIE: Yes, I do mean Lake Michigan. [laughs] I forget that some people just don't have a giant lake next to them [laughs] that they refer to as the lake. JOËL: It's practically an inland sea. STEPHANIE: Yes, you can't see the other side of it. So, to me, it kind of feels like an ocean. And yesterday, when I was in the water, I also was thinking that I felt like I was just in a giant bathtub. [chuckles] JOËL: So I'm in New England, and most of the bodies of water here are not called lakes. They're called ponds. STEPHANIE: Really? JOËL: No matter the size. STEPHANIE: Oh. JOËL: I guess lakes is reserved for things like what you have that are absolutely massive, and everything else is a pond. STEPHANIE: That's so funny because I think of ponds as much smaller in scale, like a quaint, little pond. But that's a really fun piece of regional vocabulary. So one interesting thing happened on my client project this week that I wanted to get your input on because I've definitely seen this problem before, and still, it continues to crop up. But I was working on a background job that we were passing a Boolean value into as one of the parameters that we would then, you know, use down the line in determining some logic. And we, you know, made this change, and then we were surprised to find out that it continued to not work the way we expected. So we got some bug reports that we weren't getting into one of the branches of the conditional based on that Boolean value that we were passing in. And we learned, after a little bit of digging, that it turns out that those values are serialized because this job is actually saved in -- JOËL: Oh no. STEPHANIE: [chuckles] Yeah. It inherits from the ActiveRecord, actually, and is saved in our database. And so, in that process, the Boolean value got serialized into a string and then did not get converted [chuckles] back into a Boolean. And so when we do that if variable check, it was always evaluating to true because strings are truthy in Ruby. JOËL: Right. The string false is still truthy. STEPHANIE: A string false is still truthy. And we ended up having to coerce it into a Boolean value to fix our little bug. But it was just one of those things that was really frustrating, you know when you feel really confident that you know what you're doing. You're just writing a conditional statement. And it turns out the language beguiled you. [laughs] JOËL: I've run into similar bugs when I'm reading from environment variables because environment variables are always strings. But it's common that you'll be setting some kind of flag. So when you're setting the environment variable, you're setting something to true or false. But then, when you're reading it, you have to explicitly check if this environment variable double equals the string true, then do the thing. Because if you just check for the value, it will never be false. STEPHANIE: Right. And I kind of hate seeing code like that. I don't know; something about it just rubs me the wrong way because it just seems so strange, I suppose. JOËL: Is it just, like, those edge cases where you specifically have to do some kind of, like, double equals check on a value that feels like it should be a Boolean? Or do you kind of feel a bit weird about the concept of truthiness in general? STEPHANIE: I think the concept of truthiness is very hard to grasp sometimes. And, you know, when you're talking about that edge case where we are setting...we're checking if the string is the string true. That means that everything else is false, right? So, in some ways, I think it's just really confusing because we've expanded the definition of what true and false mean to be anything. JOËL: That's really interesting because now you have to pick. Are you checking against the string true, or are you negatively checking against the string false? And those are not equivalent because, like you said, now you're excluding every other string. So, is the string "Hello, World" put you in the false branch or the true branch? STEPHANIE: Who's to say? [laughs] I think a similar conundrum also occurs when we use predicate matchers in our tests. I think this is a gripe that I've talked about a little bit with others when we're writing tests and especially if we're writing a predicate method, and then that's what we're testing, right? We kind of are expecting a true or false value. And when our test expects something to be truthy rather than explicitly saying that we expect the return value to be true, that is sometimes a bit confusing to me as well because someone could theoretically change this method and just have it return "Hello, World," like you said, as a string, like, anything else. And that would still pass the test. JOËL: And it might even pass your code in most places. STEPHANIE: Right. And I suppose that's okay. Is it okay? I don't know. I'm not sure where I land on this. JOËL: I used to be a kind of hardcore Boolean person. STEPHANIE: [laughs] That's a sentence no one has ever [laughs] said. JOËL: I like my explicit trues and falses. I don't like the ambiguity of saying, like, oh, if person do a thing, it's, like, oh, what is person here? Is this a nil check? Is it explicitly false? Do you just want to know that this person is non-empty? Well, what exactly are you checking? So I like the explicitness of saying, oh, if person dot present, or if person dot empty, or if person dot nil. And I think maybe spending some time in some more strongly typed languages has also kind of pushed me a little bit in that direction, where it's nice to have something that is explicitly either just true or just false. And then you completely eliminate that problem of, like, oh, but what if it's neither true nor false, then what do we do for that branch there? And the answer is your compiler will reject that program or say, "You've written a bad program." And you never reach that point where there's a bug. I've slowly been softening my stance. A fellow thoughtbot colleague has written an article why there is no such thing as a Boolean in Ruby. Everything is just shades of gray and truthiness and falsiness. But from the perspective of a program, there is no such thing as a Boolean. And that really opened my eyes to a different perspective. I don't know that I fully agree, but I'm kind of begrudgingly acknowledging that Mike makes a good point. STEPHANIE: Yes, I read the blog post that he wrote about this exact problem. And I think it's called "Booleans Don't Exist in Ruby." And I think I similarly, like, came away with, like, yeah, I think I get it if I just suspend my disbelief, you know, hard enough. [laughs] But what you were saying about, like, liking the explicitness, right? And liking the lack of ambiguity, right? Because when you start to believe that Booleans don't exist, I think that really messes with your [laughs] head a little bit. And one takeaway that I got from that blog post, kind of like we mentioned earlier, is that there is such thing as false, and then everything else is true. And I guess that's kind of how Ruby operates. JOËL: Sort of, because then you have the problem of nil, which is also falsy. STEPHANIE: That's true, but nil is nothing. [laughs] JOËL: That's one of the classic problems as well when you're trying to do a nil check, or maybe some memoization, or maybe even, say, cache this value, or store this value, or initialize this value if it's not set. And assuming that doing nil is falsy, so you'll do some kind of, like, or equals, or just some kind of expression with an or in it thinking, oh, do this extra work if it's nil because then it will trigger the branch. But that all breaks down if potential for your value to be false because false and nil get treated the same in conditional code. STEPHANIE: Right. I think this could be a whole separate conversation about nil and the idea of nothingness. But I do think that, as Ruby developers, at least in the Ruby world, based on what I've seen, is that we lean on nil in ways that we maybe shouldn't. And we end up having to be very defensive about this idea of nil being falsy. But that's because we aren't necessarily thinking as hard about our return values and what our arguments are that; it ends up causing problems in evaluating truthiness when we're having to check those objects that could be nil. JOËL: In terms of the way we communicate with the readers of our code, and, as a reader, I generally assume that a Ruby method that ends with a question mark will return a true Boolean, either true or false. Is that generally your expectation as well? STEPHANIE: I want to say yes, but I've clearly experienced enough times where that's not the case that, you know, it's like, my ideal world and then reality [laughs] and having to figure out how to hold both of those things. JOËL: It's one of those things that's mostly true. STEPHANIE: I want to believe it because predicate methods and, like, the Ruby Standard Library mostly return Boolean values, at least to my knowledge. And if we all kind of followed that [laughs] pattern, then it would be clear. But I think there's a part of me that these days mostly believes it to be true that I will be getting a Boolean value (And, wow, even as I say this, I realize how confusing [laughs] this is starting to sound.) and that until I'm not, right? Until I'm surprised at some point. JOËL: I think there's two things I expect of predicate methods in Ruby. One is that they will return, like, a hard Boolean, either true or false. The second is that they are purely query methods; they don't do side effects. Neither of those are consistent across the ecosystem. And a classic example of violating that second guideline I have in my mind is the valid question mark method from Rails. And this really surprised me the first time I tripped into this because when you call that on an object, it doesn't just tell you whether or not the object is valid. It actually mutates the underlying object by populating the error messages' hash. So if you have an invalid object and you examine its error messages' hash, it will be empty until you call the valid question mark method. So sometimes, you don't even care about the return value. You're just calling valid to mutate the object so that you can access the underlying hash, which is that's weird code when you call a predicate method but then totally ignore the output. STEPHANIE: Yeah, that is strange because I have definitely seen it where we are calling the valid method to validate, and then we end up using the error messages that are set on that object later. I think that's tough because, in some ways, you do care about whether the object is valid or not. But then also, the error messages are helpful usually and when you're trying to use that method. The point is to validate it so that you can hopefully, like, tell the user or, like, the consumer of your system, like, what's wrong in validation. But it is almost, like, two separate things. JOËL: It is. And sometimes, it's really hard to split those two apart. So I'm not throwing shade at the Rails dev team here. Some of these design decisions are legitimately difficult to make. And what's most useful for the most people the most time is often a compromise. I think you brought up the idea of separating those two things. And I think there's a general principle here called command-query separation. That's, like, the fancy way of talking about what you were saying. STEPHANIE: One thing that I was just thinking about kind of when we initially picked off this conversation was the idea of how things outside the Ruby ecosystem or the Ruby world interact with what we're returning in terms of Boolean values. And so when I mentioned the object being serialized because of, you know, our database and, like, background job system, that's an entity that's figuring out what to do with the things that we are returning from Ruby. And similarly, when you're talking about environment variables, it's like, our computer system talking to now our language and those things being a bit different. Because when we, like, suspend our disbelief about what is truthy or falsy in Ruby, at least we're doing it in, like, the world of Ruby. And as soon as we have to interact with something else, like, maybe that's when things can get a little hairy because there's different ideas about truthiness there. And so I'm kind of also thinking about what we return in APIs and maybe, like, that being an area where some explicitness is more required. JOËL: Whenever I'm consuming third-party data, I'm a big fan of having some kind of transformation or parse step. This is inspired in part by the "Parse, Don't Validate" article, which I'll link in the show notes. So, if I'm reading data from a third-party API and I want it to be a Boolean, then maybe I should do the transformation myself. So maybe I check literally, is it the string true or the string false, and anything else gets rejected? Maybe I have...and maybe I'm a little bit more permissive, where I also accept capital T or capital F, and I have, like, some rules for transforming that. But the important thing is I have an explicit conversion step and reject any bad output. And so for something like an environment variable, maybe that would look like looking for true or false and raising if anything else is there. So that we try to boot the app, and it immediately crashes because, hey, we've got some, like, undefined, like, bad configuration that we're trying to load the app with. Don't even try to keep running. Hard crash immediately. Fix it, and then come back. STEPHANIE: Yeah, I like that a lot because the way we ended up fixing this issue with the background job that I mentioned was just coercing our string value into a Ruby Boolean in the job that we were then, like, running the conditional in. But really, what we should have done is have fixed that at a higher level and where we parse and deserialize, like, the values we're getting from the job to prevent this kind of in the future because right now, someone can do this again, and that's a real bummer. JOËL: I always love those deeper conversations that happen after you've had a bug that are like, how do we prevent this from happening again? Because sometimes that's where you have the deepest learnings or the most interesting insights or, you know, ideas for Bike Shed episodes. I'm really curious to contrast JavaScript's approach to truthiness to Ruby's because even though they both use the same idea, they kind of go about it differently. STEPHANIE: Tell me more. JOËL: So, in Ruby, an empty array and an empty string are truthy. JavaScript decided that empty things are falsy. And I forget...there's a whole table that shows the things that are truthy and falsy in JavaScript. I want to say zero is falsy in JavaScript but don't quote me on that, which can also lead to some interesting edge cases you have to think about. STEPHANIE: Okay, yes. This is coming back to me now. I think depending on what, you know, ecosystem or language or world I'm in, I have to just only be able to think about what is true in this world [laughs] and then do that context switching when I am working in something else. But yeah, that is a really interesting idea. Someone decided [laughs] that this was their idea of true or false. JOËL: I'm curious if you have a preference for sort of JavaScript's approach to falsiness where a lot more types of values are falsy versus Ruby, which said pretty much only nil and false are falsy. Everything else is truthy. STEPHANIE: Hmm, that is an interesting question. JOËL: Because in Ruby then or, I guess, in Rails, we end up with the present predicate method that is specifically checking for not only nil and false but also for empty array, empty string, those kinds of things. So, if you find yourself writing a lot of present matchers in your code, you're kind of leaning on something that's closer to JavaScript's definition of falsiness than Ruby's. But maybe you're making it more explicit. STEPHANIE: Right. In JavaScript, I see a lot of double bangs in lieu of those predicate methods. But I suppose by nature of having to write those predicate methods in Ruby, we're, like, really wanting something else, I think. And maybe...I guess it is just a question of explicitness like you're saying, and which I prefer. Is it that I need to be explicit to convey the idea that I want, or is it nice that the language has just been encoded that way for me? JOËL: Or maybe when you write conditionals, if you find yourself doing a lot of presence checks, do you find that you typically are trying to branch on if not null, not false, not empty more frequently than just if not null, not false? Because that's kind of the difference between Ruby's model and JavaScript's model. STEPHANIE: Hmm, the way you posed that question is interesting because it makes me think that sometimes it's quite defensive because we have to check for all these possible return values. We are unsure of what we are getting back. And so this is kind of, like, a catch-all for things that we aren't really sure about. JOËL: Yeah, I mean, that's the fun of dynamic programming languages. You never know exactly what you're going to get as long as things respond to certain methods. You really lean into the duck typing. And I think that's Mike's argument in his article that "Booleans Don't Exist" in that as long as something is responding to methods that you care about, it doesn't matter if you're dealing with a true Boolean or some kind of other value. STEPHANIE: Right. So I suppose the ideas of truthiness then are a little bit more dependent on how people are using the language though it seems like a chicken-and-egg situation to me. [laughs] JOËL: It is really interesting to me in terms of maybe thinking about use cases in my own code if I'm having to...if I'm writing code that leans on truthiness where I can say just, you know if user. But then knowing that, oh, that doesn't account for, like, an empty value. Do I then also need to add an extra check for emptiness? And maybe if I'm in a Rails project, I would reach for that present matcher where I wouldn't have to do that in JavaScript because I can just say, if user, and that already automatically checks for presence. So I'm kind of wondering now in my mind, like, which default would fit my use cases more? Or, if I go back to an older version of myself, I will say I don't want any of these defaults. They're all too ambiguous. I'm going to put explicitly if user dot nil question mark, if that's the thing that I'm checking for, or if user dot empty question mark because I want my reader to know what condition I'm checking. STEPHANIE: Yeah, that is interesting, this idea of, like, which mode do you find yourself needing to use more and if that is accommodated for you because that's just the more common, like, use case or problem. I think that's something that I will be thinking about the next time I write a conditional [laughs] because, like I was saying earlier, I think I end up just leaning on what someone else has decided for me in terms of truthiness and not so much how I would like it to work for me. JOËL: And sometimes we don't want to fight the language too much, you know if I'm writing Elm, that everything is hard Booleans. And I know I'm never going to get a nil in a place where I'd expect true or false because the compiler would prevent that from happening. I know that I'm not going to get an empty value, potentially. There's ways you can do things with a type system where you can explicitly say no empty values are even allowed at this point. And if you do allow them, then the type system will say, "Hey, you forgot to check for the empty case. Bad program. I'm rejecting that." And then you have to write that explicit branch for, oh, if empty versus if present. So I really appreciate that style of programming. But then, when you're in a language like Ruby where you're not dealing with explicit types on purpose, how do you shift that mindset so that you don't need to know the type of the value that you're dealing with? You only want to say, hey, in this context, here's the minimal interface that I want it to conform to. And maybe it's just the truthy or falsiness interface, and everything beyond that is not relevant. STEPHANIE: I think it's kind of wild to me that this idea of a binary that theoretically seems very clear turns out is actually quite confusing, ambiguous, philosophical, even. [chuckles] JOËL: Yeah. It's definitely...you can get into some deep, philosophical questions there, language design as well. One aspect, though, that I'm really curious about your thoughts is bringing new people in who are learning a language. It's really common for people who are learning a language for the first time, learning to code for the first time to write code that you and I would immediately know, like, that's not going to work. You can't add a Boolean and a number. You're just learning to code. You've never done that before. You don't know. And then how the language reacts to that kind of thing can help guide that experience. So, do you think that truthiness maybe makes things more confusing for newcomers? Or, maybe on the other side, it helps to smooth that learning curve because you don't have to be like, oh, wait, I have a user here. I can't put that in a condition because that's not a strict true or false. I'm going to coerce it, or I've got to find a predicate method or something. You can just be like, no, put it in. The interpreter will figure it out for you. STEPHANIE: Wow. That's a great question. I'm trying to put myself in the beginner's mindset a little bit and think about what it's like to just try something and the magic of it working. Because, like you said, the interpreter does it for you, or whatever, and something happens, and you're like, wow, like, that was really cool. And I didn't have to know all of the ins and outs of the types of things I was working with. That can be really helpful in just getting them, like, started and getting them just, like, on the ground writing code. And having that feeling of satisfaction that, like, that they didn't have to, you know, have to learn all these things that can be really scary to make their program work. But I do think it also kind of bites them later once they really realize [laughs] what is going on and the minute that they get that, like, unexpected behavior, right? Like, that becomes a time when you do have to figure out what might be going on under the hood. So two sides of the same coin. JOËL: What you're saying there about, like, maybe smoothing that initial curve but then it biting them later got me thinking. You know how we have the concept of technical debt where we write code in a way that's maybe not quite as clean today so we can move faster but that then later on we have to pay it back? And I almost wonder if what we have here is almost like a pedagogical debt where it's going to cost us a month from now, but today it helps us move faster and actually kind of get that momentum going. STEPHANIE: Pedagogical debt. I like that. I think you've coined a new term. Because I really relate to that where you learn just enough to do the thing now. But, you know, it's probably not, like, the right way or, like, the most informed—I think most informed is probably how I would best describe it—way of doing it. And later, you, yeah, just have to invest a little more into it. And I think that's okay. I think sometimes I do tend to, like, beat myself up over something down the line when I have to deal with some piece of less-than-ideal code that I'd written earlier. Like, I think that, oh, I could have avoided this if only I knew. But the whole point is that I didn't know. [laughs] And, like, that's okay, like, maybe I didn't need to know at the time. JOËL: Yeah, and code that's never shipped is of zero value. So having something that you could ship is better than having something perfect that you didn't ship. STEPHANIE: On that note, shall we wrap up? JOËL: Let's wrap up. STEPHANIE: Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeee!!!!!! ANNOUNCER: This podcast is brought to you by thoughtbot, your expert strategy, design, development, and product management partner. We bring digital products from idea to success and teach you how because we care. Learn more at thoughtbot.com.

The Bike Shed
383: Code as Storytelling with Nicole Zhu

The Bike Shed

Play Episode Listen Later May 9, 2023 43:02


Engineering manager at Vox Media and author Nicole Zhu joins Stephanie on today's episode to discuss her writing practice. nicoledonut is a biweekly newsletter about the writing process and sustaining a creative life that features creative resources, occasional interviews with creative folks, short essays on writing and creativity, farm-to-table memes and TikToks, and features on what Nicole is currently writing, reading, and watching. This episode is brought to you by Airbrake (https://airbrake.io/?utm_campaign=Q3_2022%3A%20Bike%20Shed%20Podcast%20Ad&utm_source=Bike%20Shed&utm_medium=website). Visit Frictionless error monitoring and performance insight for your app stack. Kieran Culkin on learning about billionaires filming Succession (https://www.tiktok.com/@esquire/video/7215641441597410603?_r=1&_t=8bPK4Ingkf5) The Home Depot skeleton (https://twitter.com/jenni_tabler/status/1566266554240888832) Nicole Zhu's newsletter (https://nicoledonut.com/) The Making of a Manager by Julie Zhuo (https://www.juliezhuo.com/book/manager.html) Saving Time by Jenny Odell (https://www.penguinrandomhouse.com/books/672377/saving-time-by-jenny-odell/) Transcript: STEPHANIE: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Stephanie Minn. And today, I'm joined by my friend and special guest, Nicole Zhu. NICOLE: Hi, I'm so excited to be here. My name is Nicole, and I am an Engineering manager at Vox Media and a writer. STEPHANIE: Amazing, I'm so thrilled to have you here. So, Nicole, we usually kick off the show by sharing a little bit about what's new in our world. And I can take us away and let you know about my very exciting weekend activities of taking down our Halloween skeleton. And yes, I know that it's April, but I feel like I've been seeing the 12-foot Home Depot skeletons everywhere. And it's becoming a thing for people to leave up just their Halloween decorations and, just as the other holidays keep rolling on, changing it up so that their skeleton is wearing like bunny ears for Easter or a leprechaun hat for St. Patrick's Day. And we've been definitely on the weird skeleton in front of the house long past the Halloween train for a few years now. Our skeleton's name is Gary. And it's funny because he's like a science classroom skeleton, so not just plastic. He's actually quite heavy. NICOLE: He's got some meat to the bones. [laughs] STEPHANIE: Yeah, yeah, and physiologically correct. But we like to keep him out till spring because we got to put him away at some point so that people are excited again when he comes back out in October. And the kids on our block really love him. And yeah, that's what I did this weekend. [laughs] NICOLE: I love it. I would love to meet Gary one day. Sounds very exciting. [laughs] I do get why you'd want to dress up the skeleton, especially if it's 12 feet tall because it's a lot of work to put up and take down for just one month, but that's fascinating. For me, something new in my world is the return of "Succession," the TV show. STEPHANIE: Oh yes. NICOLE: I did not watch yesterday's episode, so I'm already spoiled, but that's okay. But I've been getting a lot of Succession TikToks, and I've been learning a lot about the making of the show and the lives of the uber-rich. And in this one interview with Kieran Culkin, the interviewer asked him, "What's something that you learned in shooting the show about the uber-rich about billionaires that's maybe weird or unexpected?" And Kieran Culkin says that the uber-rich don't have coats because they're just shuttled everywhere in private jets and cars. They're not running to the grocery store, taking the subway, so they don't really wear coats, which I thought was fascinating. It makes a lot of sense. And then there was this really interesting clip too that was talking about the cinematography of the show. And what is really interesting about it is that it resists the wealth porn kind of lens because it's filmed in this mockumentary style that doesn't linger or have sweeping gestures of how majestic these beautiful cities and buildings and apartments they're in. Everything just seems very matter of fact because that is just the backdrop to their lives, which I think is so interesting how, yeah, I don't know, where I was like, I didn't ever really notice it. And now I can't stop seeing it when I watch the show where it's about miserable, rich people. And so I like that the visual language of the show reflects it too. STEPHANIE: Wow, yeah, that makes a lot of sense. The coat thing really gets me because I'm just imagining if I could be perfectly climate controlled all the time. [laughs] NICOLE: Right? Oh my gosh, especially you're based in Chicago [laughs], that is when you can retire the winter coat. That is always an important phase. STEPHANIE: Yeah, seriously. I also am thinking now about just like the montages of showing a place, just movies or shows filmed in New York City or whatever, and it's such...so you know it's like the big city, right? NICOLE: Mmm-hmm, mm-hmm. STEPHANIE: And all of that setup. And it's really interesting to hear that stylistically, that is also different for a show like this where they're trying to convey a certain message. NICOLE: Yeah, yeah, definitely. STEPHANIE: So I'm really excited to have you on The Bike Shed because I have known you for a few years. And you write this really amazing newsletter called "nicoledonut" about your writing practice. And it's a newsletter that I open every other week when you send out a dispatch. And last year at RubyConf, they had a conference track called Bringing Your Backgrounds With You. And there were talks that people gave about how the hobbies that they did outside of work or an identity that they held made them a better developer, like, affected how they showed up at work in a positive way. And as someone who has always been really impressed by the thoughtfulness that you apply to your writing practice, I was really curious about how that shows up for you as an engineering manager. NICOLE: Definitely a great question. And to provide a bit of context for listeners, I feel like I have to explain the newsletter title because it's odd. But there's a writer who I really love named Jenny Zhang, and her handle across the Internet is jennybagel. And so I was like, oh, that would be so funny. I should be nicoledonut. I do love donuts. My Neopets username was donutfiend, so it was -- STEPHANIE: Hell yeah. NICOLE: But anyway, so that was kind of...I was like, I need to come up with some fun title for this newsletter, and that is what I settled on. But yes, I've written personal essays and creative nonfiction. And my primary focus more recently these past few years has been fiction. And this newsletter was really kind of born out of a desire to learn in the open, provide resources, act as kind of a journal, and just process ideas about writing and what it means to kind of sustain a creative life. So it has definitely made me more reflective and proactively, like you said, kind of think about what that means in terms of how that transfers into my day job in engineering. I recently moved into management a little over a year ago, and before that, I was a senior full-stack engineer working on a lot of our audience experiences and websites and, previously, more of our editorial tools. So I think when it comes to obviously writing code and being more of an individual contributor, I think you had previously kind of touched on what does it mean to treat code as a craft? And I do think that there are a lot of similarities between those two things because I think there's creativity in engineering, of course. You have to think about going from something abstract to something concrete. In engineering, you're given generally, or you're defining kind of requirements and features and functionality. You may be make an engineering plan or something like that, an EDD, given those constraints. And then I think writing is very similar. You outline, and then you have to actually write the thing and then revise. I do think writing is not necessarily as collaborative as coding is, perhaps, but still similar overall in terms of an author having a vision, dealing with different constraints, if that's word count, if it's form or structure, if it's point of view, things like that. And that all determines what the outcome will be. You always learn something in the execution, the idea that planning can only take you so far. And at a certain point, you gather as much background knowledge and information and talk to as many people. Depending on the kinds of writing I do, I have or haven't done as much research. But at a certain point, the research becomes procrastination, and I know I need to actually just start writing. And similarly, with engineering, I think that's the piece is that once you actually start implementation, you start to uncover roadblocks. You uncover questions or complications or things like that. And so I think that's always the exciting part is you can't really always know the road ahead of you until you start the journey. And I also think that in order to benefit from mentorship and feedback...we can talk more about this. I know that that's something that is kind of a larger topic. And then another thing I think where the two are really similar is there's this endless learning that goes with each of them. I guess that's true of, I think, most crafts. Good practitioners of the craft, I think, take on that mindset. But I do think that obviously, in engineering, you have industry changes, new technologies emerging really frequently. But I do think that good writers think about that, too, in terms of what new novels are coming out. But also, how do you build a solid foundation? And I do think it's that contrast that applies in any craft is, you know, you want to have a good solid foundation and learn the basics but then keep up to date with new things as well. So I think there was this...there's this meme I actually did include in the newsletter that was...it's the meme of these two guys looking at different windows of a bus, and one looks really sad, and one looks really happy. But the two of them have the same caption, which is there's always more to learn. And so I think that is the two sides of the coin [laughs]. I think that is relevant in engineering and writing that I've kind of brought to both of those practices is trying to be optimistic [laughs] about the idea that there's always more to learn that that's kind of the thought of it. And then certainly, when it comes to management, I do think that writing has proven really valuable in that very obvious sense of kind of practical communication where I just write a lot more. I write a lot more things that are not code, I should say, as a manager. And communication is really at the forefront of my job, and so is demonstrating curiosity and building empathy, fostering relationships with people. And I do think that particularly writing fiction you have to be curious about people I think to be a writer. And I think that is true of managers as well. So I do think that has been a really interesting way that I didn't anticipate writing showing up in my day job but has been a really helpful thing and has made my work stronger and think about the people, the process, and kind of what we do and why a little differently. STEPHANIE: Yeah, absolutely. Wow, you got into a lot of different things I'm excited to keep discussing further. But one thing that I was thinking about as you were talking was, have you heard of the adage, I guess, that code is read many more times than it's written? NICOLE: Hmm, I think I have, yeah. STEPHANIE: I was thinking about that as you were talking because, in some ways, in most ways, actually, if you ascribe to that adage, I suppose, we write code for others to read. And I think there's an aspect of code telling a story that is really interesting. I've heard a lot of people advocate for writing, thoughtbot included, writing your tests like they're telling a story. And so when a future developer is trying to understand what's going on, they can read the tests, understand the setup, read what is being tested, and then read what the expected outcome is and have a complete picture of what's going on. The same goes for commit messages. You are writing little bits of documentation for people in the future. And I've also been thinking about how legacy code is just this artifact as well of all of the changes that an organization might have gone through. And so when you see something that you see a bit of code that is really weird or gets your spidey senses tingling, it's almost like, oh, I wonder what happened here that led to this piece left behind? NICOLE: Yeah, definitely. Now that you're talking about it, I also think of pull requests as a great way to employ storytelling. I remember there definitely have been times where myself or other engineers are working on a really thorny problem, and we always joke that the PR description is longer than the change. And it's like, but you got to read the PR description in order to understand what change you're making and why. And here's the backstory, the context to kind of center people in that. As a manager, I think about storytelling a lot in terms of defining purpose and providing clarity for teams. I was reading Julie Zhuo's "The Making of a Manager," and it was a really kind of foundational text for me when I first was exploring management. And she kind of boils it down to people, purpose, and process. And so I do think the purpose part of that is really tied to clear communication. And can you tell a story of what we're doing from really high-level vision and then more tactically strategy? And then making sure that people have bought into that, they understand, can kind of repeat that without you being there to remind them necessarily. Because you really want that message to carry through in the work and that they have that understanding. Vision is something I only recently have really started to realize how difficult it is to articulate. It's like you don't really understand the purpose of vision until you maybe don't have one, or you've been kind of just trying to keep your head afloat, and you don't have a Northstar to work towards. But I do think that is what plays into motivation, and team health, and, obviously, quality of the product. So yeah, that's kind of another dimension I've been thinking of. And also our foes actually. Sorry, another one. Our foes, I think, like outages and incidents. I think that's always a fun opportunity to talk about stories. There was a period of time where every time we had an incident, you had to present that incident and a recap of it in an engineering all-hands every month. And they ended up being really fun. We turned something that is ostensibly very stressful into something that was very entertaining that people could really get on board with and would learn something from. And we had the funniest one; I think was...we called it the Thanks Obama Outage because there was an outage that was caused by a photo of Barack Obama that had been uploaded in our content management system, as required no less, that had some malformed metadata or something that just broke everything. And so, again, it was a really difficult issue [laughs] and a long outage. And that was the result that I remember that presentation being really fun. And again, kind of like mythmaking in a way where that is something that we remember. We pay attention to that part of the codebase a lot now. It's taught us a lot. So yeah, I do think storytelling isn't always necessarily the super serious thing, but it can also just be team building, and morale, and culture as well. STEPHANIE: Yeah, absolutely. I think what you said about vision really resonates with me because if you don't have the vision, then you're also not making the best decisions you can be making even something as low-level as how you write the code. Because if you don't know are we going to be changing this feature a month from now, that might dictate how you go forth with implementation as opposed to if you know that it's not in the company's vision to really be doing anything else with this particular feature. And you then might feel a little more comfortable with a more rudimentary approach, right? NICOLE: Yeah, totally. Whether or not it's, we've over-optimized or not or kind of optimized for speed. Like, it's all about trade-offs. And I do think, again, like you said, having a vision that always you can check your decision-making against and inform the path ahead I think is very, very helpful. STEPHANIE: When you write, do you also keep that in mind? Like, do you write with that North Star? And is that really important to your process? NICOLE: I think it depends. I think that writing can be a little more at a slant, I suppose, is how I think of it because I don't always...just similar to work, I don't always come in with a fully-fledged fleshed-out vision of what I want a piece to be. The most recent piece I've been working on actually I did have kind of a pretty, I think, solid foundation. I've been working on this story about loneliness. And I knew that I wanted to base the structure on the UCLA...a UCLA clinic has this questionnaire that's 20 items long that is about measuring loneliness on a scale. And so I was like, okay, I knew that I wanted to examine dimensions of loneliness, and that would be the structure. It would be 20 questions, and it would be in that format. So that gave me a lot more to start with of, you know, here's where I want the piece to go. Here's what I want it to do. And then there have definitely been other cases where it's more that the conceit seems interesting; a character comes to mind. I overhear a conversation on the subway, and I think it's funny, and that becomes the first thing that is put on the page. So I definitely have different entry points, I think, into a draft. But I will definitely say that revision is the phase where that always gets clarified. And it has to, I think, because as much as I'm sometimes just writing for vibes, it's not always like that. And I do think that the purpose of revision is to clarify your goals so you can then really look at the piece and be like, is it doing what I want it to? Where is it lacking? Where's it really strong? Where's the pacing falling flat? And things like that. So I do think that sooner or later, that clarity comes, and that vision comes into focus. But it isn't always the first thing that happens, I think, because I do think the creative process is a little bit more mysterious, shall we say, than working on an engineering team. [laughs] STEPHANIE: Yeah. Well, you started off responding to my question with it depends, which is a very engineering answer, but I suppose -- NICOLE: That is true. That is true. You got me. [laughs] STEPHANIE: It applies to both. MID-ROLL AD: Debugging errors can be a developer's worst nightmare...but it doesn't have to be. Airbrake is an award-winning error monitoring, performance, and deployment tracking tool created by developers for developers that can actually help cut your debugging time in half. So why do developers love Airbrake? It has all of the information that web developers need to monitor their application - including error management, performance insights, and deploy tracking! Airbrake's debugging tool catches all of your project errors, intelligently groups them, and points you to the issue in the code so you can quickly fix the bug before customers are impacted. In addition to stellar error monitoring, Airbrake's lightweight APM helps developers to track the performance and availability of their application through metrics like HTTP requests, response times, error occurrences, and user satisfaction. Finally, Airbrake Deploy Tracking helps developers track trends, fix bad deploys, and improve code quality. Since 2008, Airbrake has been a staple in the Ruby community and has grown to cover all major programming languages. Airbrake seamlessly integrates with your favorite apps to include modern features like single sign-on and SDK-based installation. From testing to production, Airbrake notifiers have your back. Your time is valuable, so why waste it combing through logs, waiting for user reports, or retrofitting other tools to monitor your application? You literally have nothing to lose. Head on over to airbrake.io/try/bikeshed to create your FREE developer account today! STEPHANIE: You mentioned revision. And so, I do want to talk about feedback because I think that is an important part of the revision process. And I have really loved what you've had to say about writing feedback and your experience with writing feedback, especially in writing workshops. And I have always been really curious about what we might be able to learn about receiving feedback in code review. NICOLE: When it comes to receiving feedback, I think I wrote a two-part series of my newsletter, one that was about providing feedback, one that was about receiving it. I think on the side of receiving feedback, first and foremost, I think it's important to know when you're ready to share your work and know that you can share multiple times. In writing, that can be I show a very early draft to my partner who is the person who kind of reads everything and anything at any stage. It's something less polished, and I'm really just testing ideas. But then obviously, if there's something that is more polished, that is something I would want to bring to a writing group, bring into a workshop, things like that. Similarly, as engineers, I think...thank God for GitHub drafts actually adopting literally the way in which I think of that, right? STEPHANIE: Yeah. NICOLE: You can share a branch or a GitHub PR in progress and just check the approach. I've done that so many times, and really that helped so much with my own learning and learning from mentors in my own organization was checking in early and trying to gut-check my work earlier as opposed to later. Because then you feel, I think, again, a bit more naturally receptive because you're already in that questioning phase. You're not like, oh, this is polished, and I've written all the tests, and the PR description is done. And now you want me to go back and change the whole approach from the ground up. That can feel tough. I get that. And so I think, hand in hand, what goes with that is whose feedback are you interested in? Is that a peer? Is it a mentor? I think obviously leaning on your own team, on senior engineers, I do think that is one of the primary, I think, expectations of a senior engineer is kind of multiplying the effectiveness of their peers and helping them learn and grow. So I do think that that's a really valuable skill to develop on that end, but also, again, just approaching people. And obviously, different teams have different processes for that, if it's daily stand-ups, if it's GitHub reminders, automated messages that get pulled up in your channel, things like that. But there are ways to build that into your day-to-day, which I think is really beneficial too. And then there's also the phase of priming yourself to receive the feedback. And I think there's actually a lot of emotional work that I don't think we talk about when it comes to that. Because receiving feedback can always be vulnerable, and it can bring up unexpected emotions. And I think learning how to regulate the emotional response to that is really valuable for us as people but obviously within the workplace too. So I've found it really helpful to reflect if I'm getting feedback that...well, first of all, it depends on the format. So I think some people prefer verbal feedback, some people will prefer written. I think getting it in the form of written feedback can be helpful because it provides you some distance. You don't have to respond in the moment. And so I've definitely had cases where I then kind of want to reflect on why certain suggestions might elicit certain reactions if I have a fight or flight response, if I'm feeling ashamed or frustrated, or indignant, all the range of emotions. Emotions are, to put the engineering hat on, are information. And so I think listening to that, not letting it rule you per se but letting it inform and help you figure out what is this telling me and how do I then respond, or what should I do next? Is really valuable. Because sometimes it's not, again, actually the feedback; maybe it's more about that, oh, it's a really radical idea. Maybe it's a really...it's an approach I didn't even consider, and it would take a lot of work. But again, maybe if I sit and think about it, it is the scalable approach. It's the cleaner approach, things like that. Or are they just touching on something that I maybe haven't thought as deeply about? And so I think there is that piece too. Is it the delivery? Is it something about your context or history with the person giving the feedback too? I think all of those, the relationship building, the trust on a team, all plays into feedback. And obviously, we can create better conditions for exchanging and receiving feedback. But I do think there's still that companion piece that is also just about, again, fostering team trust and culture overall because that is the thing that makes these conversations all the easier and less, I think, potentially fraught or high pressure. STEPHANIE: 100%. Listeners can't see, but I was nodding very aggressively [laughs] this entire time. NICOLE: Loved it. STEPHANIE: And I love that you bring up interpersonal relationships, team culture, and feelings. Listeners of the show will know that I love talking about feelings. But I wanted to ask you this exact question because I think code review can be so fraught. And I've seen it be a source of conflict and tension. And I personally have always wanted more tools for giving better feedback. Because when I do give feedback, it's for the person to feel supported to help push their work to be better and for us to do good work as a team. And I am really sensitive to the way that I give feedback because I know what it's like to receive feedback that doesn't land well. And when you were talking about investigating what kinds of feelings come up when you do receive a certain kind of comment on a code review or something, that was really interesting to me. Because I definitely know what it's like to have worked really, really hard on a pull request and for it to feel very precious to me and then to receive a lot of change requests or whatever. It can be really disappointing or really frustrating or whatever. And yeah, I wish that we, as an industry, could talk about this stuff more frequently. NICOLE: Yeah, for sure. And I do think that you know, I think the longer you work with someone, ideally, again, the stronger relationship you form. You find your own ways of communicating that work for you. I think actually what I've learned in management is, yes, I have a communication style, but I also am flexible with how I work with each of my reports, who, again, have very different working styles, communication styles, learning styles. I don't believe that the manager sets the standards. I think there is a balance there of meeting people where they are and giving them what they need while obviously maintaining your own values and practices. But yeah, certainly, again, I think that's why for perhaps more junior engineers, they might need more examples. They might not respond well to as terse a comment. But certainly, with engineers, senior engineers that I've worked with, when I was starting out, the more we developed a relationship, they could just get a little bit more terse. For example, they could be like, "Fix this, fix that," and I would not take it personally because we had already gone through the phase where they were providing maybe some more detailed feedback, links to other examples or gists, or things like that, and our communication styles evolved. And so I do think that's another thing to think about as well is that it doesn't have to be static. I think that's the value of a team, and having good team process, too, is ideally having arenas in which you can talk about how these kinds of things are going. Are we happy with the cadence? Are we happy with how people are treating each other and things like that? Are we getting timely feedback and things like that? That's a good opportunity for a retrospective and to talk about that in a kind of blameless context and approach that more holistically. So I do think that, yeah, feedback can be very fraught. And I think what can be difficult in the world of engineering is that it can be very easy to then just be like, well, this is just the best way for the work. And feelings are, like you said, not really kind of considered. And, again, software development and engineering is a team sport. And so I do think fostering the environment in which everyone can be doing great work is really the imperative. STEPHANIE: Yeah, I really like how you talked about the dynamic nature of relationships on a team and that the communication style can change there when you have built that trust and you understand where another person is coming from. I was also thinking about the question of whose feedback are you interested in? And I certainly can remember times where I requested a review from someone in particular because maybe they had more context about this particular thing I was working on, and I wanted to make sure that I didn't miss anything, or someone else who maybe I had something to learn from them. And that is one way of making feedback work for me and being set up to receive it well. Because as much as...like you said, it's really easy to fall back into the argument of like, oh, what's the best way for the work, or what is the cleanest code or whatever? I am still a person who wrote it. I produced a piece of work and have feelings about it. And so I have really enjoyed just learning more about how I react to feedback and trying to mitigate the stress that I feel in what is kind of inherently like a conflict-generating process. NICOLE: Yeah, yeah, definitely. Another thing that kind of popped into my head to one of the earlier questions we were talking about is in terms of similarities between writing and engineering, style and structure are both really, really important. And even though in engineering, like you said, sometimes it can be, I mean, there is a point with engineering where you're like, this line of code works, or it doesn't. There is a degree of correctness [laughs] that you do have to meet, obviously. But again, after that, it can be personal preference. It's why we have linters that have certain styles or things like that to try to eliminate some of these more divisive, shall we say, potentially discussions around, [laughs] God forbid, tabs or spaces, naming conventions, all this stuff. But certainly, yeah, when it comes to structuring code, the style, or whatever else, like you said, there's a human lens to that. And so I think making sure that we are accounting for that in the process is really important, and not just whether or not the work gets done but also how the work gets done is really important. Because it predicts what do future projects...what does future collaboration look like? And again, you're not just ever optimizing for one thing in one point of time. You're always...you're building teams. You're building products. So there's a long kind of lifecycle to think about. STEPHANIE: For sure. So after you get feedback and after you go through the revision process, I'm curious what you think about the idea of what is good enough in the context of your writing. And then also, if that has influenced when you think a feature is done or the code is as good as you want it to be. NICOLE: Yeah, definitely. I think when it comes to my writing, how I think about what is good enough I think there is the kind of sentiment common in the writer community that you can edit yourself to death. You can revise forever if you wanted to. It's also kind of why I don't like to go back and read things I've already published because I'm always going to find something, you know, an errant comma or like, oh, man, I wish I had rephrased this here. But I do think that, for me, I think about a couple of questions that help me get a sense of is this in a good place to, you know, for me generally, it's just to start submitting to places for publication. So one of those is, has someone else read it? That is always a really big question, whether it's a trusted reader, if I brought it to a workshop, or just my writing group, making sure I have a set of outside eyes, fresh eyes on the piece to give their reaction. And again, truly as a reader, sometimes just as a reader, not even as a fellow writer, because I do think different audiences will take different things and provide different types of feedback. Another one is what kinds of changes am I making at this point in time? Am I still making really big structural edits? Or am I just kind of pushing words and commas around, and it feels like rearranging deck chairs on the Titanic? They're not massive changes to the piece. And then the final question is always, if this were published in its current state right now, would I be happy with it? Would I be proud of it? And that's a very gut feeling that I think only an individual can kind of feel for themselves. And sometimes it's like, no, I don't like the way, like, I know it's 95% there, but I don't like the way this ends or something else. Again, those are all useful signals for me about whether a piece is complete or ready for submission or anything like that. I think when it comes to engineering, I think there's a little bit less of the gut feeling, to be honest, because we have standards. We have processes in place generally on teams where it's like, is the feature working? Have you written tests? Have you written a QA plan if it needs one? If it's something that needs more extensive documentation or code comments or something like that, is that something you've done? Has a bit more of a clear runway for me in terms of figuring out when something is ready to be shown to others. But certainly, as a manager, I've written a lot more types of documents I suppose, or types of communication where it's like organizational changes. I've written team announcements. I've written celebration posts. I've had to deliver bad news. Like, those are all things that you don't think about necessarily. But I've definitely had literally, you know, I have Google Docs of drafts of like, I need to draft the Slack message. And even though it's just a Slack message, I will spend time trying to make sure I've credited all the right people, or provided all the context, got all the right answers. I run it by my director, my peers, and things like that if it's relevant. And again, I think there is still that piece that comes in of drafting, getting feedback, revising, and then feeling like, okay, have I done my due diligence here, and is it ready? That cycle is applicable in many, many situations. But yeah, I certainly think for direct IC work, it's probably a little bit more well-defined than some of the other processes. STEPHANIE: Yeah, that makes sense. I really liked what you said about noticing the difference between making big structural changes and little word adjustments. I think you called it pushing commas around or something like that. NICOLE: [laughs] Yeah. STEPHANIE: I love that. Because I do think that with programming, there is definitely a big part of it that's just going on the journey and exploring different avenues. And so if you do suddenly think of, oh, I just thought of a completely different way to write this code, that is worth exploring even if you just end up going back to the original implementation. But at least you saw that thought through, and you're like, okay, this doesn't work because of X, Y, and Z, and I'm choosing to go this other route instead. And I think that, yeah, that is just a good practice to explore. NICOLE: Another example of storytelling, too, where it's like, you can tell the story in the PR description or whatever, in stand-up, to be like, I also did go down this path, XYZ reason. Here's why it didn't work out, and here's what we're optimizing for. And there you go. So I do think we talk...I guess product managers think more about buy-in, but I think that's true of engineers too. It's like, how do you build consensus and provide context? And so yeah, I think what you were saying, too, even if the path is circuitous or you're exploring other avenues, talking to other people, and just exploring what's out there, it all adds up to kind of the final decision and might provide, again, some useful information for other people to understand how you arrived there and get on board with it. STEPHANIE: 100%. I remember when I worked with someone who we were writing a PR description together because we had paired on some code. And we had tried three different things. And he wrote paragraphs for each thing that we tried. And I was like, wow, I don't know if I would have done that on my own. But I just learned the value of doing that to, like you said, prime yourself for feedback as well, being like, I did try this, and this is what I thought. And other people can disagree with you, but then at least they have the information, right? NICOLE: Definitely. STEPHANIE: So before we wrap up, the last thing that I wanted to talk about, because I think it's super cool, is just how you have a totally separate hobby and skill and practice that you invest time and energy into that's not programming. And it's so refreshing for me to see you do that because I think, obviously, there's this false idea that programmers just code all the time in their free time, in their spare time, whatever. And I'm really curious about how writing fits into your life as something separate from your day job. NICOLE: Yes, I've been thinking about this a ton. I think a lot of people, the last couple of years has forced a really big reckoning about work and life and how much we're giving to work, the boundaries that can be blurred, how capitalism butts its head into hobbies, and how we monetize them, or everything is a side hustle. And, oh, you should have a page running...oh, you should charge for a newsletter. And I think there's obviously the side of we should value our labor, but also, I don't want everything in my life to be labor. [laughs] So I do think that is interesting. Writing to me, I actually do not see it as a hobby. I see it as another career of mine. I feel like I have two careers, but I have one job, [laughs] if that makes sense. I certainly have hobbies. But for me, what distinguishes that from my writing is that with hobbies, there's no expectation that you want to get better. You approach it with just...it's just pure enjoyment. And certainly, writing has part of that for me, but I have aspirations to publish. I love it when my work can reach readers and things like that. But I do think that regardless having other interests, like you said, outside engineering, outside technology, it's a great break. And I do think also in technology, in particular, I notice...I think we're getting away from it, but certainly, there's an expectation, like you said, that you will have side projects that you code in your free time, that you're on Hacker News. I think there is a little bit of that vibe in the tech industry that I don't see in other industries. You don't expect a teacher to want to teach in their free time, [laughs] you know what I mean? But we have almost that kind of implicit expectation of engineers to always be staying up to date on those things. I think with writing and engineering; the two complement each other in some interesting ways. And they make me appreciate things about the other craft or practice that I may not previously have. And I think that with engineering, it is a team effort. It's really collaborative, and I really love working in that space. But on the flip side, too, with writing, I do love, you know, there's the ego part of it. You don't have individual authorship over code necessarily unless it's git blame level. But there's a reason why it's called git blame, [laughter] even the word is like git blame. I've literally had cases where I'm like, oh, this thing is broken. Who wrote this? And then I was like, oh, surprise, it was you six years ago. But I do think with writing; it's an opportunity for me to really just explore and ask questions, and things don't have to be solved. It can just be play. And it is a place where I feel like everything that I accomplish is...obviously, I have people in my life who really support me, but it is a much more individual activity. So it is kind of the right-left brain piece. But I've been reading this book called "Saving Time." It is what my microphone is currently propped on. But it's by Jenny Odell, who wrote: "How to Do Nothing." It's breaking my brain in a really, really, really good way. It talks a lot about the origin of productivity, how we think about time, and how it is so tied to colonialism, and racism, and capitalism, and neoliberalism, all these things. I think it has been really interesting. And so thinking about boundaries between work and writing has been really, really helpful because I really love my job; I'm not only my job. And so I think having that clarity and then being like, well, what does that mean in terms of how I divide my time, how I set examples for others at work in terms of taking time off or leaving the office on time? And trying to make sure that I have a good emotional headspace so that I can transition to writing after work; all those things. I think it is really interesting. And that also, ultimately, it's we're not just our productivity either. And I think writing can be very, again, inherently kind of unproductive. People joke that cleaning is writing, doing the dishes is writing, taking a walk is writing, showering is writing, but it is true. I think that the art doesn't talk about efficiency. You can't, I think, make art always more efficient in the same way you can do with engineering. We don't have those same kinds of conversations. And I really like having that kind of distinction. Not that I don't like problem-solving with constraints and trade-offs and things like that, but I also really like that meandering quality of art and writing. So yeah, I've been thinking a lot more about collective time management, I guess, and what that means in terms of work, writing, and then yeah, hobbies and personal life. There are never enough hours in the day. But as this book is teaching me, again, maybe it's more about paradigm shifting and also collective policies we can be putting in place to help make that feeling go away. STEPHANIE: For sure. Thank you for that distinction between hobby and career. I really liked that because it's a very generative mindset. It's like a both...and... rather than an either...or... And yeah, I completely agree with you wanting to make your life expansive, like, have all of the things. I'm also a big fan of Jenny Odell. I plugged "How to Do Nothing" on another episode. I am excited to read her second book as well. NICOLE: I think you'll like it a lot. It's really excellent. She does such interesting things talking about ecology and geology and geographic time skills, which is really interesting that I don't know; it's nice to be reminded that we are small. [laughter] It's a book that kind of reminds you of your mortality in a good way, if that makes sense. But much like Gary on your porch reminds you of mortality too [laughs] and that you have to put Gary away for a little bit so that his time can come in October. [laughs] STEPHANIE: Exactly, exactly. Cool. On that note, let's wrap up. Thank you so much for being on the show, Nicole. NICOLE: Thank you so much for having me. This was a blast. STEPHANIE: Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeee!!!!!!!! ANNOUNCER: This podcast is brought to you by thoughtbot, your expert strategy, design, development, and product management partner. We bring digital products from idea to success and teach you how because we care. Learn more at thoughtbot.com.

Law Firm Marketing Catalyst
Episode 114: Forget Your Website Homepage—Google's Search Results Page Is the New Face of Your Brand with Stephanie Manor Chew, Head of the Elite Sales Team at Digital Law Marketing

Law Firm Marketing Catalyst

Play Episode Listen Later Apr 24, 2023 36:12


What you'll learn in this episode: Why Google's search results page is more important than your website homepage Why the most successful law firms are involved in their marketing, even when they hire an outside agency How a firm's intake process can make or break their SEO efforts Why content marketing today is about quality, not quantity Why consistent Google reviews are the key to ranking higher About Stephanie Chew: Stephanie Manor Chew is award-winning law firm analyst andDirector of Sales and Head of the Elite Sales Team at Digital Law Marketing. For the last 16 years, she has been helping clients build credibility and increase their visibility online through the full lifecycle of digital initiatives. From custom search engine marketing and social media positioning, to targeted content and online reputation management, she makes sure that DLM clients get what they need, when they need it. Additional Resources: Digital Law Marketing Website  Stephanie's LinkedIn Digital Law Marketing Facebook Transcript: Gone are the days when you could simply outsource everything to an SEO agency and expect results. To rank on Google today, law firms must take an active role in overseeing and executing their marketing plan. Stephanie Chew, Director of Sales at Digital Law Marketing, finds that the company's most successful clients collaborate with them to achieve the best possible outcome. She joined the Law Firm Marketing Catalyst Podcast to talk about why content is no longer king; why a firm's intake process is the most important part of lead generation; and how consistent Google reviews can boost your SEO efforts. Read the episode transcript here. Sharon:          Welcome to the Law Firm Marketing Catalyst Podcast. Today, my guest is Stephanie Chew. She is the Director of Sales at Digital Law Marketing, and she's speaking to us from Annapolis, Maryland. The company is headquartered in Nashville but is basically a virtual firm and works all over the country. Digital Law Marketing encompasses a wide range of digital aspects today, and no law firm can live without them. From SEO to PPC to social media, a law firm can make a case for each of them, especially when they work together. Today, Stephanie is going to educate us on what's new in digital law marketing, where we should start and what we can't live without. Stephanie, welcome to the program.   Stephanie:    Thank you so much for having me. I'm happy to be here.   Sharon:          Stephanie, tell us your background. How did you end up doing this? You didn't tell your mother this is what you wanted to do where you were little, I don't think.   Stephanie:    It's funny; I always wanted to be in advertising in some respects. I was just telling my daughter this the other night when we were watching the Super Bowl. Watching the Super Bowl with my father, I was always so fascinated by the ads, and I always knew I wanted to do something around advertising and marketing. After college, I started with Trader Publishing Company, which is now Dominion Enterprises. It has changed hands a couple of times, but it's basically selling advertising space to car dealers. Then it turned into apartment communities, like for-rent magazines, things of that nature, and then that led me over to the SEO world, the website world. Then I started working with law firms in 2009, and I've been here ever since.   Sharon:          That's a long time with law firms. I can relate. I wonder what would have happened if I had been in advertising when SEO started. I'm involved in SEO, but I thought advertising was my dream job and quickly found it wasn't. What would you say that lawyers have to do differently in digital marketing?   Stephanie:    They have to be a part of the partnership. In the first part of my career, we would come in and help firms and companies by putting ads in newspapers or books, and the firm or the business really didn't have to do much. Now the most successful firms out there are involved with their marketing, maybe not as much as we are, but they're a pretty big part of it. More than they ever have been. For instance, getting reviews is incredibly important now, so the firm has to work to get reviews. We can make a firm tell Google how amazing the firm is. We can create an amazing website with wonderful content, great SEO strategy, but if the firm isn't getting reviews, they're not going to get business. Now, more so than it's ever been, the firm has to be behind the digital focus and be a part of what their partners are doing to help them become successful online.   Sharon:          That's interesting, because when I read a review, the first thing I look at is, “Is this a legitimate review or is something the company wrote?” I hadn't thought about how involved lawyers have to be, how involved everybody has to be. It's not just something done in the back room.   Stephanie:    Right. The firms that are the most successful online, the lawyers are actually asking for those reviews directly themselves. We've seen firms where they've hired people to get reviews for them. They're never as successful as the actual attorney asking for that review themselves. So, asking for those reviews is one thing we always push our firms to do because, like you said, you look at those reviews to see if they're real or not. Most people look first at the newest reviews, the most recent review that was posted, and then they look at the lowest review. Those are the two categories that people care the most about. So, it's important for the firm to be involved just as much as the marketing company to make sure your reputation is good too.   Sharon:          Do you explain that from the very beginning, that they have to be involved?   Stephanie:    Yes, and we will only work with firms that will be involved. We're very lucky that we're exclusive, so we only work with one firm per practice area per geographic location. If a firm isn't a partner with us, there's only so much we can do for them. But having that partnership, we are the best in what do. We like working with the best firms. It creates the best partnership for everybody's success. But yes, it's very important that they're also a part of their own success up front.   Sharon:          When you say success, is that lead generation? Is it just what they're doing?   Stephanie:    Yes, lead generation. Our goal is to help firms become visible online organically. Our main focus is search engine optimization, which is organic placement on search engines. We do paid ads, and we're very good at doing paid ads as well, but it's that organic placement that you get the most return from. The more rankings these firms have on the search engines, the more phone calls they're going to get and then hopefully the more cases they get. It really does work that way. We can track a ranking on the search engines, and then we track their phone and work with them to hear how many cases they're getting, and it really does work in that direction.   Sharon:          Social media and the paid stuff aside, do you encourage lawyers to write articles? Does this help?   Stephanie:    With our clients, we handle all of the writing because there are couple of different ways you have to write. Number one, you have to write to make sure you're the voice of the firm and it makes sense. You're writing about cases you're looking to get, but you also have to make sure you're writing so the search engines can recognize you. For instance, a very popular search phrase right now is “near me,” like “car accident attorney near me,” “car accident lawyer near me,” “dentist near me,” “best optometrist near me.” It's making sure you get those “near me” keywords in your content, making sure your content includes questions and answers, because a lot of people are asking questions of the search engines.   We do have firms that like to write themselves. Attorneys are wonderful writers, but if they're not writing so the search engines can recognize what they're saying, it's not going to help them become more visible when it comes to these search phrases. It's a balance. We do all the writing for our clients with their approval, but if somebody does want to write here and there, we encourage that. We would just help with massaging the SEO and the content.   Sharon:          Would you massage the SEO or the stuff that makes them go higher in the rankings? If they have a website already, would you say, “It's wonderful, but we can go in and do some things”? What do you do?   Stephanie:    99% of the time, we rebuild and redesign and develop the website first. The reason we do that is because a lot of how your website is built is how you're going to perform on the search engines. For instance, if you have a very slow website, Google does not like that. Your site speed is a factor if you're going to rank or not. So, we like to go in and clean up the website so we have a good product to work with to then help with SEO. From there, we write content, build out the content, create site maps, really get to know the firm, their voice, and figure out the types of cases they're looking for. Then we write content around that to help them rank on the search engines.   Sharon:          Are you called in when they say, “We're about to embark on a rebuild of our website”? It seems to me they already have one when they call you in.   Stephanie:    Sometimes that happens, where we start working with a firm and they just rebuilt their website, and we have to give them the bad news of “I'm really sorry, but this website isn't going to perform.” We wouldn't take on that client because we want to set up the proper expectations of success for our clients. If you have a marketing company tell you, “Oh no, that's O.K. Your website's slow, but we could still work with it,” that would be a red flag because it won't work as well as it could if you redid the site. It happens sometimes.   Sharon:          Going back to the “near me,” I don't even enter that, but that comes up as a choice to click on.   Stephanie:    Yeah, that's usually right.   Sharon:          That's interesting. What do you mean by content writing? Is that what you mean when you're making sure the content—   Stephanie:    When it comes to content, you have the content pages on the website. Some of the most popular content pages on a law firm's website would be their practice area pages. You might have a page on wrongful death. You might have a page on car accidents. You might have a page on personal injury. Then each one of those pages includes content. The type of content on that page could be question and answer, could be including those words “near me.”   Google pulls from that content to determine how you're going to rank based on the way the person is searching. You'll see a lot of times where Google does an instant answer. If they're asking a question, “what is the statute of limitations in the state of California for a wrongful death case,” a law firm's content page could answer that question, so they'll bring it up as the first result.   There's also blogging. You want to make sure you're blogging on a regular basis. In the past, it was as much content as you could put on there. The phrase “content is king” is gone. That used to be the way we spoke when you would push content, push content, push content. Now, it's more about the quality of content versus the quantity of content. It's making sure it's good content that's enriched with the types of cases you're looking for, and written well so the search engines recognize you as an expert on that topic with experience and expertise in the discussion. Google will see that and help you rank better based on the content and what you're saying.   Sharon:          Is that per lawyer? Let's say on the home page of the website you have banners or badges that say, “We're the best.” Or is it in the bio?   Stephanie:    It would be in a practice area page. When somebody does a search for a car accident lawyer, let's say, Google wants to provide them with the most specific information they're looking for. So, they'll more likely pull up a car accident page from your website and show that over your home page. Your home page should be a summary of everything you do, and then the content pages are more specific on each practice area. When somebody does find you, they're going to find that practice page usually over your home page, but all of your content should include things that are easily identifiable for Google.   Sharon:          I always laugh when I see a bio that says they specialize in 20 different things, because how many can you specialize in? What would you do? Would you put everything the firm does? What would you do in order to come up?   Stephanie:    With a bio, you really want to focus on that attorney and what they've done and that's it. When it comes to the actual practice area pages, that's where you would focus on that practice area. Then maybe you could put in a little sentence or two about which attorney does that, if that makes sense. There are ways of doing it. It's not necessarily a right answer or a wrong answer. It depends on the firm, the market, the practice area. But there are ways you can incorporate that being specific to the attorney and what their expertise is versus what the whole firm does on the bio page, if that makes sense.   Sharon:          It does make sense. Should you put successes like, “We won a case that was really hard to win for $10,000 and John Smith did it”?   Stephanie:    Oh yeah, verdicts and settlements pages and verdicts and settlements in general are some of the most visited areas on the websites. People want to see numbers. There are some markets where they might not be allowed to put verdict and settlement numbers on their website, or the firm doesn't feel like it's appropriate to do that. But by the way, law firms that put their numbers on their websites get more attraction than the ones that don't.   Sharon:          The big question is do people choose a personal injury firm because they like the lawyer? It's a nice, touchy-feely firm versus one that's won all of these big numbers but they might not like as much. How do you choose? What's more important?   Stephanie:    That's a good question. Again, it comes back to the person choosing and what's important to them on why they're choosing, but if you don't have the big numbers, you definitely want to talk about what you've done. A lot of people want to feel that they can relate to that attorney. I always say talk as much as you can about things you've done to help other people. If I had a case that was specific and I read that that attorney has helped other people with the same thing I have, I'm more likely to work with them regardless of what the numbers are because I feel like they could help me. If you don't have those big numbers, you want to discuss what you've done because people will be able to relate to that.   We're also big believers in putting personal information into those bios. Talk about your hobbies, talk about your children, because people relate to things. There are so many situations where I've heard that this attorney got a case because somebody saw they had the same hobby, they went rafting or whatever it was, and their son had passed away, or that they were calling him because he had the same alma mater. Obviously that is a big one people gravitate toward. Outside of politics—I would stay away from writing anything related to politics—the more information you can humanize yourself with, it's going to help people connect with you better and they'll end up hiring you.   Sharon:          That's interesting. I've heard that both ways. I tend to relate to people, so I would like to know more about them. That's interesting that you should put it in your bio. Are you usually called in the beginning or are they already underway? Why are you called in? Tell us about your business. That's several questions, sorry.   Stephanie:    That's O.K. Usually we're called in when a firm is looking to take their law firm to that next step and they're looking for more cases. They're not showing up online. They're not getting phone calls. They're not getting cases online. A lot of times, we're called in to firms that have worked with referrals for pretty much their whole law career. They're always getting referrals, and they're tired of paying those referral fees to other attorneys. They'd like to generate cases themselves from the internet. Then we would be brought in to help them analyze what's going on in their market and what their current web presence is. Then we can put together a plan to get them to where they need to be to generate more calls that generate the cases they're looking for. It's usually somebody that wants to make more money off the internet in some way, like they're tired of paying referral fees and/or they're looking for more visibility and better-quality cases. We hear that a lot; that we help firms create better-quality cases over anything else.   Sharon:          Better quality meaning larger cases, bigger numbers?   Stephanie:    It could be anything. It could be that it's a firm that did a bunch of slip and fall cases and now they're getting bigger and better quality personal injury cases. It's medical malpractice firms that used to get a lot of junk calls and now they're getting quality calls, things like that. We're really good at SEO, and we're really good at creating more rankings for somebody organically. Usually when somebody finds a firm organically, they tend to be better qualified, quality leads.   Sharon:          Do you keep your eye on the changes in the Google algorithm?   Stephanie:    Yeah, we have a SEO specialist that works with digital marketing. We're all senior level, too. I always like to mention that because our SEO specialists are also very recognized in their SEO space. We have one Google Product Expert that works for us. She's one of 50 in the world. She's outstanding. We also have a Google Local Search expert who's been nationally recognized. They're the ones that keep up with the trends and how things are changing, and then we push that down to all of our firms. We're constantly moving in different directions with content and with SEO strategies based on the changes in the Google algorithm and changes in how we as human beings search. It is ever-changing. If you looked back 10 years ago from today, it's totally different to what we're doing. Even a year ago, it's a different strategy than what we were doing.   Sharon:          That sort of leads me to the next question. When I search, you have to skip like 10 sponsored ads. Is it possible to be high organically?   Stephanie:    Absolutely. It's interesting because Google has put a lot of emphasis on their paid ads. They have a newer ad called the Local Services Ad. It's been around for two years now, but those are the ones where there are pictures at the top of the page. They're considered Google screened, but they're driven by reviews and making sure that somebody answers the phone and other things in your budget. But the biggest driver of those is how frequently you're getting reviews, which is interesting that Google is doing that. So, there are different types of advertising they're doing, and they're pulling in an organic element with those reviews. Below that you have your pay-per-click, which is the paid advertising for Google Ad Words, and then you have your local. But yes, local SEO is still the sweet spot of getting calls. The firms we see, the majority of the calls come in through that local SEO space.   Sharon:          When you say you only take one practice area and one geographic area, do you have a map divided up? What do you call a geographic area?   Stephanie:    It depends on the marketplace, but a lot of it has to do with where the office is located. For instance, we have a state where the firm has 10 office locations throughout the state. Well, they're the only personal injury firm in that state because they have so many offices, so we're not going to work with anybody else. It comes down to who their competitors are. Our whole thing is we're not going to work with your competition. If it's too close for comfort, we go to our clients first and have them tell us if it's O.K. if we work with them, yes or no based on the competition, and we will or we won't. We do not cross that line at all. We are 100% exclusive, and that's why. We only have a handful of clients per state because it's all we want. We don't want to be the biggest SEO company out there. We want to be the best, and we feel that we are.   Sharon:          What do you do if you're in a room of lawyers, whether it's partners or not, and they say, “Reviews aren't a problem. Sally in marketing handles the reviews”? What do you do then?   Stephanie:    It depends. Maybe Sally in marketing really does do a great job and she is getting multiple reviews a week. That would be awesome. We wouldn't have a problem with that at all. But if Sally in marketing hasn't gotten a review for six months, we can see that. We can say, “Oh, that's great, but the best thing for firms is to get consistent reviews on a regular basis. Two to three reviews a week would be ideal.” We can show that they're responding to them, that they're engaging with that list, and we really push that.   We've had situations where we have gotten firms top ranked—I keep trying to say first page, but there are no pages anymore when it comes to Google. It's about rank. You can't even scroll. So, we could get somebody at the top of the rank of the search engine, but if their reviews aren't good, nobody's going to call them. We've done our job, but nobody's going to call you if your reviews aren't good. It's a two-way street. We coach our firms. We encourage them. We do a lot with intake. We can audit phone calls and help them figure out how people are handling their calls. It's a lot of coaching and encouraging and trying to do our best to get them to do their part, too.   Sharon:          I think you just preempted my next question. You can have wonderful numbers, but if they fill out the intake form and nobody sees it—   Stephanie:    Yeah, if they're not answering the phone. We see this a lot. We'll do audits with some of the most successful firms in lots of different situations. I'll never forget there was a catastrophic injury/medical malpractice firm, and a lady called very upset saying that her daughter was just diagnosed with cerebral palsy, and the woman's like, “I don't know if we do that. Hold on. Let me check. Yeah, we do that.” Now the confidence is shot. There's no way. These are not the people to hire.   Intake is such a big part of these firms. It's probably the most important part that our lawyers aren't paying attention to right now. Not all our firms, but in our industry in general. We're doing a lot with our clients to help them with that, but in our industry as a whole, I feel like intake is probably the area that can be improved the most.   Sharon:          People don't talk about that enough, I think. They talk about how much money everybody is spending on SEO and organic, but not about when the calls come in, where they were sent or what happens. Stephanie:    It's really a salesperson on that line if you think about it. As you said, firms are spending thousands and thousands, tens of thousands of dollars a month in marketing, but who's answering that phone? All your dollars are going out the window when you don't have the right person. They usually want to cut costs on those types of positions, when really it should be handled as a sales organization. Some of the more sophisticated PI firms, those large firms that are coming into different markets, are handling those as sales calls. It's changing. I've seen firms do a great job, but I do think that's one of the first things that is overlooked. Hopefully it's coming to light now. More firms are starting to do better at it, but you've got to take care of all the parts.   Sharon:          There are a lot of parts. I was laughing when you said content is king because that's what people used to say. There was a time, a long time ago, when you could tell somebody, “Just write a lot about what you do and you'll be O.K.,” but that's long gone.   Stephanie:    Yeah, it's gone now.   Sharon:          Would you say that a website is the hub of everything a person is doing when they're doing paid ads and SEO?   Stephanie:    I probably would have used to say that, but what I would say now is if you do a search for the firm's name on Google, that is the new homepage. Whatever you see that comes up there is what I would be more concerned about than even the homepage of your website. The reason I say that is because if you do a search—let's say you're a car accident lawyer and somebody finds you by doing a search for car accident lawyers. They are going to see your presence on Google pop up first. Sometimes they'll go directly to your website; sometimes they'll look at your reviews before even looking at your website; sometimes they'll look at where you are before doing that. There's a lot of information they can find out before even getting to your website.   If somebody does a Google search of your firm name, on the right-hand side of that search is usually where you'll see the Google information and Google reviews, but on the left-hand side is all those other directories out there, which could have bad reviews. That shows up before somebody even gets to your homepage. It used to be that your website is the hub of everything. It's still incredibly important, and maybe it still is the hub, but when it comes to your reputation, you really need to see what Google has on your firm. What is your brand telling people before they even get to your website? What are all these directories saying? What are all these reviews saying about you?   Sharon:          What are you seeing with all the sponsored ads? I just happened to look at your website, and there are about five sponsored ads before you even get to yours. What do you do? Is that part of it?   Stephanie:    If you were to google Digital Law Marketing, there are other law marketing companies that will bid on our name to show up ahead of us. That happens. Or somebody could be bidding on digital marketing or terms like that, but people can see that they're sponsored or paid ads. You can see that right there. Most people, if they're looking for the real website, will pass those and go directly to the organic.   Now, some people search differently. Some people would click on the first one they see, but users are becoming a lot more sophisticated than they ever have been, so they understand what an ad is. Sometimes ads are the best result. Google has also done a good job with the ad program so that sometimes the best information you're finding is in the ads. It depends, but it's hard to get away from those ads. One thing you could do as a business is bid on your name. For instance, we bid on Digital Law Marketing, so we're one of the first that pops up when somebody does type in our name. But you do want to make sure you're aware of what is on the internet about your brand.   Sharon:          It seems like the world has changed so much as a marketing person who's interested in everything you're talking about. For the firm to be at the top and on social media and everywhere, you need a bunch of experts. They need their own team. You can't be an expert in everything or just a lawyer who's interested in marketing.   Stephanie:    You're absolutely right. We touch on social media, but there's so much more you could be doing with social media. There are so many different avenues and elements of everything. You could have, like you said, a whole team. You hire a company like ours to manage the website, the SEO, the paid ads. Then you have somebody that does social media video, optimization and things of that nature. Then you get somebody that just does PR. PR companies and SEO companies work really well together because it creates good results when they do. There are so many different things. It's not just hiring one person and they can do everything.   Sharon:          But the marketing person or the lawyer who's interested should also be auditing calls or at least know what's happening.   Stephanie:    Yeah, and there are so many different tools now. We use something called dynamic call tracking where you can record every call. We're constantly spot checking and listening to our clients' calls to make sure the leads are being handled properly once we bring them to the law firm. If they don't, they're not going to see the success of their marketing dollars.   Sharon:          Have you ever had to make changes because of the dynamic call tracking?   Stephanie:    Yeah, we've had to. We've actually had to not renew agreements with clients. In almost 10 years with Digital Law Marketing, we've only lost a handful of clients, and two of those we actually let go ourselves. The reason we let them go is because they weren't helping themselves and they weren't helping to be a partner. At the end of the day, nobody would be successful. Lots of times we have these hard conversations with firms and say, “O.K., this what we found out. We did an audit and 40% of the calls aren't being answered.” The firms are very receptive to it, and they make changes quickly. That's why they hire us, because they know we'll help them with making those decisions. We've had lots of hard conversations with firms, but if firms aren't willing to help themselves, it's hard for us to help them.   Sharon:          I presume you've been in the position where you've come in to replace another SEO firm.   Stephanie:    Oh, yeah.   Sharon:          How long should a law firm wait to see results?   Stephanie:    Good question. We ask all of our clients at Digital Law Marketing to give us one year of SEO. After that, it's month to month. We don't renew clients because if you don't want to be with us after a year, then we're probably not the right fit. But we don't lose clients because we can show you within a year what we've been able to do for you. If it's not us, then try somebody else. I would definitely give it a year.   Just yesterday, I had a call from somebody who was frustrated because their marketing company had been working for three months and the results weren't showing up. I'm like, “You really need to give them longer than three months. Give them a good year. I'm not going to say you're going to be at the height of your performance in a year, not at all, but you will see progression.” We tell people all the time, “We'll be able to show you in the first 90 to 120 days how you're ranking better, how you're getting more phone calls.” We continually show that progression because it takes years to get really good visibility on search engines. You're telling Google who you are over a long, consecutive period of time of building your brand, but you will see progression quickly. You're just not going to see ultimate results for some time.   Sharon:          You must have lot of people say, “A whole year? You want me to wait a whole year before I start to evaluate?”   Stephanie:    People have figured it out now. It used to be more of a challenge five years ago, but people have figured it out. SEO takes a while. With paid ads you can see a return a little quicker, but it's still not as quick as it used to be. With paid advertising, we tell everybody to give it at least three to four months. There are so many people that are doing paid advertising, so it takes a little longer. It used to be that you were able to see results in a day, but it's different the way things are working now. It just takes time, but if you're consistent and you're doing the right thing over a consistent period of time, you will see the right results with the right company. You have to make sure you trust who you're working with, too.   Sharon:          That's probably a big factor. One of the last questions, if you can tell us, is about how people find you. Do they only find you because of a web search, or do they find you other ways? How do they find you?   Stephanie:    The law firm?   Sharon:          Yeah, how do your clients find you, so they call you versus another company?   Stephanie:    They could do a web search and find us that way. We are Diamond Sponsors of the American Association for Justice, the AAJ. It's a national organization. We're also sponsors of the National Trial Lawyers. We do travel a couple of times a year to conventions and meet new firms. A lot of our clients come from other clients because our clients tell our story a lot better than anybody else. On our website, we have a bunch of FAQs and testimonials from our clients, but they can look us up on Google, social media and through our website.   We have a form on there so we can do free SEO audits for firms. We'd love for them to fill that out and see if it's something we can help firms with. We are working with firms all over the country, but we do have markets available, so we'd love to hear from anybody that's interested in not having to hire a company again. A lot of times, people come to us and say, “I'm tired of switching companies every year or every two years.” Our clients don't have to do that anymore. So, come to us and you don't have to continually look further.   Sharon:          That's a big point of differentiation. For everybody listening, we'll make sure to have the website link and any other links. Thank you so much. We really appreciate it, Stephanie.   Stephanie:    Thank you for having me, Sharon. It was fun.   Sharon:          Thanks. Stephanie:    Take care.

The Bike Shed
380: Remote Work Life

The Bike Shed

Play Episode Listen Later Apr 18, 2023 32:19


Joël has been working on his RailsConf talk about various aspects of discrete math useful in day-to-day work as a developer and going deep on some concepts from propositional logic and Boolean algebra, particularly DeMorgan's Laws, which explain how to negate a compound condition. Stephanie attended a meeting with a fun "Spicy Takes" topic. She gave a short talk on how frictionless technology may not be the best path forward and tried to argue in favor of more friction in our software. Together, they talk about ways they've made remote work work for them and things they'd like to try/do differently. This episode is brought to you by Airbrake (https://airbrake.io/?utm_campaign=Q3_2022%3A%20Bike%20Shed%20Podcast%20Ad&utm_source=Bike%20Shed&utm_medium=website). Visit Frictionless error monitoring and performance insight for your app stack. Taskmaster - Do Not Avoid Not Making the Bell Not Ring (https://www.youtube.com/watch?v=8iEnaOKGOFw) The Dark Side of Frictionless Technology (https://newsletters.theatlantic.com/galaxy-brain/6328fa97bcbd490021b314da/personal-tech-obsolete-user-experience/) Is Tech Too Easy to Use? (https://www.nytimes.com/2018/12/12/technology/tech-friction-frictionless.html) How to Do Nothing by Jenny Odell (https://www.penguinrandomhouse.com/books/600671/how-to-do-nothing-by-jenny-odell/) Rubber duck Debugging (https://rubberduckdebugging.com/) Schedule Shutdown, Complete Bike Shed episode (https://www.bikeshed.fm/310) Transcript: STEPHANIE: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Stephanie Minn. JOËL: And I'm Joël Quenneville. And together, we're here to share a bit of what we've learned along the way. STEPHANIE: So, Joël, what's new in your world? JOËL: I've recently got accepted to speak at RailsConf. And I've been working on my talk about various aspects of discrete math that are useful in day-to-day work as a developer and going really deep on some concepts from propositional logic and Boolean algebra, particularly the DeMorgan's Laws, which explain how to negate a compound condition. So if condition one or condition two, if you want to negate that thing as a whole, you can't just negate both of the conditions individually. You will get a totally different result, and that's a really easy mistake to make. I don't always memorize exactly what to do. But I know enough in the back of my head when it comes up on a pull request to check it out and be like, oh, there's a negating of a compound condition here. Pay closer attention. There might be a bug. STEPHANIE: So are you saying that when you negate each condition individually, you get the opposite result that you want? JOËL: It's not opposite, just different. STEPHANIE: Just different, okay. JOËL: So De Morgan's Laws tell us that if you want to negate the compound condition as a whole, you negate the individual clauses but then also have to flip the sign in the middle. So if you're trying to negate condition one and condition two, it becomes not condition one or not condition two. STEPHANIE: I see. Wow, that's confusing because you'd think that there are just two outcomes, but really there are a lot more. JOËL: Yes. STEPHANIE: And that reminds me of when we've talked about on the show combinatorial explosions, which I know is a favorite topic of yours. JOËL: Combinatorics will definitely come up in the talk as well. It's sometimes hard to hold all the possibilities in your mind. And so I'm a big fan of truth tables to visualize what's happening and to be like, oh, when I make this thing negative, now all these things flipped into false when I want them to be true and vice versa. Okay, I've got a weird inverse going on here or something like that. STEPHANIE: I have a funny thing to share with you. Joël, have you ever heard of the show "Taskmaster"? JOËL: No, I'm not familiar with this. STEPHANIE: Okay, it's a British reality competition comedy show where the contestants are usually famous British actors or comedians. And they have to do just really insane, silly tasks. And usually, one of the more iconic ones is to eat as much watermelon as you can in a minute. But they're just presented with a whole watermelon without any tools or anything [chuckles] for cutting it up. And it's just very funny and very delightful. And one of the tasks that I watched recently was a situation where they had to follow these instructions, and the instructions were to do the opposite of the following statement: "You must under no circumstances not avoid not making the bell not ring." And they had a bell right in front of them. And so they had to figure out if they were supposed to ring the bell or not ring the bell based on those instructions and within a certain time limit. If they had the math skills that you were talking about, [chuckles] perhaps they would have been able to figure it out. JOËL: I would absolutely want to write that out as a more formal logic thing. Otherwise, it becomes...you just mess with your head. You get in almost a recursive space where like, wait, not not, does that cancel? Does it stay? And yeah, it gets really messy. STEPHANIE: Yeah, it was very funny to watch them try to figure that out on the spot. And I think there's a clip of it on YouTube that we can link [laughs] for our listeners. JOËL: That's amazing. What's new in your world? STEPHANIE: So last Friday...you and I are on the same team at thoughtbot called Boost, and every two weeks, we get together as a team, and we have a meeting where anyone can propose a topic. It's just a nice space for people to see each other and hang out. And one of our co-workers hosted that meeting and he chose the topic of spicy takes and asked for volunteers to sign up and give a quick couple of minutes lightning talk on the spicy take that they had. And it was so fun. We got some takes on how REST is not the best. We got some opposing opinions about Tailwind. And I ended up giving a short, little talk on how frictionless technology may not be the best path forward and was trying to argue in favor of a little more friction in our software. JOËL: What would friction look like in this scenario? STEPHANIE: I was really interested in exploring how by making our software so easy for users we eliminate some amount of attention and mindfulness into using technology. So I think for me friction would be presenting the user with more autonomy and choice rather than making decisions on their behalf. I don't totally know what that looks like, but I do know that things like one-click ordering or autoplay those things have made me bristle a little bit in certain contexts and wondering what other options do we have available to us to provide the features we want to provide to our users but maybe not in a way that is so convenient and easy to use that we lose that aspect of knowing what we're doing with our technology. JOËL: I feel like knowing you, you've probably read a couple of articles and some books on this topic. And if I wanted to dig more into this idea of a little bit more mindfulness or introducing a little bit of friction into my software world, where would you recommend I go to read? STEPHANIE: Yeah, that's a great question. When I was preparing the talk, I referenced a few articles that I'll link in the show notes, one from The Atlantic and one from The New York Times. And I liked them because one of them presented what I was getting at, the more philosophical approach of like, what does it mean for our attention to be? And what does it mean for our technology to be too easy? And the other one had more practical use cases for security and technology misinformation and abuse. So I liked that those two things complemented each other equally. And then I also would plug a book called "How to Do Nothing: Resisting the Attention Economy" by Jenny Odell. I read that book last year and really enjoyed it. And she talks a lot about just the current technology landscape and what we, as consumers and users, can do to reframe our relationship with it. And I think that book is for people who use technology in general. But as developers, I think we are in a unique position to extend that train of thought right into the things that we develop. JOËL: You know, a place where I do appreciate friction is in the physical world. If there weren't any friction, my chair would not stay put on the ground. My fingers would not press on the keyboard. So we need friction to be able to do our jobs. So you work from home; I work from home because thoughtbot is now fully remote. How has that been for you setting up a work environment in your home? STEPHANIE: So I've actually been working from home since 2019. So about a year before the pandemic, I had moved to Chicago and was still working for a company in New York. And so that was when I started working from home, and then have just been doing that ever since. So I think I have now really figured out a setup that works for me. I've been doing it for four years now, which is pretty wild to me when I think about it. It's interesting because I actually really enjoyed going into an office. And there are parts of that that I really miss. But I think I have just gotten used to it and have a setup that works well for me. JOËL: Are there any things that you like to do for your environment to help get yourself into maybe the zone a little bit more easily? STEPHANIE: Yeah. So my workspace is a separate room from the rest of my apartment, which is also really just one big room. [laughs] It's kind of like a loft-style situation, so I don't really have doors. But I am in what we call the sunroom, and it's actually kind of like an enclosed porch with a big window and lots of plants. And it's in the back of the apartment. And so whenever I'm in this space, it's because I'm working. And I think having that separation of home and work is really helpful. Because when I step into this space, I'm like, okay, now I'm at work, and I don't have as many distractions as I would if I were working in a different space like a bedroom or the living room. JOËL: I have to say whenever you're on a video call, the plants around you are iconic. STEPHANIE: Oh, thank you. Yeah, it's been a nice conversation starter. When I'm meeting a new person, they usually comment on the plants, and I can give them a little show and tell. And that's been really nice. JOËL: I feel like a lot of people who work from home have put a lot of work into creating fun backgrounds for their video calls. Maybe they're setting up a cool bookcase behind them or plants. People like to put something behind them that will make things interesting on a video call in a way that maybe we didn't need to when it was just a conference room and in an office. STEPHANIE: Yeah, absolutely. I was just on a meeting with someone who had a big pile of tiny rubber ducks. So he was also a developer and, I guess, had just amassed this very delightful rubber duck collection, and it was just in the background. And we got to joke about it for a little bit, and that was really fun. JOËL: Are these rubber ducks meant to be used during debugging sessions? STEPHANIE: Yeah, exactly. JOËL: So I'm in a somewhat different situation from you in that I don't have a separate room to set up a home office. I've resisted doing anything in my bedroom. Like you said, it's good to have that separation. So I work more in my kind of living room-dining room space. And something that I found is really valuable for me has been movement. So say I work an hour in one part of the room, and then I switch to a different place. And it's going to be maybe a different posture. So I'm working in a solid chair table for a while, and then maybe I switch to more of an easy chair situation. That I think has been really helpful for me ergonomically during the day is just making sure that I'm not always in the same position constantly all the time but actually incorporating change in movement throughout my day. STEPHANIE: I like that a lot. I actually do also end up sitting at my dining room table sometimes for a change of scenery. It's funny because there was a while when...when I'm at my office desk, I have a standing desk. And so usually if I'm in a meeting, I would be at my desk and people would see me standing. And I think someone at some point mentioned like, "Wow, you seem to stand all day." And I was like, "Oh, well, when I'm not in a meeting, that's when I'm sitting on the couch or a lounge chair or something." [laughs] I'm curious, though, because you are working in your dining living space if it's been harder to separate work and home life. JOËL: I think it was definitely an adjustment, but it's a thing that I learned to do. And I still try to keep some amount of separation, which is why I don't set up an office space in my room. But I've also gotten to the point where now that I work from home, I find myself leaving home much more frequently after the workday ends. I was surprised just how much social interaction you get just by default being in an office around people all the time. When you're at home all day, even if you're on calls, it's not the same. And so I've found myself more and more to stay in a healthy emotional, mental space, leaving the home in the evening to go do things with friends or with other people. And so even though I am an introvert who prior to working from home preferred to stay at home more evenings than not, I've started living almost more of what people would assume is an extrovert lifestyle where I'm out every evening. STEPHANIE: Wow, that's so interesting because I'm the opposite; where when I was commuting and going to an office, I found it much easier to stay out. I would just go to a bar or a restaurant after work. Whereas now it's a bit harder because I'm not already out and about in the world, and also I am in my comfy pants, and I'm just like, oh, I have to go out? I don't know if I'm up for that. [laughs] Though I also really...I think the downside is that I have been really missing some of that human contact. And there are weeks where I'm like, dang, I really didn't talk to people in the world very much. So it's actually been a bit of a bigger obstacle for me to find the energy to see people in the evenings after work. JOËL: It helps to make plans. STEPHANIE: Yeah, that's a good idea. JOËL: Or you can have people come to you. You mentioned you were doing that soup club. STEPHANIE: I did, yeah, back when the winter was first starting. I mentioned on the show that I was having people over for soup on Friday nights, and that was really great. That was nice because then I was like, okay, I have to sign off by 5:00 p.m. so I can start making the soup. [laughs] MID-ROLL AD: Debugging errors can be a developer's worst nightmare...but it doesn't have to be. Airbrake is an award-winning error monitoring, performance, and deployment tracking tool created by developers for developers that can actually help cut your debugging time in half. So why do developers love Airbrake? It has all of the information that web developers need to monitor their application - including error management, performance insights, and deploy tracking! Airbrake's debugging tool catches all of your project errors, intelligently groups them, and points you to the issue in the code so you can quickly fix the bug before customers are impacted. In addition to stellar error monitoring, Airbrake's lightweight APM helps developers to track the performance and availability of their application through metrics like HTTP requests, response times, error occurrences, and user satisfaction. Finally, Airbrake Deploy Tracking helps developers track trends, fix bad deploys, and improve code quality. Since 2008, Airbrake has been a staple in the Ruby community and has grown to cover all major programming languages. Airbrake seamlessly integrates with your favorite apps to include modern features like single sign-on and SDK-based installation. From testing to production, Airbrake notifiers have your back. Your time is valuable, so why waste it combing through logs, waiting for user reports, or retrofitting other tools to monitor your application? You literally have nothing to lose. Head on over to airbrake.io/try/bikeshed to create your FREE developer account today! JOËL: So you mentioned that sometimes it's hard to leave the home because you're kind of in your comfy clothes, and you don't want to kind of get dressed to go out. Has working from home kind of changed the way you tend to dress? Do you ever do the thing where it's like, oh, I've got the formal top and then just sweats? STEPHANIE: Yeah. Like business on top and party in the bottom [laughter] or something like that is the phrase. My habits around getting ready in the morning have definitely changed; where I don't put as much energy or effort, or time into it as I did when I was working in an office. And that has been nice because I get that time back, and that is really valuable to me. Yeah, I'm also usually just in soft pants. [laughs] That has definitely been a very positive impact on my life. And I do try to make an effort to go out for coffee. And when I do that, I'm just like, yeah, how I go out is how I go out. I don't really mind. I'm very comfortable going out however I'm feeling that day. But I think getting the time back actually has been really important to me. JOËL: Hmm, I think for me, interestingly, that's become an interesting way to build a little bit of separation from personal life and work life. So I'm making a point to put on...I don't know how you describe it. I was going to say real pants, but it's not like sweats are not real pants. But yeah, I will put on the kind of thing that I would put on to go in the office. And for me, that's kind of a...it's a start to the day. It's a start to being more serious and transitioning to more of a work mindset. STEPHANIE: Yeah, absolutely. JOËL: As opposed to on the weekend, if I'm just hanging around in the same space, but I'm dressed differently, I don't feel like I'm in work mode. STEPHANIE: Yeah, yeah, that's fair. I've definitely noticed your fun sweaters that you wear in video calls and stuff. So I really appreciate that; yeah, you are just putting on clothes that make you feel like you're ready to dive into the work week. I'm really curious, do you find yourself being more productive working from home than you were working in an office? JOËL: I would say it's about even on average. There are probably days where more or less on one side or the other, but I would say it's similar. STEPHANIE: I think I'm actually much more focused at home. And I know that this is not true for everyone because I was chatting with a friend, and she was asking, like, "How do you stay focused at home?" She was telling me that she gets so distracted by all the things that she could be doing in her home life. And for me, because I really enjoyed the social aspect of being in an office, I found myself wandering into the kitchen not infrequently to go get some snacks, and oh, running into this person and having a little chat. And I think my presence also, I was available for other people to come to me and start a conversation or ask to go on a walk. And I think I actually really needed that external push to take breaks. Because now that I'm working from home by myself, I definitely just get into some rabbit holes, and it's tough for me to resurface. JOËL: Let me fix one more error, and then maybe the test will be green. Oh, that didn't fix it, but I'll bet one more would fix it. And keep doing that until it's like, oh, well, I'm going to push off my break for another 30 minutes, oh, another hour. And it's like, you know what? I'm just going to finish my day. STEPHANIE: That literally happens to me all the time. The lunchtime break is tough because I definitely will delay that by 15 minutes and then 30 minutes, and then oh no, it's like 2:00 p.m. Okay, let me just eat a snack, then. And then keep going until I finish whatever task, and then end up wishing that I had made a little more of an effort to take a real break. JOËL: Yeah, I was having a conversation recently with someone about how it's often easier to make space for other people than for yourself. So if somebody is like, "Hey, I want to take a break. Do you want to go take a walk?" You might be like, "Sure." Maybe I wasn't quite in a place where I wanted to take a break, but I'll make the time for you. Whereas when it's like, you know what? My body or my mind is telling me I need to take a break, but this test isn't green yet. So I'm going to almost deny myself here for the, I don't know, the good of the mission, whatever. It's not really a noble sacrifice. It ends up hurting you and the project in the longer run, but it's so much easier to do that. STEPHANIE: Wow. Okay, yeah, that really resonated with me because I find myself in situations where I don't think that I can take a break because I'm like, oh, I have all these red tests, and I need to get them in a place where I feel comfortable stepping away. But if someone asked me like, "Hey, I'm at your door. Let's go for a walk," I could just put it away and go for a walk and have a great time. And I would like to be able to do that for myself when I don't have someone prompting me. JOËL: There's something I really appreciated that someone who used to be at thoughtbot would do is this person would go for a walk every afternoon without fail and would drop a line in the Slack channel being like, "Hey, I'm stepping away for a walk." And, I mean, yeah, it's nice to know that, okay, this person's not reachable for the next 15 minutes or whatever. But that's not really, I think, the value that I got from it. It was more of seeing somebody else taking a break and it being a reminder for me too to be like, you know what? Maybe I should take a walk as well, like, it might be time for a break. STEPHANIE: Yeah, I like that a lot. I think it's kind of ironic that I have quote, unquote, "optimized" my setup so much that I don't get distracted that I miss out on the friction laughs (A little call back to earlier.) that I would like to, yeah, call more mindfulness to how I'm physically feeling, not even physically but also emotionally and intellectually and being prompted, like I said, externally because I am realizing now that I really need that. JOËL: And at least for us here in North America, it's now starting to be spring. And so I think sometimes winter can be its own barrier to be like, you know what? I should go and take a walk. I don't know if I want to put on all the layers and my boots and all of that and deal with the snow. Whereas now it's like, just walk out and there will be flowers and trees covered in blooms. And it's going to be amazing. STEPHANIE: Yeah, I'm really looking forward to that. I agree; I think when the weather is nice, that is definitely a bigger motivator for me because there's more to enjoy and more to look at. And I love being outside. When you do step away to take a break, what do you do in your home or outside your home? JOËL: So I'm a big fan of taking a walk. I live in a dense, walkable neighborhood, Downtown Boston. And so just walking around a few blocks is a great way to get a little bit of fresh air, just get some motion going because I've been sitting around for a long time. It's a lot of natural beauty as well. A lot of people have gardens, and there are a lot of trees planted along the roads. So it's just a really pleasant way to, in some ways, connect with a little bit of nature and be outside and reset. Do you find yourself when you're looking for a break gravitating outwards or inwards in your space? STEPHANIE: I like to make myself a snack, a cup of tea. Sometimes if I'm reading a good book, I'll get into the book for 20 minutes. And sometimes, if there's nothing to pick up, maybe I'll find myself on YouTube and watch a short little thing just to reset and have some fun. Sometimes I'll try to tackle some dishes. I think the other thing with working from home is that I now create more mess in my home. [laughs] I don't know if it's the same with you. But I, yeah, try to keep on top of that so that I don't have to do it later in the evening. JOËL: I think one of the things that's really nice about working from home is the ability to cook more because you're in that space. So I've found myself oftentimes more on my lunch break, maybe prepping some things for a stew or something that's going to braise, and then just having it sit on the stove all afternoon. And like I said, maybe a really quick break is just you get up, go check the pot on the stove, and you turn the heat down or stir it a little bit and then get back to work. STEPHANIE: Yeah, I like that a lot. I do that, too, with a pot of rice or beans or something like that. I also am definitely making my own food for lunch a lot more just because, being at home, you have your whole kitchen and fridge available to you, and I feel less pressure to get all that done the night before. JOËL: Right. I think I've been trying to incorporate a little bit more physicality to my breaks recently. And one thing that I've done for shorter breaks...if it is a longer break, it is nice to go out and take a walk. But for shorter breaks, I set up a pull-up bar, and I just try to go and do a set of pull-ups there. And I'm not great at it, so it's not like I'm there for 10 minutes doing 100 pull-ups. But it's a nice way to go from a very static mental mode to a quick break that just totally resets you into this active physical space. STEPHANIE: Yeah, I like that a lot because something like that requires your full attention and physical effort in that moment. So it's not like you can still really be thinking about work while you're in the middle of doing a pull-up, at least [laughs] that's my interpretation of [laughs] how you take those breaks. JOËL: I'm curious, are there any other kinds of lifestyle elements that you've changed or customized to help you have a better working-from-home experience? STEPHANIE: There was a past Bike Shed episode hosted by Steph Viccari and Chris Toomey, and I can't remember exactly what it was that they were talking about. It must have been working from home-related because Chris had mentioned a ritual that he had when he was finishing his workday where he would close his laptop and say, "Schedule shutdown complete." And I've been thinking about that a lot and trying to do a similar thing of just verbalizing, "I'm done with work now," to make it true. [chuckles] Otherwise, if I don't, I can find myself gravitating towards my laptop when I have a thought. Like, I have an idea like, oh, I just thought of a way to try to debug that test or whatever. And then I'll want to go back just really quickly to write it down on my work computer so it's there for me when I come back. But if I've said, "I am done with work today," that means I'm trying not to reopen the work laptop, and then I'll try to jot it down somewhere else. And that has been really helpful. JOËL: So, setting like an emotional boundary. STEPHANIE: Yeah, an emotional boundary that almost becomes physical in a way because when I was working in an office, I would never take my work stuff home with me, so I physically could not access it. And since I can't do that now, by verbalizing it, it's almost as if I've created a boundary in my head. JOËL: That's really powerful, the impact that you can have just by sort of verbalizing something. STEPHANIE: I will say that I also don't keep any work stuff on my personal devices and that was true even when I worked in an office, but I think it has actually been more helpful and important working remotely. It sounds like you've experimented with a lot of different ways to make remote working work for you. And I'm curious if there's anything else that you really want to change or anything that you would like to try or do differently. JOËL: I think an element that I've been experimenting with recently is actually working outside of the home, so something like going to the library or going to a coffee shop. Interestingly, I've tended to use those mostly for when I want to work on personal projects that are not work. So strangely enough, now I work in my home, and when I do things for myself that I previously would have maybe done in my home, now it's always at a coffee shop, at the library, something like that. So I still keep that separation, but it's inverted. STEPHANIE: Wow, that's really interesting. I also like to be in a more public space as well with my work. And just being surrounded by other people and busyness is very comforting for me. And it actually also helps with the rabbit hole because I think I am more present in my environment when I do have cues of people getting up around me or whatever. Though ironically, my wanting to be around other people does not really work well with meetings and collaborating and pairing with other people. [chuckles] And so when I have to do those things, even though I'm also socializing just in a different way, I usually have to be in a more quiet, private space. JOËL: Have you ever tried to maybe group your meetings on a particular day so that you have, let's say, an afternoon of uninterrupted time that you know you can just go to a coffee shop and be heads down and not have to take a call there? STEPHANIE: I haven't tried that. But I think that would be helpful because then it's kind of like the best of both worlds, right? Where I can say, "Hey, I can meet once I'm moved back into my private space," and also have that physical environment of being around other people. And I think I had previously thought just those things were mutually exclusive, but there are certainly ways that I'd love to try injecting that into my home-work setup. I'm really glad that we ended up talking about this because I think this will just be our future for a while. And it's always worth revisiting it and thinking about it and thinking if it's working for us or not. I'm really excited to try some of the new things that you mentioned. Like, we've been doing this for several years now, but there's always room for improvement and room to inject more fun and joy, and creativity in how we choose to do our work. JOËL: On that note. Shall we wrap up? STEPHANIE: Let's wrap up. Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeee!!!! ANNOUNCER: This podcast is brought to you by thoughtbot, your expert strategy, design, development, and product management partner. We bring digital products from idea to success and teach you how because we care. Learn more at thoughtbot.com.

The Bike Shed
378: Leadership and Impact as an Individual Contributor

The Bike Shed

Play Episode Listen Later Apr 4, 2023 38:16


Today's episode is "Old News"! Stephanie shares her ergonomic desk setup. Joël talks about the pyramids. Another old thing is the Bike Shed episode two weeks ago about success and fulfillment. Stephanie and Joël realized off-mic that one area they didn't really talk about so much is impact, and that is something that is very fulfilling for both of them. Today, they talk about impact and leadership as individual contributors because leadership is typically associated with management. But they believe that as ICs, at any level, you can be displaying attributes of leadership and show up in that way on teams. This episode is brought to you by Airbrake (https://airbrake.io/?utm_campaign=Q3_2022%3A%20Bike%20Shed%20Podcast%20Ad&utm_source=Bike%20Shed&utm_medium=website). Visit Frictionless error monitoring and performance insight for your app stack. Success and Fulfillment episode (https://www.bikeshed.fm/376) Logitech MX Vertical (https://www.bestbuy.com/site/logitech-mx-vertical-advanced-wireless-optical-mouse-with-ergonomic-design-graphite/6282602.p?skuId=6282602&ref=212&loc=1&extStoreId=319&ref=212&loc=1&&&gclid=EAIaIQobChMItMP27PT8_QIVfMiUCR0_dwVqEAQYASABEgIWJ_D_BwE&gclsrc=aw.ds) Rose Wiegley's Lead From Where You Are (https://www.youtube.com/watch?v=1GorXHiB7nw) Transcript: JOËL: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Joël Quenneville. STEPHANIE: And I'm Stephanie Minn. And together, we're here to share a bit of what we've learned along the way. JOËL: So, Stephanie, what's old in your world? STEPHANIE: I'm glad you asked that question because I don't think we get a chance to talk about things that are exactly the same as they've always been. And so today, I'd like to share my ergonomic desk setup, [laughs] which has been old for about a year or so. And back then, I was having some issues with some back pain and some wrist pain, and I made a few upgrades and since then have not had any issues. And I feel like it's one of those things that I just forgot about because when it stops being a problem, you don't really notice it. And today, I am able to reflect on my old problem of bodily pain while working. And I'm happy to say that things have been much better for a while now. JOËL: Oh, that's amazing. What's one thing you think had the most impact in your setup? STEPHANIE: Oh, I picked up one of those vertical mice for my wrist. I was having some wrist pain, like I mentioned. And I actually solicited some input from other thoughtboters for the best mouse to replace the Apple Magic Mouse that I was using, which I really wanted it to work for me because I liked the way it looked, but nevertheless, that was causing me issues. So I ended up with the Logitech MX vertical, and that has really solved my wrist pain. It is very not cute. [laughs] It kind of looks like a weird big, gray snail. But you know what? You got to do what you got to do. JOËL: That sounds like an art project waiting to happen. STEPHANIE: Yeah. I would love to see; I don't know, a way to make these vertical mice look a little more cute. Maybe I will stick some googly eyes or something on it and then just be like, this is my pet snail [laughs] that works with me every day. JOËL: Do you have a name? STEPHANIE: Not yet. Maybe I'll save it for what's new next week. [laughter] JOËL: Homework assignment. Years ago, I was also having some wrist pain. And I think one of the most impactful things I did was remapping some keys on my keyboard. So I'm a pretty heavy Vim user. And I think just reaching with that pinky for the Escape key all the time was putting a lot of strain on my wrist. So I remapped Caps Lock to control. That's what I did. Yes, because it was reaching down with the pinky for the Control key and remapped escape to hitting J twice. So now I can do those two very common things, Control for some kind of common chord and then Escape because you're always dropping in and out of modes, all from the Home row. And now, both my hands feel great, and I can be happy writing Vim. STEPHANIE: That's really nice. I think when I had asked in Slack about mouse recommendations, someone had trolled me a little bit and said that if I just use my keyboard for everything, then I won't need to use [laughs] a mouse at all. [laughs] So there's also that option too for listeners out there. JOËL: It's true. You go to tmux and Vim, and on a Mac, maybe something like Alfred and a few OS shortcuts, and you can get 90% of the way to keyboard only. STEPHANIE: What about you, Joël? What's old in your world? JOËL: So you know what, something that's really old? Pyramids. STEPHANIE: Wow. [laughter] I should have known that this is where we were headed. JOËL: Long-term listeners of the show will know I'm a huge history nerd. And we think of the pyramids as being old, but they are ridiculously old. A fun fact that I have not learned recently because this is something that is old in my world, but that I learned a while back is that if we look back to Cleopatra, the last Pharaoh, she is closer to us in time than she was to the building of the Great Pyramid. STEPHANIE: No. What? Wow. Okay, yeah, that definitely just messed with my brain a little bit. And now, I have to rethink my understanding of time. JOËL: I think the way the timeline sort of works in my mind is it tends to get compressed the further back you go. So it's like, yeah, I think of modern-ish times, like, yeah, there's like a lot of stuff, and I'm thinking in terms of decades until maybe like the 1900s. And now I start to think in terms of centuries. And they're kind of more or less equivalent, you know, the Victorian Age. It fills about the same amount of space in my mind as like the '60s. And then you get to the point where it's just like millennia. STEPHANIE: Mm-hmm. When you think of Ancient Egypt, do you think Cleopatra and also pyramids, so you kind of conflate? At least I do. I conflate the two a little bit. But yeah, I guess a lot of time passed in between that. [laughs] JOËL: The pyramids are also really cool because they were one of The Seven Wonders of the ancient world, which is sort of, I want to say, like a tourist circuit created by the ancient Greeks, sort of like monuments that they thought were particularly impressive. But they're also the only ones that are still standing; all of the others have been lost to time. STEPHANIE: Wow, it's the real wonder then [laughs] for being able to stand the test of time. JOËL: It's also the oldest of the seven and has managed to survive until today, so very impressive. STEPHANIE: I love that. Just now, when you were talking about thinking about time periods kind of compressed, I definitely fall victim to thinking that the '70s or whatever was just 30 years ago, even though we are solidly in the 2020s and, in reality, it's obviously like 50. But yeah, I think that always freaks me out a little bit. JOËL: Yes, it's no longer the year 2000. STEPHANIE: Turns out. [laughs] So, in case our listeners didn't know. [laughs] JOËL: I think when we were close-ish to the turn of the millennium, it just made mental math so easy because you're at that nice zero point. And then you get to the early 2010s, and it's close enough within a rounding error. And now we just can't pretend about that anymore. STEPHANIE: No, we really can't. JOËL: We need a new anchor point to do that mental math. STEPHANIE: I love that we're talking about what's old in our world because I love a chance to just repeat something that I've said before that I still think is really cool, but I feel like that doesn't get invited as frequently. It's just like, oh, how are you doing? What's new? So yeah, highly recommend asking people what's old in their world? JOËL: Yeah. And beyond that, not just like, what are some new things you're trying? But kind of like what you were talking about earlier, what's something that's stayed stable in your life, something that you've been doing for a while that works for you? STEPHANIE: Yeah, I love it. So another thing that's old is our episode from a couple of weeks ago about success and fulfillment. And you and I realized off-mic that one area we didn't really talk about so much is impact, and that being something that is very fulfilling for both of us. And that kind of got me thinking about impact and leadership. And I especially am interested in this topic as individual contributors because I think that leadership is typically associated with management. But I really believe that as ICs, at any level, really, you can be displaying attributes of leadership and showing up in that way on teams. JOËL: Definitely. I think you can have an impact at every level of the career ladder, not just an impact on a project but an impact on other people. I remember the first internship I did. I was maybe two weeks in, and I had a brand new intern join. It's day two, and I'm already pairing with him and being like, "Hey, I barely know anything about Rails. But if you want help with understanding instance variables, that's the one thing I know, and I can help you." STEPHANIE: Yeah, that's awesome. I mean, everyone knows something that another person doesn't. And just having that mindset of injecting leadership into things that you do at work, no matter how big or how small, I think is really important. JOËL: I think there's maybe a lie that we tell ourselves, which is that we need to wait to be an expert before we can help other people. STEPHANIE: Yeah, I've certainly fallen into that trap a little bit where I think it's held me back from sharing something because I assumed that the other person would know already or the thing I'm thinking is something I learned but not necessarily something that someone else would find interesting or new. JOËL: Right. Or even somebody's looking for help, and you feel like maybe you're not qualified to help on that problem, even though you probably are. STEPHANIE: One thing that I was really curious about is, can you remember a time when an IC on your team demonstrated leadership, and you were really impressed by it? Like, you thought, like, wow, that was really great leadership on their part, and I'm really glad that they did that. JOËL: Yeah. So I think one way that I really appreciate seeing leadership demonstrated is in client communication. Typically, the teams we have at thoughtbot are structured on a particular project where there's like a team lead who is in charge of the project. It's usually a couple of consultants working together as peers. Depending on the situation, one or the other might take leadership where it's necessary. But I've really appreciated situations where a colleague will just really knock it out of the park with some communication with the client or when they are maybe helping talk through a difficult situation. Or maybe even we realize that there's a risk coming down the pipeline for the project and raising it early and making sure that we de-risk that properly. Those are all things that I really appreciate seeing. STEPHANIE: Yeah. I think the way folks engage in channels of communication can have a really big impact. A few things that come to mind for me that I think is really great leadership is when more experienced or senior folks ask questions in public spaces because that kind of cultivates a space where asking questions is okay, and even people who have whatever title or whatever years of experience they still have questions and can signal to other folks in the team that this is okay to do. And the same thing goes for sharing mistakes as well. Also, just signaling that, like, yeah, we mess up, and that's totally normal and okay. And the consequences aren't so scary that people feel a lot of pressure not to make mistakes or share when they happen. JOËL: Yeah. The concept you're describing is very similar to the idea of vulnerability. STEPHANIE: Yeah, that sounds right. JOËL: So kind of modeling that from more senior people helps create a safer environment for the more junior people. STEPHANIE: I think another thing that I really love that others do for me, and something that I want to get better at doing for others, is speaking up when something is a little off because, again, with power dynamics, for people who are newer or less experienced, they might be noticing things, but they don't feel encouraged to speak up about it in a public space or even with their manager. But they might confide in another IC who is maybe a little more senior. And one thing that I really liked that happened on my client project recently is a senior engineer said in Slack, "Hey, I noticed some sentiment from our daily sync meeting that we're cutting it close to our deadline." And he asked like, "Should we shift some priorities around? Or what is more important to make sure that we focus on in the next few weeks before the end of the quarter?" And I was just really glad he said that because I certainly had been feeling it. But I don't know if I necessarily kept a pulse that other people were also feeling it. And so having someone keeping an eye on those things and being receptive to hearing that from folks and then being like, okay, I want to make sure that I bring it up to the manager because it's important. I thought that was really cool. JOËL: Yeah. Now we're almost dialing into sort of emotional awareness of what other people on the team might be feeling and also the ability to think in terms of risks and being proactive about managing those. STEPHANIE: I like your use of the word risks because that definitely feels like something that, in general, people are scared to bring up. But ultimately, it is the signal of someone who is experienced enough to know that it's important to make transparent and then adjust accordingly. Even beyond noticing what folks are feeling, there are also more concrete things that can be noticed as well, like if team members are complaining about CI build time being really long and that being a repeating issue in getting their work done. Or any other development or tooling thing that is causing people issues, having someone notice how frequently that happens and then being like, hey, this is a problem. And here's what I think we should do about it. JOËL: So not only the awareness but also the initiative to try to enact change. STEPHANIE: Yeah, absolutely. MID-ROLL AD: Debugging errors can be a developer's worst nightmare...but it doesn't have to be. Airbrake is an award-winning error monitoring, performance, and deployment tracking tool created by developers for developers that can actually help cut your debugging time in half. So why do developers love Airbrake? It has all of the information that web developers need to monitor their application - including error management, performance insights, and deploy tracking! Airbrake's debugging tool catches all of your project errors, intelligently groups them, and points you to the issue in the code so you can quickly fix the bug before customers are impacted. In addition to stellar error monitoring, Airbrake's lightweight APM helps developers to track the performance and availability of their application through metrics like HTTP requests, response times, error occurrences, and user satisfaction. Finally, Airbrake Deploy Tracking helps developers track trends, fix bad deploys, and improve code quality. Since 2008, Airbrake has been a staple in the Ruby community and has grown to cover all major programming languages. Airbrake seamlessly integrates with your favorite apps to include modern features like single sign-on and SDK-based installation. From testing to production, Airbrake notifiers have your back. Your time is valuable, so why waste it combing through logs, waiting for user reports, or retrofitting other tools to monitor your application? You literally have nothing to lose. Head on over to airbrake.io/try/bikeshed to create your FREE developer account today! STEPHANIE: So you and I are actually working on the same client but on different project teams. And you've been involved with making improvements to CI to reduce kind of the problem that I was just talking about where it takes a while for us to develop. And you are working on reducing the number of days between the master branch and when you are allowed to hit the merge button to make sure that feature branches had incorporated the latest changes for master. And one thing that I really like that you did was you solicited folks' input for what that time range should be. So I think you were playing around with the idea of giving people three days to merge, or else they'd have to rebase. JOËL: I thought it was being really comprehensive here with three days because, you know what? You solicited feedback, you got review, but maybe it's the end of the day, or maybe someone's in different time zones. So we definitely want to cover at least a 24-hour period. So three days gives you an extra day. It should be safe. Is there any common situation where you might want a PR to be open for more than three days, but you wouldn't have rebased the latest master changes? STEPHANIE: Yeah. I can see how you thought about it from a few different angles too. Like, you're thinking about time zones and folks working in other regions. And I ended up responding to you, and I was like, oh, what about the weekend? [laughs] JOËL: Oops. STEPHANIE: Because three days seems a little short if two of those days are eaten up by Saturday and Sunday. But what I liked was that you said, "Hey, I'm thinking about doing this. What do other people think?" Because you didn't claim to know what works best for everyone. And I think that's a really important skill to be honest, soliciting others for feedback, and knowing who to ask for and who to make sure you are not negatively affecting their work by making a change or making a decision. JOËL: And in this case, it helped me realize that I had skipped over the most obvious edge case while thinking I'd covered all the really niche ones STEPHANIE: We got there in the end, [laughs] and I think made the most informed decision. JOËL: I guess that's just good product design in general. Talk to your users, get early feedback, put a prototype out where necessary. You don't always want your users to dictate what you will do, but it's good to get their feedback. And similarly, I think that applies when working with dev-facing things; you want feedback from developers. If I asked everybody at the company, I would have gotten a lot of different answers. And I might not have gotten one that satisfied everybody. But having some of that feedback helps me make a more informed decision. STEPHANIE: Yeah, and to take it to the next step, I think there's also accountability for those decisions that you have to have. So if the decision that you made ends up being like a huge pain for some unforeseen reasons, I imagine you'd be on top of that as well and would want to figure out how to adjust if the experiment doesn't work as well as you would have liked. JOËL: Right. I think we often talk about failing early. In fact, we have a recent episode about dealing with failure. And we mostly talked about it from a technical perspective, catching errors or making code more resilient to failure. But there is also a human component of it, which is if you catch errors or design problems, and I'm using design here as a product design, not in visual design, at a prototype phase or maybe a user interview phase, you've saved yourself a lot of maybe unnecessary work that you would have had if you went out to the product phase and shipped it to your entire customer base. I guess, in a sense, it's worth thinking about other developers, the engineering team as customers sometimes. And a lot of the internal facing parts of your project are effectively a product geared towards them. They are the users. And so, throwing in a little bit of product development and design skills into building internally-facing software can have a huge impact. So beyond just thinking of developers as a sort of internal customer base, occasionally, we work on projects where you are building internal tooling for other teams; maybe it's business development, maybe it's the marketing team, maybe it's some form of customer support. And that can often have a really large level of impact. Have you ever been on a project like that? STEPHANIE: I have. One of my first jobs was for an e-commerce company. And I built tools for the customer support team for dealing with customers and getting their orders correct and fixed and whatnot. So I did work on an admin dashboard to make their jobs easier as well as the company also had its own internal software for dealing with warehouse logistics. And so, I also built a little bit of tooling for our logistics and fulfillment team. And I really liked that work a lot because I could just go over and talk to the folks internally and be like, "Hey, what did you mean by this?" Or like, "What do you want here, and what would make your life easier?" And I felt a much more tangible impact than I did sometimes working on customer-facing features because I would deliver, and that goes out in the world. And I don't get to see how it's being used, and the feedback loop is much longer. So I really liked working on the internal tooling. JOËL: In my experience, those teams are often really underserved when it comes to software. And so it's possible to make a huge impact on their quality of life with relatively little work. Sometimes you can just take an afternoon and eliminate a thing that's causing them to pull out their hair. STEPHANIE: Yeah, absolutely. And you get the satisfaction of knowing that you built something exactly as they wanted it. Whereas sometimes, with user or customer-facing features, we are guessing or experimenting a little bit. And yeah, I think having someone who then is very grateful for, I don't know, the button that you added that makes them have to click less buttons [laughs] when they do their work in an internal dashboard can feel really good. JOËL: Having that direct access can be really nice where you get to just go over and talk to them or shadow them for a day, see how their work happens, get to hear their frustrations real-time. It's often a smaller group as well than you would have for our customers, which might be thousands of people, and so you sample a few for user testing. But for an internal team, you can get them all in a Zoom call. I don't necessarily recommend doing a giant Zoom call for this kind of thing, but it's a small enough group that you could. STEPHANIE: I'd like to flip that around to you. Have you ever been on the receiving end of an improvement or someone else making your life a little easier, and if you could share what that was and how it made you feel? JOËL: I think pretty early on in my career, one of my first projects for thoughtbot, we were building a small kind of greenfield app for a startup. And another member on the team took a couple of hours one afternoon to just write a few small abstractions for the test suite that; just made it so much nicer to write tests. And we're pretty scrappy. We've got a tight deadline, and we're trying to iterate very quickly. But that quality of life difference was significant to the point I still remember this ten years later. I think we were rotating this developer off, and this was kind of a farewell present, so... STEPHANIE: That's really sweet. JOËL: You know what? I love that idea of saying when you rotate off a project, do a little something extra for the people you're leaving behind. STEPHANIE: Yeah, I love that too. It's your kind of like last chance to make a small impact in that world. JOËL: Especially because on your last couple days, you're probably not expected to pick up a ticket and get it halfway done. So as you're kind of ramping down, you might have a little bit of time to do some sort of refactoring task or something that needs to get done but hasn't been prioritized that will have a positive impact on the team. STEPHANIE: Yeah, or even writing a script to automate something that you have kind of developed the muscle memory for, like, oh, I run these three commands in succession. And if you could just wrap it up in a little script and hand it off to someone else, it is a very sweet parting gift as well. JOËL: Absolutely. So I'm curious, we opened the topic talking about impact, and you immediately connected that to leadership, and I want to explore that idea a little bit. Do you think impact has to be connected to leadership? Or are there ways to have impact, maybe outside of a leadership role? STEPHANIE: I think they kind of go hand in hand, don't you? Because if you are wanting to make an impact, then in some ways, you are demonstrating that you care about other people. And at least for me, that is kind of my definition of leadership is enabling other folks to do better work. And you and I talk about attending and speaking at conferences pretty frequently on the podcast. And that is a very clear way that you are making an impact on the community. But I also think that it is also a demonstration of leadership that you care enough about something that you want to share it with others and leave them with something that you've learned or something that you would like to see be done differently. JOËL: And just to be clear here, the way you're talking about leadership is not a title; it's an action that you do. You're demonstrating leadership, even if you don't have any form of leadership title. STEPHANIE: Yeah, absolutely. I think that because software development is a collaborative job, in some ways, in most things we do, there is some form of leadership component, even if you're not managing people or you don't have a particular title. JOËL: Like you said, it's about the things that you're doing to enable other people or to act as a sort of force multiplier on your team rather than how many people report to you in the org chart. STEPHANIE: Yeah, absolutely. JOËL: So if everybody aspires to enable each other and to be impactful, is it possible to have a team where every person on the team is a leader? STEPHANIE: Whoa, [laughs] asking the big questions, Joël. I mean, logically, the answer seems to be no based on our traditional understandings of leadership and being a leader or follower. But I also kind of disagree because, as developers, we have to make choices all of the time, and that can be at the level of the code that we write, the commit messages we write, what we communicate in our daily sync. And those are all opportunities, I think, to inject those skills that we're talking about. And so, yeah, everyone on the team is making decisions about their work. And inherently, to me, at least, the way you make those decisions and the impact of those decisions imply some form of leadership. What about you? What do you think about this? JOËL: It's tough because you can get into bikeshedding the definition. STEPHANIE: [laughs] JOËL: Which, hey, it's all about that, right? You know, is leadership about authority or decision-making capacity? Is it about impact? Is it about maybe even responsibility if things go wrong? Who's responsible for the consequences? It could be about position in the org tree and relative depth on that tree, to use some data structure terminology. But I liked your emphasis on the idea of impact and enabling others. So now it's a thing that you do. And so any member at any moment can be demonstrating leadership or acting in some leadership capacity, and they're contributing to the team in that way. And in the next moment, somebody else stands up and does the same thing. And it doesn't necessarily have to be in conflict. You can actually be in a beautiful harmony. STEPHANIE: Yeah, I really like the way you said that. I love a good beautiful harmony. [laughs] I think part of what has shaped my view on this is a keynote talk from RubyConf Mini back in November by Rose Wiegley. And her talk was called "Lead From Where You Are." And I think perhaps I've kind of internalized that a little bit to be like, oh yeah, everything we do, we can make a decision that can have a positive impact on others. So that has helped me at least feel like I have a lot more agency in what I do as a developer, even if I don't have the concrete responsibility of being a mentor to a particular person or having a direct report. It injects meaning into my work, and that goes back to the fulfillment piece that we were talking in, knowing that, like, okay, like, here's how I can make an impact. And that's all just wrapped up together. JOËL: So you kind of defined earlier the idea of leadership as work that has impact on others or that enables the work of others. And I think that there are some forms of that work which are kind of highly respected and will get you noticed and will be kind of called out as like, oh, you're performing leadership here. You stood up in that meeting, and you said the hard thing that needed to be said. And there are other forms of supporting or enabling the team that almost get viewed as the opposite of leadership that don't get recognized and are almost like you're seen as less of a leader if you're spending a lot of your time doing that. That can be sometimes more administrative work. How does that sort of fit into this model where we're talking about leadership as something that has an impact on others? STEPHANIE: Yeah, I'm glad you mentioned that because I have a lot of gripes [laughs] and thoughts, I suppose, about what work is visible and not visible and valued more or less. And I do think some more traditional signals of leadership, like talking the most in a meeting, like, that I don't necessarily think is my definition of leadership; in fact, the opposite. A true leader, in my opinion, is someone who makes space for others and makes sure that all voices are heard. And yeah, I guess it just speaks to like what I was saying about soliciting other people for feedback as well. It's like someone to me who demonstrates leadership is not someone who thinks that they have all the right answers but actively seeks out more information to invalidate what they think is right and find the right solution for the folks on their team. Similarly, in Rose's talk, she also mentions the idea of being a problem finder, so not just being tasked with solving a problem but looking around and being like, okay, like, what aren't we talking about and that we should be? And obviously, also contributing to making that better and not just being like, "Here's a bunch of problems, [laughs] and you have to deal with it," but that proactive work. Ideally, we are addressing those things before they become a huge problem. And I really liked that aspect of what leadership looks like as well. JOËL: Yeah, I think something that I've noticed that I do more as I've built more experience over time is that when I started off earlier in my career, it was a lot of here's a problem that needs to be solved, go and solve it. And then over time, it's what are the problems that need to be solved? You have to sort of figure out those problems before you go and solve them. And then sometimes it's even one level above that; what questions should we be asking so that we can find the problem so that we can solve them? And that will happen...it could be internally, so some of the things that I'm doing currently around improving the experience of a test suite is like, okay, we know sort of that it's slow in certain ways. How can we make that faster? We know that the experience is not great. But what are the actual problems that are happening here, the root causes? Or we're getting some complaints, but we don't really know what the underlying problem is. Let's go and search that out. STEPHANIE: Yeah, that brings to mind an issue that I think I see a lot on client projects where perhaps stakeholders or an engineering manager is seeing that we are slow to merge our PRs, and they kind of start reaching for solutions like, okay, well, people should spend more time doing code reviews or whatever, thinking that that's what the issue is. But in reality, maybe it's, I don't know, it can even be something as lower level as having to re-request reviews every single time you push a new commit because the GitHub settings are such that it requires additional approvals for every new change. And that is something that they would not know about unless someone spoke up and said, "Actually, this is what's causing us friction," and having to go back and do these manual tasks that maybe we should explore a different alternative to solve. JOËL: Yeah, instead of just jumping in with a solution of we need to throw more dev hours at this problem, it can be useful to step back and ask, okay, well, why do we have this problem in the first place? Is it a process issue that we have? Is there some sort of social element that we need to address and organizational problems? And if it's not that, then what are the questions that we're missing? What questions should we be asking here to understand this problem? STEPHANIE: Right. And even speaking up about it too and going against someone's assumption and saying, "Here's what I've been seeing, and this is what I think about it," that takes a lot of courage. And I do think it is something that is especially important for folks who are more experienced and have more responsibility or a higher-level title, but ideally is something that anyone could do. I would love to know for you, Joël, what is the most important way that you want to make an impact as a developer? JOËL: I think the human element is the most important. I want to have an impact on my colleagues, on the dev teams with my clients. I want to ship good work. But I think the most valuable thing to invest in is other people. STEPHANIE: Yeah, I agree. I think for me; it's like making a good work experience for the people that I work with. And it's also a little bit selfish because then that means I am having a good work experience, and I'm in a good culture and environment. But that is definitely an area that I spend a lot of time thinking about and wanting to start conversations about. JOËL: It's a win-win, right? You make it better for everybody else and better for you in the process. STEPHANIE: Exactly. JOËL: And it's okay for it to be somewhat selfishly motivated. Like, it doesn't have to always be every day super altruistic like; I just want to make the world a better place. STEPHANIE: [laughs] JOËL: Like, you know what? I want my corner of the world to be better, and in doing so, I'm going to make it better for everyone else. STEPHANIE: What's that phrase? The tide rising all the ships. [laughs] That is extremely not correct, but I think you know what I'm trying to say. JOËL: I think a rising tide lifts all boats. STEPHANIE: Yeah, something like that. I love a good rising tide. [laughs] On that note, shall we wrap up? JOËL: Let's wrap up. Or let's rise up. STEPHANIE: [laughs] STEPHANIE: Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeee!!!!! ANNOUNCER: This podcast is brought to you by thoughtbot, your expert strategy, design, development, and product management partner. We bring digital products from idea to success and teach you how because we care. Learn more at thoughtbot.com.

The Bike Shed
377: Error Handling

The Bike Shed

Play Episode Listen Later Mar 28, 2023 45:06


Joël is a mentor for RailsConf and got matched with a speaker. Stephanie has been having trouble stepping away from her work. It's frustrating when chasing down a bug because something's gone wrong, and you spend a whole afternoon figuring out where it is. Joël and Stephanie discuss error handling as a possible solution. This episode is brought to you by Airbrake (https://airbrake.io/?utm_campaign=Q3_2022%3A%20Bike%20Shed%20Podcast%20Ad&utm_source=Bike%20Shed&utm_medium=website). Visit Frictionless error monitoring and performance insight for your app stack. Mis en Place Writing (https://www.swyx.io/writing-mise-en-place) Errors accumulate at boundaries (https://thoughtbot.com/blog/testing-your-edge-cases) Retryable errors (https://thoughtbot.com/blog/handling-errors-when-working-with-external-apis) Transcript: STEPHANIE: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Stephanie Minn. JOËL: And I'm Joël Quenneville. And together, we're here to share a bit of what we've learned along the way. STEPHANIE: So, Joël, what's new in your world? JOËL: So recently, RailsConf has closed out their CFP, and they've started sending out acceptances and rejections for proposals. And one thing that they do that I think is really nice is that they offer first-time speakers the ability to get matched with a speaker-mentor, somebody else who has given talks before that can help them prep their talk, listen to them rehearse, that kind of thing. And so they had put out a call for mentors last week. I responded to that, and I got matched with a speaker today. STEPHANIE: Cool. Is this your first time being a speaker-mentor? JOËL: First time for RailsConf. I've done it for another conference before. STEPHANIE: That's really exciting. What do you like about playing that role? JOËL: So I very much like prepping and giving talks myself. And I really value if there's something that I'm excited about sharing it, helping others build up that skill as well. So I think it's a great opportunity. I also remember what it was like when I was a first-time speaker and just how very nervous I was and not sure. So I think having someone who can play that role is an opportunity to have a really powerful impact in what's oftentimes, I want to say, a monumental moment. But it's kind of like a milestone marker moment in someone's career, the first time I gave a talk at a conference. So you get to help them to make that moment the best it can be. STEPHANIE: I love that, yeah. You make a really great point that after you've been speaking for a while, you maybe might forget what it felt like to give your first talk and how big of a deal it is. And in general, I think one thing I really love about Ruby Central conferences is how supportive they are of first-time speakers. So even in the CFP, they mentioned that they welcome first-time speakers and want to make sure to accept talks from those folks and then provide them support through this mentor program. And yeah, it just makes me feel really happy. JOËL: Do you remember your first talk? STEPHANIE: I do. So my very first talk I gave virtually at RubyConf in 2021. And then last year was actually my first in-person talk. And I remember even though it was technically my second talk; it was really my first talk in front of an audience. And I saw speakers in the Slack workspace asking questions about the AV setup, and I didn't even think to consider that in my preparation. So it was nice. Even though I didn't get set up with a mentor, to share a space with other experienced speakers and see what kinds of things they were asking about or what kinds of things they were sharing in that Slack space was helpful for me. JOËL: So when you do a proposal, do you typically have an outline already built out, or is it mostly a concept that you're pitching, and then you maybe start with an outline? Or where do you go next after a proposal has been accepted? STEPHANIE: That's a great question. I think first, I procrastinate for several months, [laughs], but I do try to write an outline in the proposal when I submit it so I do have a starting point. And I think that actually helps the CFP committee, too, when they are evaluating proposals to kind of get a better idea of what the talk will be about. And so, in my ideal world, I already have some structure, so by the time I've procrastinated to the point where it's a month or so before the conference itself, [laughs] I have an outline. And I end up writing words, like, I will just write my talk as if it were an essay with this bullet point outline already. And I find that helpful for me because I definitely have a bit of a stream-of-consciousness productivity energy. And so if I just put it all out there, I will then go back and be very ruthless, I suppose, in my editing, and I think that's where the magic happens. So I kind of let myself just word vomit all over the page. And then the real work comes in the editing process and organizing and making sure it sounds the way I would want it to sound when I'm speaking. And yeah, that's how it has worked for me so far. JOËL: So you have a sort of a separate phase for sort of just stream of consciousness dumping and then separately editing. And having those two separate is an important part of your process. STEPHANIE: Yeah, I think so. I don't do as well trying to imagine the structure and everything perfectly the first time around and then filling things in. I find that just putting everything out there and, you know, a lot of things get cut. But that works well for me. What about you? What is your typical conference talk writing process? JOËL: I think mine is a little bit more iterative. I tend to put in some pieces that I like and then try to connect them together, try to make sure it's telling a story. I think a lot about the pedagogical side of things, where people are going to be confused, where they're going to have questions, where they might check out. And then very early, start doing kind of draft rehearsals where I'm starting to work on the talk. And I will stop halfway through because, in my mind, I'm trying to seat myself in the audience and be a person who's listening. And there might be a moment where I'm like, wait a minute, you just jump from one thing to another, and I don't get the logical connection here. And I might pause right there in the rehearsal and add in, say, okay, we need a transitional point, or we need to explain a concept between these two. And I keep doing that until I can get through the whole thing and then realize it's way too long and start cutting. And I cut aggressively, and now it's too short. And now I go through it again. And again, people have questions in the audience, hypothetical audience; I am the audience. And so I really kind of inflate it and then cut it down and re-inflate it and cut it down a bunch of times until I'm happy. STEPHANIE: I like that a lot. That sounds right. That sounds very you to work even on a conference talk iteratively. JOËL: It's very time-consuming. So I don't know it's the most efficient way to build a talk, but it's a process that works for me. STEPHANIE: Yeah, that's true. And then there's value in the journey, even if the talk ends up changing from the very beginning to the end product. JOËL: So the approach that you described for yourself, I think, where you have a rough draft, and you're separating the editing from almost like a creative process, reminds me a lot of an article that I read called "Mise en Place Writing" by...I'm not sure what their full name is. They go by the handle Swyx. This is an article about their process for writing, but I think it applies to conference talks as well. Have you seen this article? STEPHANIE: I haven't. But that, I think, is similar to how I've thought about it or I've seen or heard other authors talk about their writing process and it being kind of similar where the creative work...they give themselves a lot of grace and just letting it be. And then the, like I mentioned, real work is in the editing process. It's kind of two different mindsets, I think. JOËL: We'll link the article in the show notes. STEPHANIE: I'm curious then how you incorporate visuals into your process because I think that's where my workflow is a little less successful because I'm not really thinking about visuals along with the words, and they do feel more like an afterthought. And I've always been really impressed when people who give talks can have a really visual and dynamic slide presentation. How does that work for you? JOËL: So I think I try to avoid slides that are three bullet points in the slide, and then I'm going to talk about it for three or four minutes for each bullet point. People read those quickly and then check out. I'll oftentimes try to have, like, turn each of those bullet points into a full-on slide. And maybe it's just a title and a fun picture or something like that. What this ends up doing is I kind of really inflate my slide deck. I'm going through maybe 80 or 100 slides in a 30-minute presentation. So it's multiple slides a minute. They move by really quickly. So I usually have either just an image or a header. I will usually start by just sketching it out with headers and then, where it makes sense, using an image. An image can be just for fun, or it can be something like a diagram where it is trying to illustrate a point. STEPHANIE: Yeah, I like that. I think talks with a lot of slides that are mostly just images or something that you can grasp in a few seconds are really engaging because you're keeping it moving, and you don't really let people get bored. And so you show a new slide, and they look at it, but then they are able to direct their attention back to what you're saying. JOËL: It's fun too with images because you can reuse them, and then they become a way to connect people back to a theme or let them know that you're making the same point again. A lot of talks, I will have a central theme that gets repeated. I'll often have a slide with some fun image with my key point on it. And then that slide will show up three or four times in my presentation oftentimes because each of the main points I'm trying to make kind of culminates at that same takeaway. And so for example, in the talk I gave at RubyConf Mini last fall, I had a slide about writing Ruby code being delightful. I think having some children being happy with just a big title being like, "Oh, delightful," or something like that. And after each of my examples where we went from code that was less good to something that was more idiomatic, Ruby that was really fun to work with, I would finish on that slide and be like, hey, our code is now delightful. And hopefully, that helped people with the takeaway of, like, we want to write delightful code. Ruby has tools to do that. And then, hopefully, they either remember the things they can do to get to that point or can look it up and find a talk online. STEPHANIE: Yeah, I watched that talk, and I really vividly remember that slide and the theme that you were trying to hone in on. So I thought it was pretty effective. I think this makes me realize speaking, I mean; speaking is obviously a skill but even the process of creating a talk in that particular medium is also a vast skill and can go...there are so many different styles and flavors. But I really think that what you said will get me thinking next time I'm writing my talk and how I can better incorporate that kind of engagement with the audience and making sure that the way I deliver the talk is just as thoughtful as the content itself. JOËL: Yeah, I've been putting a lot of thought into what makes a good talk and what elements are unique to my process, what elements can be useful to others because now I have to coach someone else on their process and say, "Hey, here's the thing that worked for me. Maybe this will be helpful for you." Or maybe it's just, "Have you tried this?" Or "I think audiences will be asking this question at this moment, what do you think of this?" So that's definitely been top of mind in a whole other dimension for me recently. How about you? What's new in your world? STEPHANIE: So before we started recording, I was heads down deep in the muck of trying to write some tests, some RSpec tests on my client project. And the domain for this client project is really big. There are a lot of models. And I was starting to go deep into the factory setups for our test fixtures. And it was hairy. And I was just going further and further down the rabbit hole to the point where I was skipping lunch. JOËL: Ooooh. STEPHANIE: Yeah, I was like, I couldn't pull myself away from it, and I kind of regret it a little bit. [laughs] And so I was just thinking about, like, how can I incorporate taking breaks a little bit more and feeling better about stepping away from the work when I'm really deep in it? You and I had this standing appointment to record [laughs] a podcast, so that was kind of the signal to me that it was time to try to set it aside. And I did end up taking the dog for a walk around the block beforehand to get some fresh air, but yeah, it was a little rough, I don't know. How do you deal with just being so deep in the code that you don't really want to resurface? JOËL: That's hard because sometimes I'm feeling productive, and I don't want to stop because I feel like I might not get back into the flow quite as easily. Sometimes it's just out of frustration. It's like, oh, I'm just so close to getting this bug done. If I get this one more test to pass, then I'll be good. And I keep doing one more thing. And the next thing I know, I have skipped lunch, and it's late in the afternoon. And it's just like; it's been a frustrating day. STEPHANIE: And you're cranky, yeah, yep. I know that feeling. JOËL: I've stopped being productive for the past hour. But I'll be like, one more thing, one more thing. STEPHANIE: I think I was in that place because I was starting to get deep into the internals of models completely unrelated to the test that I was writing, but that was just where the rabbit hole led me. And I think after this, I will go and ask in Slack for a pair because I think that would be really helpful right now. I've just reached the limits of what I know. And I'm almost positive that someone knows how to do this more efficiently than I do. So that was a bit of a signal to me, but it was very challenging untangling myself out of that headspace. JOËL: Have you ever played the video game Civilization? STEPHANIE: No, I haven't. JOËL: It's a turn-based historical strategy game. The running joke about it is that people get really pulled into it. And they're always just saying, "I'm going to play one more turn, and then I'm going to be done for the evening." And the next thing you know, it's 4:00 a.m. And I think that sometimes applies to fixing one more failure, just getting one more file in that chain of figuring out what the bug is in code. It's a very similar feeling. STEPHANIE: Yeah, I know exactly what you're talking about. MID-ROLL AD: Debugging errors can be a developer's worst nightmare...but it doesn't have to be. Airbrake is an award-winning error monitoring, performance, and deployment tracking tool created by developers for developers that can actually help cut your debugging time in half. So why do developers love Airbrake? It has all of the information that web developers need to monitor their application - including error management, performance insights, and deploy tracking! Airbrake's debugging tool catches all of your project errors, intelligently groups them, and points you to the issue in the code so you can quickly fix the bug before customers are impacted. In addition to stellar error monitoring, Airbrake's lightweight APM helps developers to track the performance and availability of their application through metrics like HTTP requests, response times, error occurrences, and user satisfaction. Finally, Airbrake Deploy Tracking helps developers track trends, fix bad deploys, and improve code quality. Since 2008, Airbrake has been a staple in the Ruby community and has grown to cover all major programming languages. Airbrake seamlessly integrates with your favorite apps to include modern features like single sign-on and SDK-based installation. From testing to production, Airbrake notifiers have your back. Your time is valuable, so why waste it combing through logs, waiting for user reports, or retrofitting other tools to monitor your application? You literally have nothing to lose. Head on over to airbrake.io/try/bikeshed to create your FREE developer account today! JOËL: So it can be really frustrating when you're kind of chasing down a bug because something's gone wrong, and now you're spending a whole afternoon figuring out where it is. Do you ever find yourself maybe acting preemptively to try to prevent those sorts of things from happening in the first place? So maybe putting in some sort of guards or error handling or something like that so that your future self won't have to spend that afternoon. STEPHANIE: That's a great point because the bug that I was facing just now was definitely something I think could have been avoided. It was a classic no method [laughs] on nil class error. And I am still unsure how that happened, and I hope to come back to it after this. But yeah, that certainly is a great topic to get into, error handling. I think it's been on my mind a little bit lately because I'm working on a full-stack feature that has user-facing errors and things we want to make sure that we communicate to the user so that they could hopefully do something about it or just contact customer support on this app. But there are also some API calls that are kicked off in the process of the user submitting the form, and those can lead to a bunch of different failures. And we may or may not have already discovered what those failures could be, and there may or may not have been designs created for those different failure states. And I feel like I haven't quite gotten a handle on how to deal with all of the possible errors that can happen when implementing a full-stack feature or a vertical slice. Yeah, that has tripped me up a lot lately. JOËL: I think my time working in Elm has really made me much more aware of the different ways that things can fail just because Elm's type system is very robust. It's very complete. And so it will point out to you every potential place that could have a failure and ask you to handle it because it doesn't want to get to a point where it doesn't know what to do and there's a runtime error for something like no method or something like that. So if you've got a potential nullable value and you're trying to say, okay, take this and render it, the compiler will say, wait a minute, you did not handle the null case. Give me something to do with the null case, or I refuse to compile. And now you've got to handle that. If there's something that might feel like an HTTP request, again, the compiler would be like, well, but what about the failure case? You didn't tell me what to do on the failure case. This is an incomplete piece of code. I refuse to compile that. So I think I've built now a little bit of anticipation because I know the compiler is going to tell me to do this. Now even when I write code that's not compiled like Ruby, my brain compiler is still like, oh, there's a nullable value here. You didn't check the null case. What are you going to do about that? STEPHANIE: Yeah, that's a great point. I think the more experience I gain, the more possible errors I see in the world or out in the wild. When I think about developing on the web, you know, you mentioned HTTP requests, but also, if we fail to connect to the database or a job fails to enqueue, there are just so many places where things can go wrong. And it's almost like the more I learn about all those possible failures, the more anxious I am [laughs] to make sure that I've covered everything though I think there is some amount of just that being impossible. And I'm particularly interested in figuring out what is enough because one thing that really I find quite painful is when you don't think through things enough and you just cross your fingers and hope it works and you ship it, and then your team is dealing with a lot of bugs or a lot of noisy error monitoring notifications afterwards. And so that's kind of what I'm trying to adjust for, I think. JOËL: I think there's like two general classes of approach you can use to deal with that; one is to try to prevent errors altogether, and there's a variety of tools you could use for that. I'm thinking of either something like a type system or maybe test-driven development or even some sort of analysis tool. That could be diagramming, that could be decision tables, something like that. All those, I think, fall under better understanding of the edges of your system. Whereas sometimes you want to do the opposite and sort of really lean into, okay, errors will happen. How do we recover from them? How do we make them easy to diagnose in the future? STEPHANIE: Yeah, that second bit is really interesting to me because I've started to try to think about the errors and who we want to notify about the errors. And so I feel like there are a few different categories of errors where if it's a validation error and it's something that the user can fix, you know, that we want to make sure to surface and tell them how they can fix it. If it's like a programming error, there's no value in showing that to the user. And I'm sure that we've all seen a website that responded with a 500, but then we actually saw the error message itself, and we're like, ooh, this is kind of weird [laughs] to be seeing this. And so realizing, okay, that's not valuable to the user. But what should I be doing with it instead? And maybe that is hooking it up to whatever error monitoring service you use to make sure someone is alerted. Or, I don't know, even in the third case, like, what should a customer support team be notified about? And that kind of sits in between not quite a user-facing error but also not a bug, and that's a different category. JOËL: So, something that is not necessarily a problem in the code, but you might want somebody in the company to know about and be notified about. STEPHANIE: Yeah, exactly. Maybe not something that is so urgent that it needs to be flagged in real-time but goes somewhere, and someone will check on it at some point. [laughs] So you were mentioning that you now have a better sense of what could go wrong. How much time do you spend writing code to cover all of those different possibilities? JOËL: Hmm, I don't know that I've ever put the time to quantify it. I would say a decent amount because you've got to think about...sometimes they're not even things that can go wrong per se. But they're off that very simple, linear happy path that you're thinking of. So you might think even for rendering some kind of view, and you've got some search results you're trying to display. Have you considered an empty state? Is there a difference between initially loading the page or have not performed a search yet, and search but did not find any results? Those are things that are not necessarily errors, but they're not things you're thinking in mind when you're just writing that first happy path of, like, oh, load page, show results. I assume there's always a result set. And so those are things that are important for the user experience that you need to have, but that are kind of edge cases that you have to add in afterwards, or you have to think about. And so I think that, for me, tends to fall under a similar category as okay; what if an error happened? Especially when you're dealing with kind of a full-stack situation where on the front end maybe you're making a result to a back end to pull down...let's say you're making a search and the back end is doing the actual search. You send up a query. Now you get back a failure. Is that the same thing as getting no results back? Like, a success with no results, versus an error code, versus not making a query yet. So you've got like four or five states you've got to think about on the front end to display and how you're going to handle those. So I think thinking about those upfront is often really helpful. STEPHANIE: As you were talking about that, I suppose I asked the question because I have experienced when those things are not thought about upfront, and then you discover them as you're implementing. And how much time do you use to kind of go into a little detouring trying to make sure that you have all of the edge cases covered, and at what point do you stop? Because you're like, I've covered what I can. And this ticket was supposed to only be three points [laughs] or whatever, you know. JOËL: Yeah. And how do you keep a feature from ballooning when there are all these edge cases? STEPHANIE: Yeah, exactly. It's a balance. JOËL: Are there any techniques that you like to do when you...so you pick up a ticket that looks easy, but that might have a lot of these hidden edge cases in it. Are there techniques you like to use that might help you figure out those edge cases and maybe give you some follow-up questions that you might reach out to the product person to clarify? Or maybe it's mostly intuition and experience as a developer that you kind of figure out that, oh, these are the things we need to ask about. It's like, have you thought about an error state? STEPHANIE: Yeah, that's a good question. In general, I'm a little suspicious of any ticket that doesn't include some kind of acceptance criteria about the unhappy path. And I certainly think it's a lot easier once you are embedded into this domain, and you have that expertise, and you are able to see the possible issues you'll run into. I do think that I like to do a little bit of coding just to kind of explore the space, and then that does give me more insight into how I might be able to follow up on the ticket. So you mentioned techniques. Especially if they're written as user stories, I don't think they necessarily incorporate the flow or the procedure of how things are kicked off. And so when you're thinking about implementing it, you're like, oh, this actually needs to happen in the background, or this should be synchronous or not. And those are a lot of error states that I find are missing when I pick up a ticket. And I think it also depends on which way you want to implement it what implementation is viable. And then maybe you bring it to a product person, and they are actually like, "No, we don't want it to work like that." And then you have to kind of rethink things a little bit. But yeah, certainly, the process of taking a user story and then doing an initial think-through of what approach you want to take definitely surfaces some potential unhappy paths. JOËL: It's almost like prototyping it in your mind. STEPHANIE: Yeah, I think so. I think it also depends a little bit on the team because if the engineer wrote the ticket, then there likely has been some thought about unhappy paths. But on other teams that I've been on when implementation is up to the person who picked it up rather than kind of spelled out for you by someone else who did that thinking, that's definitely an opportunity to pause, I think, and document which way you might want to go so that you can make sure that you account for the possible things that could go wrong that likely the user story didn't cover. JOËL: Sometimes there are some edge cases or failure states that are just sort of built into the problem that you're solving. If you're having to make a background request, there's always a chance that that might fail because the network is not trustworthy. Sometimes though, those things just kind of come out of our implementation, the fact that we implemented it in a particular way. And that's not something that you'd expect a product person to have to think about. That's more on us as developers to be like, oh yeah, well, I'm indexing into a hash and didn't think to check is a nested hash even present? Maybe that key isn't there. And now I've got a weird nil error, an undefined method. That's kind of on us rather than on, like, oh, a specific kind of thing that we can think about upfront. STEPHANIE: Yeah, that's fair. And I think that is just an important part of the development process. Though you make a good point because I think that just kind of speaks to all of the different layers of things that can go wrong [laughs] and figuring out which ones are specific to your role as developer to account for, and then which are ones that you need to bring in or pull in a designer to chat about. It can be a little overwhelming. I'm overwhelmed just thinking about it. [laughter] JOËL: Yeah, errors are not a sort of monolithic class of things. They can't be an afterthought. But they're also not just a thing where it's like, oh yeah, do the error handling, and then you're good. We kind of lump a lot of things under the concept of errors, even if they might all eventually manifest as some kind of exception. I guess a true solution is just one giant top-level rescue nil. STEPHANIE: [laughs] Very funny. JOËL: So we've talked about a few different dimensions of errors where they might be sort of user-visible or not, or something that's more implementation-based versus inherent to the problem. One thing that we haven't looked at is the dimension of errors that might be recoverable versus not. Have you ever built a system where you had errors that could be recovered from and didn't crash the program? STEPHANIE: Ooh, yes. That makes me think about retrying and especially what you're saying if things are happening in the background. Maybe there is an ephemeral error where the network timed out or something. But if it is given another shot, it might succeed on the second go. And I think there's a whole process of thinking about what happens when a process has to be retried and if there were any side effects that you didn't want to have committed the first time around, you know, but then something else that was supposed to happen and when the process happens again, things are very broken. So making sure that you are keeping things idempotent so that by undoing it again, there are not any unforeseen issues. JOËL: I heard you say that word commit here, and that's kind of a keyword to my mind. I immediately think database transactions. Is that the sense that you're thinking about this term here? Or does it have another meaning for you in this context? STEPHANIE: Yeah. I do think I used that word specifically because when I've run into this in the past, it has been around making database changes. I'm trying to think if there is another way that this might show up. I think even in something like sending an email, too, though it is a bit lower stakes. I've certainly, as a user, experienced when that goes wrong and just been [laughs] flooded with emails and being like, wow, this is annoying. And that's, I think, something valid to consider as well. JOËL: Yeah. You don't want that email job to be a thing that gets retried and just keeps failing because there's a nil error after the email gets sent. And so we just re-enqueue it, re-enqueue it, re-enqueue it, and the person ends up receiving 500 emails. STEPHANIE: What about you? Any thoughts about recoverable errors? JOËL: Yeah. I think really common for me is thinking about that in the context of a background job because those are things that I think are specifically designed to be retried if they fail; at least, a lot of job enqueuing systems assume that. When we write them, we don't always take that into account, but that's the system that we're working in. So that can be something as simple as marking somewhere that you have sent that email so that you don't resend it if that job ever re-executes. I think that goes to your point about idempotency earlier that you often want to write code that can get executed multiple times but doesn't necessarily do the action multiple times. It will do it at most once. And that's probably an interesting distinction to have is knowing what elements of your code need to execute at most once, versus as many times as the code is called, versus things that might get tried and then rolled back like a database transaction. And so then that will...I guess you could say it's at most once because you're writing it but unwriting it. But that plays out a little bit differently than something like an email where you can't undo sending an email outside of Gmail. STEPHANIE: Yeah, I love that undo button. [laughs] JOËL: You need some other mechanisms for that. STEPHANIE: Yeah. As you were talking about that, I was also thinking about the idea of failing gracefully, which I think also ties into the idea of recoverable. So this is not a development-specific example. But the idea of an escalator no longer working well; at least you can use it as stairs. So that doesn't mean that everything is totally broken and people are unable to get from one floor to another. So maybe if there is a network request that's touching data and that fails, you can at least fall back on something that's cached. That mindset, I think, really is important to think about at all the different levels we are talking about. JOËL: Yeah, or hopefully, even maybe some amount of graceful degradation. On a front-end app, you might not want to just crash the whole thing if one background request failed. So you can try again. You can be told, okay, try again in so much time. Maybe we automatically retry to make that same request with some sort of exponential backoff strategy. Or maybe we say, "Look, search is down for now. Here's a link if you want to go check a status page. Until then, other parts of the site are still working." I feel like we're getting back into what makes great product design and how great product designers have to make failure conditions. It has to be at the forefront of the thinking that comes to designing that product. STEPHANIE: Yeah, that's a good point. I think my initial feelings of being overwhelmed and stressed about dealing with errors may be because a lot of it falls on the developer if those things aren't accounted for. And we spoke a little bit earlier about, okay, what is within our realm or domain of actually being responsible for, and what can we loop in others for help with? JOËL: So we've been talking a lot about different ways of preventing errors, different ways of recovering, generally trying to make the whole experience really smooth. A slightly different philosophy around errors is rather than preventing them early is to fail early, like, fail early and loudly. And maybe you recover, maybe you don't. That depends on the context. But instead of putting so much effort into preventing errors upfront, it's better to just crash a lot or to fail loudly and deal with the consequences, or have a strategy for dealing with failure because failure is inevitable. How do you feel about that philosophy? STEPHANIE: Oh, I think it has a time and a place. One example I'm thinking of is if you don't want your application to be deployed if some configuration is not exactly how it needs to be for the app to run effectively. And so there is a matter of, like, okay, I really want to make sure that the DevOps team or the development team knows that something is very wrong because if this were to be deployed, the app would be unusable. And so that's an example to me of failing loudly but, ideally, not letting it affect end users because they're still using [laughs] the site on a different version. [laughs] JOËL: Right. I guess the classic example of that is for a Rails app, doing a Hash#fetch() on the environment to load up your environment variables instead of using the square bracket syntax so that as the app is booting and executing those initializers, it will crash if it encounters one of those and then fail to deploy if you're doing a deploy via something like Heroku. I've even sometimes when I'm adding environment variables, purposefully had them loaded in an initializer rather than maybe like in a class later on, specifically so that it would crash the app and prevent deployment if that environment variable was not set. STEPHANIE: Yeah, that's what I was thinking too, environment variables. Though I think even with that kind of mindset, you're either just delegating that responsibility to someone else down the line to either figure out how to accommodate or account for in a graceful manner. Or you are creating an environment where everyone is very stressed out [laughs] and having to fight fires. So I think it also requires a little bit of thought and isn't necessarily a strategy to just completely embody. [laughs] JOËL: I've noticed that bugs and errors often accumulate at the boundaries of systems or even subsystems or modules within a program. Maybe the place to apply the strategy of failing early and loudly is particularly valuable at those boundaries. But internally, within a subsystem or a module, maybe it's nicer to use other strategies for error handling. Does that sound like maybe a useful distinction to you? STEPHANIE: Yeah, I think subsystems was the keyword to me there because you don't want it to be such a catastrophe that it affects the usability of the app entirely. But that does still require some systems in place, I think, to respond to when that thing is failing loudly. JOËL: I think an example that came to mind for me is like you were mentioning earlier, a full-stack application. And if you've got the back end that's providing an API and something is wrong, I don't want that API to give me back garbage data and try to pretend that everything's okay. Let that API give me back some kind of error code. And I in the front end, I already know that the network is inherently unreliable. I'm planning to handle errors at that point. So it's fine for the API back end to fail loudly in this case. In fact, I think that's the optimal solution. STEPHANIE: Yeah, I think that's true because ideally, that error clues you into what kind of thing failed, and then maybe you can use that information more meaningfully than trying to guess at what happened with this bad data and then having to define some kind of error message in your app when ideally someone else who had more knowledge about it could have told you what went wrong. JOËL: And I guess the problem with not failing loudly or with an explicit failure is that if you try to just pass on some sort of value that will pretend to be like what you initially asked for, whoever's consuming that doesn't know that something went wrong. So then you use this garbage data, and you do some things and pass it along to the next person. And eventually, it may cause a failure three or four steps down the line. And now, trying to trace that, like, why did this fail? And it's not because something was wrong in Module D, or C, or B. It all comes back to oh, A had a problem but didn't crash or give us an error. It tried to pass its sort of best guess, like, this is probably okay. And then it just kind of moved all the way down the line. STEPHANIE: I'm imagining external API developers everywhere just nodding their heads in agreement. [laughs] JOËL: I've fought this on a local level as well. I was working on some kind of code for a JavaScript date picker plugin, and this was back in the jQuery days. It was some kind of...it was not a date picker. I think it was a typeahead drop-down thing. In some situations, I forget exactly how it would happen, but the input from there might be empty, but then that would get converted into an undefined value, which then JavaScript would convert to the string undefined, which would then get passed to something else that if it saw a string, it thought that was the thing that the user typed, and they would pass it through. And I think maybe in the end, I was looking at a crash ten functions away in the front-end code that had to deal with the input from this typeahead and being like, why am I getting these undefined? Or maybe it was a string NaN or something like that. Like, why am I dealing with these weird strings that should never have come out of this? And it turned out it was just kind of an edge case. It wasn't addressed in this component further on, and then it was kind of leaking strings that everybody else thought was sensible up until three or four jumps further down the stack. STEPHANIE: Yeah, that's a great point. I think it does go back to the idea of there being preventable errors. And then there are things that are truly not preventable because we live in a physical world [laughs] where computers talk to each other over the wire. And that distinction is, you know, perhaps the first being avoidable errors by writing resilient code. And the second being like, okay, in reality, there will be things that go wrong, and this is what we really have to watch out for. On that note, shall we wrap up? JOËL: Let's wrap up. [laughs] STEPHANIE: Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeee!!!!!! ANNOUNCER: This podcast is brought to you by thoughtbot, your expert strategy, design, development, and product management partner. We bring digital products from idea to success and teach you how because we care. Learn more at thoughtbot.com.

The Bike Shed
372: Onboarding (Well!) Onto a Project

The Bike Shed

Play Episode Listen Later Feb 21, 2023 37:37


Stephanie raves about more software development-related zines by Julia Evans. Joël has been thinking about the mechanics of rolling dice. Stephanie also started on a new client project that Joël has already been working on for many months. They talk about onboarding. This episode is brought to you by Airbrake (https://airbrake.io/?utm_campaign=Q3_2022%3A%20Bike%20Shed%20Podcast%20Ad&utm_source=Bike%20Shed&utm_medium=website). Visit Frictionless error monitoring and performance insight for your app stack. Julia Evan's Wizard Zines (https://wizardzines.com/) Why's Poignant Guide To Ruby (http://poignant.guide/) Learn You A Haskell For Great Good (http://www.learnyouahaskell.com/) Mazes for Programmers (http://mazesforprogrammers.com/) thoughtbot dotfiles (https://github.com/thoughtbot/dotfiles) rcm (https://github.com/thoughtbot/rcm) Transcript: AD: thoughtbot is thrilled to announce our own incubator launching this year. If you are a non-technical founding team with a business idea that involves a web or mobile app, we encourage you to apply for our eight-week program. We'll help you move forward with confidence in your team, your product vision, and a roadmap for getting you there. Learn more and apply at tbot.io/incubator. JOËL: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Joël Quenneville. STEPHANIE: And I'm Stephanie Minn. And together, we're here to share a bit of what we've learned along the way. JOËL: So, Stephanie, what's new in your world? STEPHANIE: So I got a very exciting package in the mail the other day that I wanted to share with you. So I think I've mentioned her on the pod before, but I got a package of software development-related zines by Julia Evans, and I'm going to share a few of the titles that I got. So I picked up, "Oh shit, git!" [laughs] Can I swear on this podcast? I don't know. I guess we're going to find out. Or maybe we can just make the executive decision that it's fine. [laughs] I also got "Hell Yes! CSS!", "The Pocket Guide to Debugging," which I think I mentioned previously. I had seen the PDF version before, but now I have this cute, little, I don't know, six-inch book that I can carry around for all of my debugging needs. Who knows? Maybe I'll be out in the world and just need to pull it out [laughs] and debug something while I'm on the train; who's to say? And then I also picked up "HTTP: Learn Your Browser's Language!" So I'm really excited to have these little illustrated digest-sized resources. I think they'll look really cute on my shelf next to my more intense hardcore technical books like "Design Patterns" and "Practical Object-Oriented Design in Ruby" or whatever. I'm really excited about the more creative endeavors people have done with creating educational resources about software development. In fact, I think last time when we talked about creativity and creative expression, we totally missed the world of side projects. And I've really just enjoyed when people illustrate things and make stuff a lot more accessible to a wider audience than a traditional textbook or more text-based heavy resources. JOËL: I love when people go for a bit more of the playful or quirky when dealing with technical topics. And this is a great example. I love Julia Evans' work. But I'm also reminded of things like "Why's (poignant) Guide to Ruby," "Learn You a Haskell for Great Good!" or even...I forget the title of it. But there's a book by...I think it's Jamis Buck on mazes. And it's told in this sort of quirky style in a narrative. But it's all about maze-solving algorithms but told through the eyes of characters who are wandering through a maze, and it's just delightful. STEPHANIE: Aww, that's so cute. I love that. I also just had the thought that these things would make great gifts for a fledgling developer or a developer in your life who, if you don't want to get them something super specialized or technical or whatever. There are so many, like you said, quirky and fun things out there that I'm sure they'll appreciate. So, Joël, what's new in your world? JOËL: I play D&D regularly with some colleagues at thoughtbot. And recently, I got to thinking about the mechanics of rolling dice. Specifically, what dice can be rolled together? Like, can I roll multiple dice at the same time? And which one do you have to wait for the outcome of a previous roll before it makes sense to roll it? That was really interesting to me because I think that connects to a lot of other things that we do in software, where sometimes some things are independent. You can do them at the same time. And then, other times, you have to wait for the outcome of the first thing before you can even start doing the second thing. So I think, in many ways, it's a great metaphor for the difference between parallel versus series operations. STEPHANIE: I think it's very funny that you found a way to connect D&D to software development. I'm just imagining you rolling your die and then while you're doing that, having some revelation like the math lady meme or whatever, just thinking about, whoa, if this outcome happens, then [laughs] what happens? I have not joined in on our company's D&D campaign, but I do like that y'all post little updates about the story in a public space for the whole company to check out. So sometimes I've been searching for some message in our company's knowledge base, and I have stumbled upon a post about the campaign so far and what happened in last night's session, you know, how all the adventurers fought the big bird, [laughs] and it is very delightful to me. JOËL: It's a really fun way, I think to be creative. I think I enjoy the role-playing side of it a little bit more than just the mechanics of rolling dice, even though the thing I was excited to share today is rolling dice is fun. It is kind of like doing improv, where you're trying to figure out what would your character do and how do they respond to what other people say? It's fun, but it's hard. STEPHANIE: One burning question I have is, does anyone do voices for their characters? JOËL: Absolutely. Aji Slater, who was on a previous episode of this podcast, is part of this campaign, and their character has some really fun voices. STEPHANIE: That's awesome. I'm really interested in joining as a guest or something. But yeah, the improv aspect of it kind of freaks me out. I bet it's a really welcoming group. And if other people are getting into it, then I can get into it too. JOËL: Yeah, this group is very, very low-key. Most people playing, I think, are fairly new to the game. So it's very friendly, very kind of tolerant of, oh, you didn't know this rule existed, that's totally fine. We'll make it work, things like that. STEPHANIE: Nice. So another recent development in my world is that I started a new client project, actually the same client that you've been working on for many months, Joël. JOËL: Yes, the same client but different teams within the client. So we don't get to necessarily interact with each other day to day. But it is interesting that now we get to share knowledge about how this application works with each other. STEPHANIE: Yeah, yeah. And I don't think we've gotten a chance to work together even in the same world like this before. So that's kind of exciting. JOËL: How has the onboarding been for you? STEPHANIE: So, one onboarding development that was surprisingly easy and felt good was setting up a new laptop. So the client company shipped a laptop to me to use for all of their work. And I had to set up just the laptop from scratch, so I could develop on it. And I was able to do that pretty painlessly with the help of the dotfiles that I had previously put together and all of the configurations that I had exported and uploaded to like a cloud drive. And so I was able to have that up and running within a day with all of my favorite keyboard shortcuts, applications, all my little preferences, and that felt really good. So I'm going to pat myself on the back [laughs] for past Stephanie's efforts in making current Stephanie's life easier. JOËL: I'm curious, do you use thoughtbot's dotfiles as the base for your development environment, or do you use something custom? STEPHANIE: I have my own personal dotfiles that I have in a GitHub repo. But I think I did, at one point, go through thoughtbot's dotfiles for inspiration. I found that it has just a lot of extra stuff that I don't really need, but I do like that it's out there. So if any folks want a place to start with having a laptop setup configuration, you should definitely check that out. And we can link that in the show notes. JOËL: I really like the tool rcm, which is also by thoughtbot that allows you to have a modular system of dotfiles that you can pull from a few different sources and combine together. STEPHANIE: Oh, that's neat. I hadn't known about that one. That's cool. JOËL: It's a suite of command-line tools that allows you to pull probably from a git repo. And it might be several, and then trying to pull them all to the right place on your machine to be executable. So, in my case, I have the thoughtbot dotfiles and then also some personal ones. And it just kind of merges them together based on some rules and creates all the dotfiles in my home directory for that. STEPHANIE: Nice. I think the one thing that I do need to keep up on is pushing updates to the dotfiles when I make changes locally because I did have to pull in a few things that I had adjusted or made tweaks to that didn't make it to the source that I was pulling from on this new machine. This is actually my fifth MacBook that I own [laughs] just from remnants of jobs and clients' past. And one day...I keep telling myself that I'll have to return one of the older ones that I'm not using anymore, but as of now, I am an owner of five computers. [laughs] JOËL: Just start mining Bitcoin on the idle ones. STEPHANIE: Oh. [laughs] That's genius. I guess that's definitely a better use than them just sitting in my drawers. JOËL: I guess you're paying for power, and that's kind of the whole point, so... STEPHANIE: That's fair. JOËL: What are some things that you like to do when you onboard onto a new project? STEPHANIE: So, aside from my laptop adventures, when I joined this new project, I had a few things in mind that I wanted to achieve during this onboarding process. One of the things I think I want to get better at is understanding the business when I'm onboarding onto a new client. I think this is an area that previously I hadn't really focused on, but I'm now understanding is actually really important to being set up for success on a team. And so, as consultants, we're dropped into a client project oftentimes when things are already moving. And they kind of clearly have some things that they were hoping we could help with. But I am hoping to also use this time to just take a bit of a step back and ask questions about, like, what is the product? And what are its core features? And who are its users? And also, what's the direction of the business? Can I get some more context on how things are right now? We're so frequently brought in and being like, okay, like, you're going to work on this project but without the context of is the business scaling right now, or what are its struggles? We aren't quite able to make as informed decisions as we could if we had been at the company for longer and had just seen things change and had more of a feel of why we're doing what we're doing. JOËL: I love that you're asking all those questions upfront. I feel like coming in onto a new project, and that can be as a consultant, or it could be just starting a new job, is the perfect time to just be asking all of those questions. And people, I think, appreciate when we ask those questions. Sometimes I think as consultants; we can sometimes be afraid that, oh, if we're asking these sorts of basic questions, people might think less of us. But I think the opposite happens where because we're asking those foundational questions about the business model, about the future of the product, about how the technical architecture works, people really appreciate that we're asking those foundational questions where other people might not. So it actually helps build credibility rather than hurting credibility. STEPHANIE: Yeah, and I think they are really important in making the right technical decision, too, because it can help inform where you spend your time refactoring or evaluating whether this shortcut is worth it to meet this deadline or if it's not because of the bigger picture and where things are headed. If anything, I've learned that being a developer really isn't just about being in the code but having as much information as possible so that there is less ambiguity and you have more clarity to make the right choices when you do have to write the code. Another key aspect that I have become a lot more observational about, I think, is understanding the team that I'm joining, especially what their process is, how they communicate. One thing that's kind of funny about seeing a lot of different companies and how they work as consultants is they might claim to use agile, but in reality, it is a little bit different than that. And you can have that perspective as an outsider. Things like pointing an estimation is kind of all over the place in the industry. So I really like to make sure I fully understand how the team does that and what points means to them. I think another thing that I want to do during my onboarding time this week and as I'm getting to know developers on the client side is learning about the pain points that they're feeling. And, yeah, just getting more of a feel about what's top of mind for them and where is a good space to invest my time and my energy. Lastly, some more basic stuff is communication. Another thing about being a contractor that's challenging is that we don't normally get the full onboarding experience that full-time hires do. And so we may or may not have an onboarding mentor or a buddy and finding out, okay, who is the right person that I should be asking questions to? Or where's the right space for that? When you join new teams, are there any other things that you like to take into consideration? JOËL: I like that you talked about understanding the team's process. One thing that I often like to do pretty early on is make some kind of small code change but then have it go through the full process of coding on my machine to deploy it in production. And so just find some small change in the code that needs to be done, and maybe it's an easy bug fix or something. But just so I can walk through all the steps and find out what the team's process is. What are some sort of weird things that this team does that other people might not that I need to know about? Where does review happen? Is there a staging environment, unexpected ways which my change might get rejected? Things like that. So walking through the entire, I guess you could say software development lifecycle, kind of speedrunning is, I think, a really valuable exercise to do really early on a new project. STEPHANIE: Yeah, that's a great point. Like I mentioned, I think that looks so different for every team. And I'm now learning about new tools and SaaS products that I have never seen before. And even though I have an understanding of the software development lifecycle in general, just learning those quirks is very valuable so that you can be a contributor as soon as possible. JOËL: I like to contribute on day one, if possible, so kind of in order of...I don't want to say order of priority. But the order of things that I often do on a new project is one, clone the repo, try to run the setup script, or manually step through instructions in the README. Depending on the repo, that might be 10 minutes. That might be all of my first day. Number two, try to run the test suite. STEPHANIE: Yes. JOËL: Number three is figure out what went wrong for me in step one or two, make a fix for it, commit it, and open up a PR for it, and that's my contribution. If I can do those three things on day one, I feel like that is a solid first day. STEPHANIE: That's great. I love that. What can you do to help improve this process and make it just a little bit better for someone else? I think another good first-day task might be automating a part of that process that is currently manual and kind of annoying. MID-ROLL AD: Debugging errors can be a developer's worst nightmare...but it doesn't have to be. Airbrake is an award-winning error monitoring, performance, and deployment tracking tool created by developers for developers that can actually help cut your debugging time in half. So why do developers love Airbrake? It has all of the information that web developers need to monitor their application - including error management, performance insights, and deploy tracking! Airbrake's debugging tool catches all of your project errors, intelligently groups them, and points you to the issue in the code so you can quickly fix the bug before customers are impacted. In addition to stellar error monitoring, Airbrake's lightweight APM helps developers to track the performance and availability of their application through metrics like HTTP requests, response times, error occurrences, and user satisfaction. Finally, Airbrake Deploy Tracking helps developers track trends, fix bad deploys, and improve code quality. Since 2008, Airbrake has been a staple in the Ruby community and has grown to cover all major programming languages. Airbrake seamlessly integrates with your favorite apps to include modern features like single sign-on and SDK-based installation. From testing to production, Airbrake notifiers have your back. Your time is valuable, so why waste it combing through logs, waiting for user reports, or retrofitting other tools to monitor your application? You literally have nothing to lose. Head on over to airbrake.io/try/bikeshed to create your FREE developer account today! STEPHANIE: So once you've cloned the repo and you're poking around the codebase, what are some things that you notice when you're looking at the code? JOËL: Ooh, that's always fun. In a Rails application, there are a few files I almost always open first in a new project just to get a feel for it. Number one is the routes file. What does that look like? Is it huge? Is it small? Are there a lot of non-standard routes in there, not just standard RESTful resources? That's going to tell me a lot about how things are structured. I can probably even get a sense of what controllers are large, what controllers have 20 non-RESTful actions in them just by looking at the routing file. The other place I like to look at is the user model. Generally, that just collects so many methods. And so I can also often get a feel about the app just by looking at that. And then from there, it's pulling on connections and trying to say, okay, well, what seems to be the core model of this app that everything coalesces around? And maybe for an e-commerce app, it's some kind of product, or maybe for an insurance product, it might be some kind of policy object. And so you find that, and then you find all of the core business logic around there. And that can often give you a really good picture of what the app is like. STEPHANIE: Yeah, a few other things I would add to that list of things to check out is the Gemfile. I like to look at that to see what gems are familiar to me. Do they have authentication, common authentication gems that I've used before? Or is there a lot of stuff that's new to me? And it also kind of tells you, are they more likely to reach for a library or try to build something themselves? I liked that you mentioned that you try to run the test suite early on. I think test coverage is a good place to investigate as well if they have any metrics, you know, that also tells you that it is or isn't something they value. And then seeing like, okay, what parts are well-tested and what parts are a little less tested? I'm really glad that you pointed out how much information you can glean about controllers because then, once you're poking around in there, that can tell you a lot about where are the scary parts of the app? I've found that to be really interesting. You know, sometimes you can just open up a file and be like, whoa, [laughs] and have kind of a gut reaction. Other times, you might pick it up from other developers, and you might start hearing about areas of the app that they are a little nervous to touch. JOËL: I definitely connect with that. I feel like many products have a particular file that is kind of scary and that people don't want to touch. And sometimes, people will tell you upfront, sometimes, you just discover it yourself. And I've been on projects where it's like, oh no, we have a ticket that's come up. It's fairly straightforward, except we know whoever picks it up is going to have to touch the scary file, and I'm not it. STEPHANIE: Yeah, absolutely. JOËL: I'm curious if you run any kind of automated tooling to try to understand a little bit more about the code. So I'm thinking things like maybe Flog or Flay or some of those tools to get a feel for maybe what are the hotspots in the application, anything like that that you like to look for? STEPHANIE: That's a great point. I think the only times I have invested energy into doing that has been more when I'm doing a code audit for a client, which, in some cases, is a separate service that clients can pay consultants for. But I can see the value of doing it when you're joining a team for the first time. JOËL: In a sense, I almost feel like we do a kind of abbreviated code audit for ourselves as part of onboarding. STEPHANIE: That's fair. I wonder if you can use those tools and scope it in a way to the particular team or areas in the codebase that you know that you'll be working on. JOËL: You mentioned the Gemfile earlier. And one thing that maybe seems super obvious is checking version numbers for things like Rails and Ruby because that will significantly impact how development is going to work. Is this a Rails 3 app, or is this a Rails 7 application? STEPHANIE: Yeah, yeah, that's a great point. I am glad you mentioned that because I think that's probably the very first thing [laughs] that I would do just to set my expectations around what I'm working with. JOËL: I feel like it's one of those things that's often just told to you when somebody helps you onboard. It's like, "Okay, you can clone the repo. It's over here. By the way, this is a Rails 3 app. We're kind of behind the times. Here are some weird things we've had to do to keep it alive. We have this other team. They're in this back room over there, slowly working on a Rails 4 upgrade. It's been in progress for four months, but we think we're pretty close. Can't wait for Rails 4." STEPHANIE: Oh God. [laughs] I think the alternative is a developer being like, "Oh yeah, we just upgraded to Rails 7," and they're all really excited and feeling really good about it, [laughs] as they should be, because I think that Rails upgrades are an important thing to stay on top of. And it is really great when you are working on a project that gets to be up to date there. JOËL: Yeah, Rails upgrades are interesting because I feel like when you're proactive about them, they're not that bad, especially more modern versions. I think Rails has gotten a lot better about making those upgrades smoother today than they were ten years ago. But when you're not up to date about them, when you've just kind of procrastinated on doing the updates, every month or year that you wait to do the update makes it so much harder to do that update when the time comes. Because now more gems have fallen out of date, more things have now been abandoned that you just can't use. A lot of community knowledge is just not around as much anymore. Because Rails 3...I forget when Rails 4 came out, probably about ten years ago. So people who remember how things were done idiomatically ten years ago, some of that knowledge has kind of passed on. It's not as prevalent as knowledge around Rails 6 or Rails 7 is. STEPHANIE: 100%. I think I heard someone at thoughtbot identify themselves as a post-Rails 5 generation developer. And I loved that because it really tells you a lot about just their experience. And it's kind of fun. I can imagine some kind of BuzzFeed quiz or something that's like, what Rails generation are you? But yeah, I've certainly seen pro-con lists about joining different projects, and a con might be the app is still on Rails 3. And then, if the app is on a very new version of Rails, that's usually in the pro column because folks are excited about getting to have all that good, new stuff. What do you look out for in terms of design patterns in a codebase? Is that something that kind of sets off your radar at all? JOËL: One thing that will definitely make me raise an eyebrow is heavy use of metaprogramming. I've been bitten by that a lot on projects. Some things are way too clever by half. So a lot of metaprogramming typically means it's going to be difficult to read and follow the flow of logic in the code. And also, there might be some unexpected bugs. Or I found once a memory leak that happened because of some weird metaprogramming. So that definitely makes me a little bit skeptical of part of the code. STEPHANIE: Yeah, that's fair. And it also just makes it hard to understand the domain when you have no idea where things go. And you have to just find out later when you are debugging and are in the middle of desperately trying to figure out how this app works. So I can see how that is a little suspicious. I think one thing that I am reevaluating for myself when I notice design patterns is trying to figure out, do I want to perpetuate them? Do I want to follow them? And in the past, I have been more likely to just follow an existing pattern in the codebase. But one thing that I'm hoping to do moving forward is to simply ask, how do decisions get made around patterns? Who gets to introduce them? Are they documented? What does that process look like? Do you have a conversation with the team about it? Just so that I have more tools in my toolbox, I think if I ever do find something that I feel really strongly about, that should be different than what I'm seeing in the codebase. So kind of expanding my skill set there. JOËL: I think that's a fantastic question to ask, and I've done this on previous projects. And sometimes, the answers are just absolutely illuminating. So you see a weird pattern, and you ask, like, "Oh, where does that come from? Why do we do that?" And some will say," Oh yeah, that was Bob back in, you know, 2017. He read an article and was really a fan of this thing, and he put it everywhere. Nobody else really understood the pattern, but we haven't really been able to change it. And he's no longer with the company, and now we just kind of...it's there." Or sometimes it's like, "Oh, great question because you see, we have this subtle business problem. And we've got to reconcile these two pieces of technology with also this expectation that our customers have. And so we came across this pattern, and we decided to use it." And it's these things where just looking at the code with no context, you're like, that's weird. Why would you want to do that? And then, when you understand the underlying problem, it makes so much sense. It's like, okay, I don't love this pattern, but it's the correct solution here, and I fully support having that here. It's a tricky problem at the intersection of technological problems and business problems, and this was the best way we could solve it. I'm not always super happy, but it is the right choice. STEPHANIE: Yeah, I've heard someone describe that as code archaeology in a way that all codebases have a story to tell about how they got to the current state that they're in. And I have certainly struggled with this but trying to approach joining a new team and working on a new codebase, especially if it's legacy code, from a place of curiosity rather than being combative about it. And just going through the git commits or just simply asking members of the team, like, "Hey, what's going on here?" and getting to hear some of those fun stories. JOËL: Yeah, most code exists for a reason. It's not just people writing things just because, particularly code that, you walk in as an outsider and think, oh, that's bad code or looks weird. It's usually for a reason. People aren't just purposefully writing this to trigger you two years down the road. It's also important...as a new person onboarding onto a project, people care about your perspective. As an outsider, oftentimes, it's really rich to bring in an outside perspective. But it's also not a great look to come in and just immediately be like, "Oh, we need to tear this thing down," or "This is so bad." It's important to build trust with the team. And as with so many things in life, seek to understand before running your mouth. STEPHANIE: Wow, how insightful, Joël. [laughs] Speaking of building trust, can we talk a little bit about different strategies we have for doing that? JOËL: Yeah. As a new person on the team, you really want to build a strong connection with the client and to build that trust because then you can be more effective in doing your job. You can bring more value to the client. What are some ways that you like to get that moving in a positive direction early on a new project? STEPHANIE: I think setting up channels of communication is really important, so, ideally, having a one-on-one with a manager or a team lead because that is a great place to make sure that the work you're doing is aligned with what they think you should be doing. So figuring out what their expectations are, like, what do you expect me to get done in my first week? And then what do you want me to be doing by the first month? That is important because we might think about all the things we would love to improve about this codebase or like influence on the team. But if that is not lined up with their views of what success looks like, then we're not quite delivering on the value that we [laughs] had hoped that we would. Another thing that I'm starting to notice a lot more, and we talked a little bit about this previously when we talked about the value of sustainability in web development, but learning what the team's values are and also what the organization's values are because that will really inform the behavior of folks on the team and the decisions that they make. So some values that come to mind are transparency, or collaboration, or growth, or speed. Like, if you find out those underlying foundational pillars, that can really help you orient yourself in your work and being like, okay, I know that this organization really focuses on these kinds of things, so I would like to try to make decisions that uphold or are in line with the things that are important to them. JOËL: I want to really second your comment about good communication. That is one of the most powerful things you can do to build credibility to build trust with another human being, and that can happen in a lot of ways. Like you're saying, some of it is setting up actual communication channels with a manager. Some of that can be the things we mentioned earlier, like asking questions about the architecture, trying to learn all about the product and the business. That can also be being active in that particular team's Slack channel. Sometimes new people come on to a team, and they're a little bit more timid, and they're just kind of not present. And so kind of coming in and...like, you don't want to take over the channel but being active in the channel, asking your questions in that channel, even just talking about your onboarding experience being like, "Hey, I'm running through...I got stuck on this thing. Here's the thing I did to get unstuck." People love seeing that. And it helps them to feel like you're actively participating from day one. STEPHANIE: Yes, that is a great transition to what I wanted to make sure to say at the end of this is that your onboarding experience matters. I know that when you're joining a new team, you might feel a lot of pressure to start contributing and make sure that you are providing value. But your onboarding experience should be inclusive, and you should advocate for your needs. Like, if you don't have access to credentials or there are just various blockers to your onboarding, that's a big deal, and it should not be a gatekeep-y process. Everyone wants you to be able to do your job, and so if you're running into those issues, it's definitely important to raise those concerns for yourself and also for anyone else who comes along the way. Also, everything is new, and will probably feel uncomfortable. If you're anything like me, I feel a lot of pressure to prove myself when I join a new team and start contributing left and right. But it's just important to remember that when all this stuff is new, feeling uncertain or feeling confused and just being in that beginner's mindset again can be uncomfortable, but that is totally normal. JOËL: I feel like something I sometimes do that ties all of these ideas together is when I'm encountering some new code or a new problem, to help myself understand it, I will diagram it. But oftentimes, it can be nice to share that diagram in the team's Slack channel and to say, "Hey, I'm new to the project, and I was exploring this area, and I kind of diagrammed it." Just talk a little bit about the thing that you're doing and maybe what you learned about it. People love that. Visuals are a really powerful tool. And you might be surprised that there might be some team members that have been on the project for a while who never really understood that part of the code. And so they will latch on to what you've shared and be like, "Oh, thank you, because now I finally have a feel for that part." Or maybe you didn't get it quite right, and somebody will follow up and say, "Hey, I love your diagram, but you have a misconception here. There's actually a different piece that connects here." And then you can have a conversation, and you just revealed a blind spot. And so I've found that that can be a really positive way to get started. STEPHANIE: Yeah, absolutely. Joël Quenneville, professional diagrammer. But even if you don't draw a diagram, putting your assumptions out into the world and how you understand things I think is really valuable because, yeah, it's like you are showing your learning path and also being open to receiving feedback if it's not quite right and, hopefully, spreading knowledge all around. So I love that. JOËL: This reminds me a little bit of the episode we had with Steve Polito about learning in public. And he was focused more on learning about Rails, and open source, and things like that. But there's a sense in which you can sort of learn the product or learn the codebase. And public means your team channel. So you can say, "Hey, I'm digging into this model, and here's how I understand the way things work. It's a bulleted list of three things." You might get some good comments on that. You might get other people who appreciate it. So kind of learning the internals of a product within the public confines of a team, I think, is a really good framework as well. STEPHANIE: Absolutely. JOËL: On that note, Shall we wrap up? STEPHANIE: Let's wrap up. Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeee!!!!!!!! ANNOUNCER: This podcast is brought to you by thoughtbot, your expert strategy, design, development, and product management partner. We bring digital products from idea to success and teach you how because we care. Learn more at thoughtbot.com.

The Bike Shed
370: Creative Expression in Software Development

The Bike Shed

Play Episode Listen Later Feb 7, 2023 38:52


Stephanie shares that she's been taking an intro to basket weaving class at a local art studio, and it's an interesting connection to computer science. Joël eats honeycomb live on air and shares a video that former Bike Shed host Steph Viccari found from Ian Anderson. It's a parody to the tune of "All I Want For Christmas Is You," but it's all about the Ruby 3.2 release. In this episode, Stephanie and Joël shift away from literature and lean into art. Writing code is technical work, but in many ways, it's also aesthetic work. It's a work of art. How do you feel about expressing yourself creatively through your code? This episode is brought to you by Airbrake (https://airbrake.io/?utm_campaign=Q3_2022%3A%20Bike%20Shed%20Podcast%20Ad&utm_source=Bike%20Shed&utm_medium=website). Visit Frictionless error monitoring and performance insight for your app stack. Weaving, Computing, and the Jacquard Loom (https://www.scienceandindustrymuseum.org.uk/objects-and-stories/jacquard-loom) Ian Anderson's Ruby Christmas song (https://www.instagram.com/reel/CmAxL_ZNMOa/?igshid=YmMyMTA2M2Y%3D) Dan McKinley's Boring Technology Club slides (https://boringtechnology.club/) Simple English Wikipedia (https://simple.wikipedia.org/wiki/Main_Page) Geepaw Hill's Twitter thread about levels of thinking (https://twitter.com/GeePawHill/status/1565389543628480518) Julia Evans's debugging puzzles (https://mysteries.wizardzines.com/) Tomorrow, and Tomorrow, and Tomorrow by Gabrielle Zevin (https://bookshop.org/p/books/tomorrow-and-tomorrow-and-tomorrow-gabrielle-zevin/17502475) Transcript: AD: thoughtbot is thrilled to announce our own incubator launching this year. If you are a non-technical founding team with a business idea that involves a web or mobile app, we encourage you to apply for our eight-week program. We'll help you move forward with confidence in your team, your product vision, and a roadmap for getting you there. Learn more and apply at tbot.io/incubator. JOËL: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Joël Quenneville. STEPHANIE: And I'm Stephanie Minn. And together, we're here to share a bit of what we've learned along the way. JOËL: So, Stephanie, what's new in your world? STEPHANIE: I'm really excited to share that I've been taking this intro to weaving class at a local art studio. I'm actually a few weeks in, and it's wrapping up soon. But one thing that I found really cool at the very first class was that the instructor mentioned that weaving was, in some ways, a predecessor or inspiration to modern computing. And he said that, and I got really excited because surely that meant that I would be good at this thing [laughs] and this craft, and then I promptly kind of forgot about it. But I was inspired the other night to look up this history to just learn more about weaving and its connection to computer science. And I learned that, in particular, the invention of something called the Jacquard loom really led to early computing machines because, basically, weaving involves threading horizontal and vertical fibers. And the way you do it if you thread the horizontal fiber, also called the weft, over or under the vertical fibers, called the warp, you get different patterns. And so with the Jacquard loom, this invention utilized punch cards as instructions for basically binary code, and that would tell the loom how to raise and lower those vertical threads, which would then lead to a beautiful pattern. And after that invention, this previously very laborious process became automated. And that also had a really big impact on the textile industry. And fabric became a lot more available at a much lower cost. So that was a really cool little history lesson for me. JOËL: That is really cool. So are you saying that punch cards, as we know them from early computing, were borrowed as a concept from the weaving industry? STEPHANIE: Yeah, that's at least what I've read. I can see now how complex weaving tapestries and patterns set the stage for more complex computations. And I don't know if I'm going to keep going down this weaving journey. I liked the intro class because it was very chill, and I got to use my hands. And I had a little bit of fun making, I don't know, like ten by 12-inch little tapestry. But yeah, I've definitely seen other more advanced weavers make really beautiful textiles and fiber arts. And it's really cool to see the application of that detail-oriented skill in different formats. JOËL: Are you going to try to make your own punch cards? STEPHANIE: That's an interesting evolution of this skill [laughs] for sure. I think what I really did like was the hands-on approach. And so the punch cards did make this process automated. But I personally enjoyed the switching of the threads and pulling them through and doing it with my hands instead of something that's kind of turned into automated machine work. Does that inspire you in some way? JOËL: I think sometimes it's interesting, right? As software people, we sort of have the two urges. We work in so much automation. When we see a process, we would love to try to automate it ourselves, even if it's been done before. So, oh, could I build a small, automatic mechanical loom using punch cards? That sounds like a fun automation challenge. At the same time, so much of my daily job is automation that sometimes it's nice to kind of remove automation entirely from the picture and, like you said, just work with your hands. STEPHANIE: That's a really interesting way to think about it. I do believe that people have different reactions to it, like you said, where they're like, "Wow, I can use my skills to do this really cool thing." On the other hand, you might also respond with, "Wow, I've done this automation code-writing work for eight hours. So now I really want to do something completely different." And I think that's the camp that I was in, at least when I first signed up for this class, just having space, like three hours a week, to sit and not look at a computer and deal with the physical realm. JOËL: So here's the other route that I think a lot of software people take, and that is, here's a fun mechanical process that can be automated. What if we simulated it virtually? So what if I create a program where you can sort of create your own punch card, like, decide where you want to punch the holes? And maybe these are just radio buttons or something or checkboxes in a grid on a webpage. And then, the program will output an SVG that is the thing that would have been woven if you'd used it in that pattern. And so now you can kind of play around with, like, huh, what if I punch here? What if I unpunch here? And you get all these patterns out, and you could just get to try it around. STEPHANIE: That's fascinating. I can't believe your brain went there. [laughter] But yeah, the idea that it's not actually about the pattern itself but the holes that you make, that part being the creative process and then what comes out of it then being a bit of a surprise or just something organic that's a really interesting take too. JOËL: Something that I find is really fun about software and things created from software is this sort of really short feedback loop in terms of trial and error. So if you were actually having a weaving machine and you made a physical punch card, and then you try something, and you realize it's not quite right, the machine weaved something you didn't quite like, now you've got to set it up again. You probably have to start from scratch with a new punch card because you can't really unpunch holes unless maybe you can put tape over it or something. That trial-and-error feedback loop is much shorter. Whereas with a program, you just pause the simulation, punch-unpunch some holes, restart, and then you just kind of keep trying. And there's something fun about that creative exploration when you've got that really tight feedback loop. STEPHANIE: That's fair. I think perhaps that actually might be why doing it manually, and by it, I mean weaving, gives you a little bit more room to [laughs] debug if you will, because you can see when something goes wrong. And this actually happened to me in class earlier this week where I didn't thread the fiber over instead of under. And I was like, oh, this doesn't look right. Like, that's not the look I'm going for. And then I could kind of quickly see, oh, I missed a thread over here and unravel and do it again. Whereas what you just described, if the punch card is wrong and then you create this big piece of fabric, at that point, I'm not really sure what happens then. If someone out there is a weaving expert and knows the answer; I would be very curious to know. JOËL: Now I kind of wish we'd had this conversation last month because, in early January, there was a game jam event that happened. It's a yearly or biyearly Historically Accurate Game Jam, and they select a theme, and then everybody has to submit a game, or a simulation, or something, an interactive program that fits with the theme. And this year's theme was the Industrial Revolution. And I feel like simulating an old automated loom with punch cards would be the perfect fit for something that's small enough that I could build it in a week without spending 10 hours a day working on it. It fits within the theme, and it's still kind of fun. STEPHANIE: Wow, that would have been a really great idea. If there was an award for best fitting the theme, I think that would have won because then you're also tackling the history of computing. I was talking about earlier the loom obviously being...or the automated loom also really playing a big role in the Industrial Revolution. And, I don't know, maybe this is our future club, Joël, and we're going to get into video game development. [laughs] What's new in your world, Joël? JOËL: There are two things. One is that today former Bike Shed host, Stephanie Viccari, shared a video with me from Ian Anderson. This was made last December to the tune of All I Want For Christmas Is You. But it's all about the, at that time, upcoming Ruby 3.2 release. It is amazing. The lyrics talk about the different features that are upcoming. It rhymes. It's set to meter. I am just blown away by this. And I'm just really hyped [laughs] about this video. STEPHANIE: You sent it to me and I gave it a watch before we sat down to record, and I also loved this video. It was so fun. And I think Ruby has a bit of a tradition of releasing new versions around Christmas time. So if this became a tradition, that would be very fun, and maybe instead of singing Christmas carols, we'll be singing new Ruby version carols around the holidays. JOËL: I feel like if Ian wants to do another one next Christmas, now that you have the precedent, it'd be a great space to try something to the tune of Last Christmas because now you can reference back last year's song. STEPHANIE: Yeah. I might as well just go all in and create a whole Christmas album of Ruby anticipation carols. [laughter] JOËL: Yeah, really excited about that. Kudos to Ian. And for all of our listeners, we'll link the video on the show notes of the podcast. Go and check it out; it is worth the two and a half-minutes of your life. STEPHANIE: Agreed. JOËL: The other cool thing, for the past few episodes, we've been talking a lot about hexagons and how they show up in nature, and bees, and how they build their honeycombs and whether that is sort of by design or sort of just happens by nature through sort of external forces. And so this week, I went out to the store, and I bought some real honeycomb. And I'm going to try it on air. STEPHANIE: [laughs] Oh my gosh, I didn't realize that's what was happening. [laughter] Okay, I'm ready. JOËL: All right, I'm going to take a slice. STEPHANIE: Wow. For research. JOËL: For science. STEPHANIE: Wow, that is a big bite. [laughs] JOËL: Hmmm, it's basically crunchy honey. STEPHANIE: So I've enjoyed honeycomb in that raw form on ice cream. I really like it on there and oatmeal and stuff like that. I think it's a little bit waxy. Like, once you get to chewing the bits at the end, that part is a bit of a less pleasant mouth-feel [laughs] in my opinion. What are you experiencing right now? JOËL: Yeah, so like you're saying, the honey kind of dissolves away in your mouth. You had this really fun mix of textures. But then, in the end, you do end up with a ball of [laughter] beeswax in your mouth. STEPHANIE: Oh no. JOËL: Which I understand is completely safe to eat, so... STEPHANIE: Yeah, that's true. JOËL: I'm just going to eat the whole thing. STEPHANIE: I think it's kind of like swallowing gum. [laughs] JOËL: Which apparently does not last for seven years in your digestive system; that's a myth. STEPHANIE: Wow, debunking myths, trying honeycomb. You're welcome, to all The Bike Shed listeners out there. Investigating the important things. JOËL: What is interesting is that we're talking about the structural power of hexagons. I can cut a pretty thin slice of the comb, and it doesn't fall apart. It still has a lot of strength to it, which is nice because it means that the honey doesn't just go splashing everywhere. I can cut up a fairly thin slice, pick it up, it still holds the honey, put it in my mouth, and it doesn't make a mess. STEPHANIE: The bees know what they're doing. [laughs] Cool. Would you eat raw honeycomb again? JOËL: Well, I got a whole block, and I had one tiny slice. So, yes, I will be eating the rest of this. STEPHANIE: [laughs] JOËL: I don't think this will be a regular thing in my weekly groceries. But I would bring this out again for a special occasion. Or I can see this fitting nicely, like you said, on maybe certain breakfasts, even on a charcuterie board or something. STEPHANIE: Oh yeah, that's a really good use for it. JOËL: In some ways, it's nice because it's a way to have honey without having to have it on something else or having to eat it with a spoon. It's honey that comes with its own carrying vessel. STEPHANIE: That's great. Yeah, like a bread bowl for soup. [laughs] JOËL: Exactly. Bees make their own bread bowls for honey. STEPHANIE: [laughs] MID-ROLL AD: Debugging errors can be a developer's worst nightmare...but it doesn't have to be. Airbrake is an award-winning error monitoring, performance, and deployment tracking tool created by developers for developers that can actually help cut your debugging time in half. So why do developers love Airbrake? It has all of the information that web developers need to monitor their application - including error management, performance insights, and deploy tracking! Airbrake's debugging tool catches all of your project errors, intelligently groups them, and points you to the issue in the code so you can quickly fix the bug before customers are impacted. In addition to stellar error monitoring, Airbrake's lightweight APM helps developers to track the performance and availability of their application through metrics like HTTP requests, response times, error occurrences, and user satisfaction. Finally, Airbrake Deploy Tracking helps developers track trends, fix bad deploys, and improve code quality. Since 2008, Airbrake has been a staple in the Ruby community and has grown to cover all major programming languages. Airbrake seamlessly integrates with your favorite apps to include modern features like single sign-on and SDK-based installation. From testing to production, Airbrake notifiers have your back. Your time is valuable, so why waste it combing through logs, waiting for user reports, or retrofitting other tools to monitor your application? You literally have nothing to lose. Head on over to airbrake.io/try/bikeshed to create your FREE developer account today! JOËL: So, for the last couple of weeks, we've been joking that this is turning into the Stephanie and Joël book club because we've been talking about a lot of articles and books. Today, I'd like to shift a little bit away from literature and lean into art. Writing code is a technical work, but in many ways, it's also an aesthetic work. It's a work of art. How do you feel about the idea of expressing yourself creatively through your code? STEPHANIE: So this is interesting to me because it's actually quite different from what we've been talking about in recent episodes around the idea of writing sustainable code, code for other people to read. Because if you are writing code purely for creative expression and just for yourself, that will look very different than what I think folks have kind of called boring technology, which is choosing the patterns, the tools, the frameworks that are tried and true, and just kind of sticking to the things that people have solved before. And so, in some ways, I don't know if I really get to express myself creatively in the code that I write, which I think is okay for me because I don't really consider myself someone who needs a creative outlet in my work. What about you? What thoughts do you have about this? JOËL: I think it's interesting the way you described it. I'm almost wondering if I'm making maybe a comparison to physical architecture; maybe you almost have a sort of brutalist perspective on the things you construct. STEPHANIE: [laughs] JOËL: So they're functional. They're minimal. They are not always the prettiest to look at, but they're solid. Does that metaphor sound about right to you? STEPHANIE: I feel like I have to make a pun about SOLID, the design patterns, and code. JOËL: Ooh. STEPHANIE: [laughs] But I think I like brutalist, I mean, the term itself. I don't know if I necessarily identify with it in terms of my work and output. But the idea that the code that I do is functional is, I think, particularly important to me as a developer. And I don't just mean, like, oh, the code works, so it's done, but functional for whatever need I'm solving and also for the people who are working with this code again in the future. I mentioned boring technology. There's a talk that I'm kind of referencing by Dan McKinley, and you can check out his slides at boringtechnology.club. And he talks about this idea of decision-making and how that relates to writing boring or creative code. And he also references Maslow's hierarchy of needs. And so, ideally, if you're working in an existing codebase, all the low-level decisions have been made for you. And then you can kind of traverse the hierarchy and focus your creativity on the high-level problems that you're trying to solve. So maybe you're not necessarily expressing your creativity in the syntax or whatever pattern you're using, again, because a lot of those things have been solved. But where the creativity comes from is the particular domain or business problem you have and the real-world constraints that you're faced with. And how do you figure out what to do given those constraints? JOËL: I think that lines up a lot with my own experience as well. I think as a newer developer, syntax is sort of the thing that's top of mind. And so, maybe trying to get clever with syntax is something that I would focus on more. Sometimes that's trying to get code really short and terse. Sometimes it's because I want to try. Can I do this thing with a particular piece of syntax, or even just does it look pretty? I think now, in my code, I am actually kind of boring with my syntax. I, probably when I write Ruby, mostly use a kind of slimmed-down set of syntax and don't use the full expressive power of the language for most of my day-to-day needs. So basic things with objects, and methods, and blocks, sort of the basic building blocks that we get from Ruby regular conditionals, if...else, and a few other nice things that the language gives us. But, in many ways, it almost feels like...I don't know if you've ever seen the simplified English Wikipedia. STEPHANIE: No, I haven't. What is that? JOËL: They're treating it, I think, like a separate language, but it is a version of Wikipedia in English with a more restricted vocabulary to try to make the content more accessible to those that might struggle with more standard English. So it's a sort of smaller subset of English. And, in many ways, I feel like a lot of the day-to-day Ruby code that I write is simplified, Ruby. STEPHANIE: Wow, that's really interesting. I think this also goes back to the specialized vocabulary episode we talked about. And is there value in keeping things accessible, and straightforward, and boring but at the cost of being able to express yourself with everything you have available to you? This is a bit of a tangent, I guess, but I grew up speaking Chinese with my parents, but since then, I have really lost a lot of that vocabulary. And, in some ways, I really struggle with communicating in Chinese because I feel like I'm not able to express myself exactly the way I want to in the way that I can in English. And when I'm talking to my parents, yeah, that's been a bit of a challenge for me because I do really value being able to say things the way that I mean, and I'm not able to have that with my limited vocabulary. So I can also see how people might not enjoy working within these confines of boring syntax and boring frameworks. JOËL: Sometimes it's nice to give yourself a sort of syntactical restriction, but they're very low-level when it comes to most of what we do for programming. And I think that's sort of what I've learned as my career has evolved is that programming is so much more than just learning syntax. So kind of like with art, maybe it's nice to restrict yourself to say, oh, can I do something with only a particular brushstroke technique, or restricting myself to a particular palette or a particular medium? And that can foster a lot of creativity. So, similarly, I think you could do some things like playing Code Golf, not on production code; please don't. STEPHANIE: [laughs] JOËL: But as an experiment in a side project or just almost as a piece of art, that can be a really interesting problem to solve and give you a deeper understanding of the language. And I'm sure there are plenty of other syntactical limitations you could put on yourself or maybe fancy things you would like to explore and say, "Well, this is over the top. We don't need to structure it in this way or use this syntax. But I want to sort of push the boundaries of what can be done with it. Let's see where I can take it." STEPHANIE: That's really fair. And I think it relates back to what I was saying earlier about perhaps creativity when writing software products comes from the constraints of the business of, in some ways, physical aspects of development. In the Dan McKinley talk, I mentioned about choosing boring technology. He generally recommends against bringing in a new language or framework because of the costs, the carrying cost of doing that, and the long-term maintenance to consider. But he instead suggests turning the question on its head and being like, how can we solve this problem with the current technology that we do have? And I think that relates to what you were saying about being able to push the boundaries of a particular medium or tool and in a way that you might not have considered before. JOËL: Exactly. And I think going back to the analogy with art; sometimes it is nice to restrict yourself to a particular brushstroke or something like that to try to foster creativity. But oftentimes, you want to explore creativity in much higher-level ways. So maybe you're not restricting things like brushstrokes and color, and, instead, you want to explore lighting. You want to explore maybe certain ways of mixing colors. There are all sorts of, I think, higher-level ways that you can be creative in art that's not just the mechanics of how you apply pigment to canvas. And we see the same thing like you were saying, in code where there's a lot of higher level business problems. Generally, how do we want to structure large chunks of the code? How do we want to build abstractions? Although that can also be a dangerous place to get too creative in. STEPHANIE: Yeah, absolutely. Do you consider yourself a creative person or need a creative outlet? And how does writing code or software development play a role in that for you? JOËL: I would say, yes, I consider myself a creative person. And I would consider coding, in general, to be a creative endeavor. I sometimes describe to people that writing code is like building something out of infinite legos. You're constrained only by the power of your imagination and the amount of time you're willing to put into constructing the thing that you're building. Of course, then you have all sorts of business constraints. And there are things you want to do on a work project that are probably not the same as what you would want to do on a client project or on a personal project. But there's still creativity, I think, at every level and sometimes even outside of the code itself. Just understanding and breaking down the business problem can require a ton of creativity before you even write a single line of code in your editor. I was reading a Twitter thread the other day by @GeePawHill that sort of proposes that there are sort of four steps in evolution of kind of the mindset that programmers go through over their career. And I'd be curious to hear your thoughts on this evolution if you kind of agree with it or disagree with it if that maybe lines up with some of your experience. So this Twitter thread proposes four levels of thinking that we go through. I think we can kind of jump between these levels at various points in our work. So we might do all of these in a day, but to a certain extent, they also follow a little bit of a progression in our career. So the first level is thinking in terms of syntax; that's just knowing the characters to type in the editor. The second level is thinking in terms of code, that's, thinking a little bit more semantically. So now, instead of thinking, oh, do I need if then curly brace, then closed curly brace? Now we're thinking more in terms of, okay, I need a branch in the flow of control for my logic here. And at that level, maybe you don't even need to think about the syntax quite so much because you're so comfortable with. It kind of just fades away. Building beyond that, now you're thinking in terms of your paradigm. So Ruby is an object-oriented language, so you might be thinking in terms of what objects do I need to represent this problem and how do they need to talk to each other? And the sort of underlying semantics of, oh, do I need a conditional here or not? Those might start fading away because now you're thinking at a slightly higher level. And then, finally, thinking in terms of change sets. Now you're thinking less in terms of the language itself and more in terms of the business problems and how the current behavior of the software is different and needs to change to get to where we want the behavior to be. STEPHANIE: I think I disagree a little bit with the idea that it's a progression. And I'm thinking about how when you have a beginner's mind, anything is possible. And in some ways, if you are new to coding, before you have that understanding of what is and isn't possible, anything is possible. And so, in some ways, I've worked with people who are super new to coding, and the ideas that they come up with for how to make a change at that highest level that you were just describing, in some ways, make sense. You can be like, oh yeah, that actually is something we can do and an idea that you might eventually get to from someone more experienced, having followed those different levels of progression and reaching a place where you're like, I know exactly what tools or the details about how to do this. But when you have that beginner's mind, and you don't have the details of the how, I think you can still think about those problems at a higher level, and that is valuable, and maybe they'll need help implementing along the way. And I think that that could be a really interesting area of collaboration that perhaps we don't do enough in this industry because it's very mentorship-focused where it's like, okay, I have more experience, and so I'm going to teach you what I know. Whereas if you bring someone with a totally fresh perspective along, what ideas can you generate from there? JOËL: I think we definitely exist in all of these layers every day as developers. I think, looking back at myself as a newer developer, I tended to maybe work bottom-up when I tried to solve a problem. And I think that now I probably tend to work sort of in the reverse order, start by thinking in terms of changes and then work my way down. And so syntax, at that point, is the last thing that I'm thinking about. It's really an implementation detail. Whereas I think as a new coder, syntax was super important. Was your experience similar to that, or did you have a very different journey? STEPHANIE: It's funny that you mentioned it because I think when I was new to development, there were so many syntactic things that I didn't understand that I just kind of like blurted out of my brain when I was reading code and was then trying to latch on to the important pieces of information that I needed to know, which often meant class names or method names. Pieces that I could grab onto and be like, okay, I'm seeing that this method then calls this other method or whatever. And, yeah, what you were saying about implementation details falling away, I kind of did that at the beginning of my career a little bit, at least at that syntactic level. So, yeah, I think I'm with you where we all exist at different parts of this framework, I suppose. And that journey could look different for everyone. JOËL: So we're talking about ways to be creative at higher levels. And one way that I find has been really fun for me but also really useful has been bringing in dependency graphs as a tool for design. You knew I had to mention dependency graphs. STEPHANIE: We got there in the end. [laughter] Cool, go on. JOËL: I think it's been really good sometimes in terms of modeling change sets because dependency graphs can be a great tool for that, but also sometimes in terms of trying to understand what the underlying business problem is and how it might translate into code structures where things might be tightly coupled versus not. And so, drawing it out visually is a really powerful design tool. And because now I can look at it in two-dimensional space, I can realize, oh, I see something that feels like it's maybe an anti-pattern or might be a problem here. There's a cycle in my graph; maybe we should find a way to break that. Maybe we need to introduce some dependency inversion and break that cycle, and now our graph is acyclic. And so I think that's where there can be a lot of creativity that happens, even when you're not writing code at that point. You're just sort of talking about how different pieces of the project or even different subproblems...you're not even talking about if they're implemented in code, but just saying this subproblem is related to this subproblem, and maybe I would like to find a way for them to not have a connection to each other. STEPHANIE: I'm glad we got back to this dependency graph topic because I stumbled upon something that I'm curious to hear your opinion on. I have been following Julia Evans' work for a little bit now. And she recently released a new zine about debugging. And at the end of the zine, she includes a link to these choose-your-own adventure puzzles that she has created, specifically to teach you about debugging and how to do it. And so it's basically a little detective game, and you kind of follow along with this bug. And she gives you some different options about how would you like to find a little bit more information about this bug? And what approach would you take? And you make some different selections, and then as you go, you get more information about the bug. And that helps inform what next steps you might take. And, one, I think this is a great example of a creative project about software development, even though it's not necessarily your day-to-day work. But then she also uses a tool called Twine, which is for creating non-linear stories, or puzzles, or games. And it got me really thinking about the multi-step wizard we've been talking about and this idea of looking at a problem in different mediums. It also reminds me of if you have a designer on your team and they're doing prototyping, they usually have some kind of user interactivity that they have to codify. And they are making those decisions about okay, like, if you are at this step, then where do you go next? And those are all things that you've talked about doing as a developer, I think, at a later point in the future lifecycle. And I'm now just kind of thinking about how to integrate some of that into our workflow. Do you have any thoughts about that? JOËL: I had one of the coolest experiences in my career when I was doing a front-end project where we were building a typeahead component that was pulling data from a remote server and then populating a drop-down. And the designer and I sat down and just started to look through all the different states that you could be and how you could move from one to another. So it looked like maybe you start the typeahead is empty; it's just a text box. And then as you start typing, maybe there's a spinner that shows up. And then maybe you have some results, or maybe you don't have results. And those are two different entirely states that you could be in. And then, if you backspace, what happens? And what if something goes wrong on the server? Like, we just kept finding all these edge cases. And we built out a diagram of all the possible journeys that someone could take, starting from that empty text box, all the way to either some sort of error state or a final state where you've selected an item. But, of course, these are not necessarily terminal because in an error state, maybe you can just start typing again, and you sort of jump back into the beginning of the flow. So we did this whole diagram that ended up looking very much like a finite-state machine. We didn't use the term, but that's kind of what it ended up being. And I think we both learned a lot about the problem we were trying to solve and the user experience we were trying to create through that. There was just a lot of back and forth of, like, oh, did you think about what would happen if we get no results here? Have we thought about that state? Or it's like, okay, so now we're in an error state. What do we do? Is there a way to get out of it, or are we just kind of stuck? Oh, you can backspace. Okay, what happens then? STEPHANIE: Yeah, I mean, we've been talking about creativity as a solitary process. But I think that that goes to show that when collaborating with other people, too, that process can also be very fun and creative and fulfill that need outside of the way the code is written. JOËL: In many ways, I think working with somebody else, and that gets made at the intersection of two or more people's work, is probably the most creative way to build software. STEPHANIE: That actually reminds me of a book I read last year called "Tomorrow, and Tomorrow, and Tomorrow." And it's about these two friends and their journey creating video games together. And it kind of follows several decades of their life and their relationship, and their creative and collaborative process. And I really loved that book. It was very good, especially if you like video games. There are a lot of great references to that too. But I think what you were saying about that fulfillment that you can get with working with other people, and that book does a really good job examining that and getting into our need as humans for that type of collaboration. So that's my little book rec. It goes back to our conversation about designing a game. Again, maybe this is [laughs] what we'll do next. Who knows? The world's our oyster. On that note, shall we wrap up? JOËL: Let's wrap up. STEPHANIE: Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thank you so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeeeee!!!!!!!! ANNOUNCER: This podcast is brought to you by thoughtbot, your expert strategy, design, development, and product management partner. We bring digital products from idea to success and teach you how because we care. Learn more at thoughtbot.com.

The Bike Shed
369: Most Impactful Articles of 2022

The Bike Shed

Play Episode Listen Later Jan 31, 2023 50:00


Joël has been pondering another tool for thought from Maggie Appleton: diagramming. What does drawing complex things reveal? Stephanie has updates on how Soup Group went, plus a clarification from last week's episode re: hexagons and tessellation. They also share the top most impactful articles they read in 2022. This episode is brought to you by Airbrake (https://airbrake.io/?utm_campaign=Q3_2022%3A%20Bike%20Shed%20Podcast%20Ad&utm_source=Bike%20Shed&utm_medium=website). Visit Frictionless error monitoring and performance insight for your app stack. Maggie Appleton tools for thought (https://maggieappleton.com/tools-for-thought) Squint test (https://www.youtube.com/watch?v=8bZh5LMaSmE&themeRefresh=1) Cardinality of types (https://guide.elm-lang.org/appendix/types_as_sets.html) Honeycomb hexagon construction (https://www.nature.com/articles/srep28341) Coachability (https://cate.blog/2021/02/22/coachability/) Strangler Fig Pattern (https://shopify.engineering/refactoring-legacy-code-strangler-fig-pattern) Finding time to refactor (https://thoughtbot.com/blog/finding-the-time-to-refactor) Parse don't validate (https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/) Errors cluster around boundaries (https://thoughtbot.com/blog/debugging-at-the-boundaries) Transcript: STEPHANIE: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot that has basically become a two-person book club between me and Joël. [laughter] JOËL: I love that. STEPHANIE: I'm so sorry, I had to. I think we've been sharing so many things we've been reading in the past couple of episodes, and I've been loving it. I think it's a lot of the conversations we have off-air too, and now we're just bringing it on on-air. And I am going to lean into it. [laughs] JOËL: I like it. STEPHANIE: So, Joël, what's new in your world? JOËL: So, in a recent episode, I think it was two episodes ago, you shared an article by Maggie Appleton about tools for thought. And I've kind of been going back to that article a few times in the past few weeks. And I feel like I always see something new. And one tool for thought that Maggie explicitly mentions in the article is diagramming, and that's something that we've used as an industry for a long time to deal with conditional logic is just writing a flow diagram. And I feel like that's such a useful tool sometimes to move away from code and text into visuals and draw your problem rather than write your problem. It's often useful either when I'm trying to figure out how to structure some of my own code or when I'm reviewing a PR for somebody else, and something just feels not quite right, but I'm not quite sure what I want to say. And so drawing the problem all of a sudden might give me some insights, might help me identify why does something feel off about this code that I can't quite put into words? STEPHANIE: What does drawing complex things reveal for you? Is there a time where you were able to see something that you hadn't seen before? JOËL: One thing I think it can make more obvious is the shape of the problem. When we describe a problem in words, sometimes there's a sense of like, okay, there are two main paths through this problem or something. And then when we do our code, we try to make it DRY, and we try all these things. And it's really hard to see the flow of logic. And we might actually have way more paths through our code than are actually needed by the initial problem definition. I think we talked about this in a past episode as well, structuring a multi-step form or a wizard. And oftentimes, that is structured way more complex than it needs to be. And you can really see that difference when you draw out a flow diagram, the difference between forcing everything down a single linear flow with a bunch of little independent conditions versus branching up front three or four or five ways, however many steps you have. And then, from there, it's just executing code. STEPHANIE: I have two thoughts here. Firstly, it's very tragic that this is an audio medium only [laughs] and not also a visual one. Because I think we've joked in the past about when we've, you know, talked about complex problems and branching conditionals and stuff like that, like, oh, like, if only we could show a visual representation to our listeners. [laughs] And secondly, now that makes a lot more sense why there are so many whiteboards just hanging out in offices everywhere. [laughs] JOËL: We should use them more. It's interesting you mentioned the limitations of an audio format that we have. But even just describing the problem in an audio format is different than implementing it in code. So if I were to describe a problem to you that says, oh, we have a multi-step form that has three different steps to it, in that description, you might initially think, oh, that means I want to branch three ways up front, and then each step will need to do some processing. But if you look at the implementation in the code, maybe whoever coded it, and maybe that's yourself, will have done it totally differently with a lot more branching than just three up front because it's a different medium. STEPHANIE: That's a really good point. I also remember reading something about how you can reason about how many branches a piece of code might have if you just look at the structure of the lines of code in your editor if you either step away from it and are just looking at the code not really able to see the text itself but just the shape that it makes. If you have some shorter lines and then a handful of longer lines, you might be able to see like, oh, like these are multiple conditionals happening, which I think is kind of related to what you're saying about taking a piece of code and then diagramming it out to really see the different paths. And I know that that can also be obscured a little bit if you are stylistically using different syntax. Like, if you are using a guard clause to return early, that's a conditional, but it gets a bit hidden from the visual representation than if you had written out the full if statement, for example. JOËL: I think that's a really interesting distinction that you bring up because a lot of languages provide syntactic sugar for common conditional tasks that we do. And sometimes, that syntactic sugar will almost obfuscate the fact that there is a conditional happening at all, which can be great in a lot of cases. But when it comes to analyzing and particularly comparing different implementations, a second conversion that I like to do is converting all of the conditional code to some standardized form, and, for me, that's typically just your basic if...elsif...else expressions. And so any fancy Boolean operators we're doing, any safe navigation that we're doing around nil, maybe some inline conditionals, early returns, things like that, all of the implicit elses that are involved as well, putting them all into some normalized form then allows me to compare two implementations with each other. And sometimes, two approaches that we initially thought were identical, just with different syntax, turned out to have slightly different behavior because maybe one has this sort of implicit branch that the other one doesn't. And by converting to a normalized syntax, all of a sudden, this difference becomes super obvious. To be clear, this is not something I do necessarily in the actual code that I commit, not necessarily writing everything long-form. But definitely, when I'm trying to think about conditional code or analyzing somebody else's code, I will often convert it to long-form, some normalized shape so that I can then see some things about it that were not obvious in the final form. Or to make a comparison with something else, and then you can compare apples to apples and say, okay, both these approaches that we're considering in normalized form, here's what they look like. There's some difference here that we do care about or don't care about. STEPHANIE: That's really interesting. I find it very curious that there is a value in having the long-form approach of writing the code out and being able to identify things. But then the end result that we commit might not look like that and be shortened and be kind of, quote, unquote, "polished," or at least condensed with syntactic sugar. And I'm kind of wondering why that might be the case. JOËL: I think a lot of that will come down to your personal or your company's style guide. Personally, I think I do lean a little bit more towards a slightly more explicit form. But there are plenty of times that I will use syntactic sugar as well, as long as everybody knows what it does. But sometimes, it will come at the cost of other analysis techniques. You had mentioned the squint test earlier, which I believe is a term coined by Sandi Metz. STEPHANIE: I think it might be. That rings a bell. JOËL: And that is a benefit that you get by writing explicit conditionals all the time. But sometimes, it is much nicer to write code that is a little bit more terse. And so you have to do the trade-offs there. STEPHANIE: Yeah, that's a really good point. JOËL: So that's two of the sort of three formats that I was thinking about for converting conditional code to gain more insight. The other format is honestly a little bit weird. It's almost a stretch. But from my time spent working with the Elm language, I learned how to use its type system, which uses a concept called algebraic data types, or some languages will call these tagged unions, some languages will call these sum types. This concept goes by a lot of different names. But they're used to define types into model data. But there's a really fun property, which is that you can model conditional code using this as well. And so you can convert executable code into these algebraic data types. And now, you can apply a lot of tools and heuristics that you have from the data modeling world to this conditional code. STEPHANIE: Do you have a practical example? JOËL: So a classic thing that data modelers will say is you should make impossible states impossible. So in practice, this means that when you define a type using these algebraic data types, you should not be able to create more distinct values than are actually valid in this particular system. So, for example, if a value is required to always be present for something and there's no way in the system for a value to become not present, then don't allow it to be nullable. We do something similar when we design a database schema when we put a null false on a column because we know that this will never be null. And so, why allow nulls when you know they should never be there? So it's a similar thing with the types. This sort of analysis that you can do looking at...the fancy term is the types cardinality. I'll link to an article that digs into that for people who are curious. But that can show you whether a type can represent, let's say, ten possible values, but the domain you're trying to model only has 5. And so when there's that discrepancy, there are five valid values that can be modeled by your type and an additional extra five that are not valid that just kind of shake out from the way you implemented things. So you can take that technique and apply it to a conditional that you've converted to algebraic data type form. And that can help find things like paths through your conditional code that don't line up with the problem that you're trying to solve. So going back to the example I talked about earlier of a multi-step form with three different steps, that's a problem that should have three paths through your conditional. But depending on your implementation, if it's a bunch of independent if clauses, you might have a bit of a combinatorial explosion. And there might be 25 different paths through that chunk of code. And that means three of them are the ones that your problem wants, and then the extra 22 are things that should quote, unquote, "never happen," but we all know that they eventually will. So that kind of analysis can help maybe give you pointers to the fact that your current structure is not well-suited to the problem that you're trying to solve. STEPHANIE: I think another database schema example that came to mind for me was using an enum to declare acceptable values for a field. And, yeah, I know exactly what you mean when working with code where you might know, because of the way the business works, that this thing is impossible, and yet, you still have to either end up coding defensively for it or just kind of hold that complexity in your head. And that can lead to some gnarly situations, and it makes debugging down the line a lot more difficult too. JOËL: It definitely makes it really hard for somebody else to know the original intention of the code when a conditional has more paths through it than there actually are actual paths in the problem you're trying to solve. Because you have to load all of that in your head, and our programmer brains are trained to think about all the edge cases, and what if this condition fires but this other one doesn't? Could that lead to a bug? Is that just a thing that's like, well, but the inputs will never trigger that, so you can ignore it? And if there are no comments to tell you, and if there are comments, then do you trust them? Because it -- STEPHANIE: Yes. [laughter] I'll just jump in here and say, yeah, I have seen the comments then conflict with the code as well. And so you have these two sources of information that are conflicting with each other, and you have no idea what is true and what's not. JOËL: So I'm a big fan of structuring conditional code such that the number of unique paths through a set of conditions is the same as the sort of, you might say, logical paths through the problem domain that we haven't added extra paths, just sort of accidentally due to the way we implemented things. STEPHANIE: Yeah. And now you have three different ways to visualize that information in your head [laughs] with these mental models. JOËL: Right. So from taking code that is conditional code and then transforming it into one of these other representations, I don't always do all three, but there are tools that I have. And I can gain all sorts of new insights into that code by looking at it through a completely different lens. STEPHANIE: That's super cool. JOËL: So the last episode, you had mentioned that you were going to try a soup club. How did that turn out? STEPHANIE: It turned out great. It was awesome, the inaugural soup group. I had, I think, around eight people total. And I spent...right after work, I went straight to chopping celery [laughs] and onions and just soup prepping. And it was such a good time. I invited a different group of friends than normally come together, and that turned out really well. I think we all kind of had at least one thing in common, which was my goal was just to, you know, have my friends come together and meet new people too. And we had soup, and we had bread. Someone brought a spiced crispy chickpea appetizer that went really well inside of our ribollita vegetable bean soup. And then I had the perfect amount of leftovers. So after making a really big batch of food and spending quite a long time cooking, I wanted to make sure that everyone had their fill. But it was also pretty nice to have two servings left over that I could toss in the freezer just for me and as a reward for my hard work. And then it ended up working out really well because I went on vacation last week. And the night we got back home, we were like, "Oh, it's kind of late. What are we going to do for dinner?" And then I got to pull out the leftover soup from my freezer. And it was the perfect coming home from a big trip, and you have nothing in your fridge kind of deal. So it worked out well. JOËL: I guess that's the advantage of hosting is that you get to keep the leftovers. STEPHANIE: It's true. JOËL: You also have to, you know, make the soup. [laughs] STEPHANIE: Also true. [laughs] But like I said, it wasn't like I had so much soup that I was going to have to eat it every single day for the next week and a half. It was just the amount that I wanted. So I'm excited to keep doing this. I'm hoping to do the next soup group in the next week or two. And then some other folks even offered to host it for next time. So maybe we might experiment with doing a rotating thing. But yeah, it has definitely brought me joy through this winter. JOËL: That's so lovely. What else has been new in your world? STEPHANIE: I have a clarification to make from last week's episode. So last week, we were talking about hexagons and tessellation. And we had mentioned that hexagons and triangles were really strong shapes. And we mentioned that, oh yeah, you can see it in the natural world through honeycomb. And I've since learned that bees don't actually build the hexagon shape themselves. That was something that scientists did think to be true for a little bit, that bees were just geometrically inclined, but it turns out that the accepted theory for how honeycomb gets its shape is that bees build cylindrical cells that later transform into hexagons, which does have a lot of surface area for holding the honey, though the process itself is actually still debated by scientists. So there's some research that has supported the idea that it's formed through physical forces like the changing temperature of the wax that transforms it from a cylinder shape into a hexagon, though, yeah, apparently, the studies are still a bit inconclusive. And the last scientific paper I read about this, just to really get my facts straight [laughs], they were kind of exploring aspects of bee behavior that led to the hexagons eventually forming because that does require that the cylinders are perfectly the same size and are at least built in a hexagonal pattern, even though the cells themselves are not hexagons. JOËL: Fascinating. So it sounds like it's either a social thing where the bees do it based off of some behavior. Or if it's a physical thing, it's some sort of like hexagons are a natural equilibrium point that everything kind of trends to, and so as temperature changes, the beehive will naturally trend towards that. STEPHANIE: Yeah, exactly. I have a good friend who is a beekeeper, so I got to pick her brain a little bit about honeycomb. [laughs] MID-ROLL AD: Debugging errors can be a developer's worst nightmare...but it doesn't have to be. Airbrake is an award-winning error monitoring, performance, and deployment tracking tool created by developers for developers that can actually help cut your debugging time in half. So why do developers love Airbrake? It has all of the information that web developers need to monitor their application - including error management, performance insights, and deploy tracking! Airbrake's debugging tool catches all of your project errors, intelligently groups them, and points you to the issue in the code so you can quickly fix the bug before customers are impacted. In addition to stellar error monitoring, Airbrake's lightweight APM helps developers to track the performance and availability of their application through metrics like HTTP requests, response times, error occurrences, and user satisfaction. Finally, Airbrake Deploy Tracking helps developers track trends, fix bad deploys, and improve code quality. Since 2008, Airbrake has been a staple in the Ruby community and has grown to cover all major programming languages. Airbrake seamlessly integrates with your favorite apps to include modern features like single sign-on and SDK-based installation. From testing to production, Airbrake notifiers have your back. Your time is valuable, so why waste it combing through logs, waiting for user reports, or retrofitting other tools to monitor your application? You literally have nothing to lose. Head on over to airbrake.io/try/bikeshed to create your FREE developer account today! JOËL: So in the past few episodes, we've talked about books we're reading, articles that we're reading. This is kind of turning into the Stephanie and Joël book club. STEPHANIE: I love it. JOËL: That got me thinking about things that I've read that were impactful in the past year. So I'm curious for both of us what might be, let's say, the top two or three most impactful articles that you read in 2022. Or maybe to put it another way, what are the top two or three articles that you reference the most in conversations with other people? STEPHANIE: So listeners might not know this, but I actually joined thoughtbot early last year in February. So I was coming into this new job, and I was so excited to be joining an organization with so many talented developers. And I was really excited to learn from everyone. So I kind of came in with really big goals around my technical growth. And the end of the year just passed, and I got to do a little bit of reflection. And I was quite proud of myself actually for all the things that I had learned and all the ways that I had grown. And I was reminded of this blog post that I think I had in the back of my mind around "Coachability" by Cate, and she talks about how coaching is different from mentorship. And she provides some really cool mental models for different ways of providing support to your teammates. Let's say mentorship is teaching someone how to swim, and maybe helping someone out with a task might be throwing them a life raft. Coaching is more like seeing someone in the water, but you are up on a bridge, and you are kind of seeing all of their surroundings. And you are identifying ways that they can help themselves. So maybe there's a branch, a tree branch, a few feet away from them. And can they go grab that tree branch? How can they help themselves? So I came to this new job at thoughtbot, and I had these really big goals. But I also knew that I wanted to lean on my new co-workers and just be able to not only learn the things that I was really excited to learn but also trust that they had my best interests in mind as well and for them to be able to point out things that could help my career growth. So the idea of coachability was really interesting to me because I had been coming from a workplace that had a really great feedback culture. But I think this article touches on what to do with feedback in a way that I hadn't seen before. So she also describes being coachable as having two axes, one of them being receptiveness to feedback and the other being actionability in response to feedback. So receptiveness is when you hear feedback; do you listen to it? Do you work through it? How does that feedback fit into your mental model of your goals and your skills? And then actionability is like, okay, what do you do with that? How do you change your behavior? How do you change the way you approach problems? And those two things in mind were really helpful in terms of understanding how I respond to feedback and how to really make the most of it when I receive it. Because there are times when I get feedback, and I don't know what to do with it, you know, maybe it just wasn't specific enough. And so, in that sense, I want to work on my actionability and figuring out, okay, someone said that testing would be a really great opportunity for me to learn. But what can I do to learn how to write better tests? And that might involve figuring that out on my own, like, what strategies work for me. Or that might involve asking them, being like, "What do you recommend?" So yeah, I had this really big year of growth. And I'm excited to keep this mental model in mind when I feel like I might be stuck and I'm not getting the growth that I want and using those axes to kind of determine how to move forward. JOËL: I think the first thing that comes to mind for me is the episode that you and I did a while back about the value of precise language. For example, you talked about the distinction between coaching and mentorship, which I think in sort of colloquial speech, we kind of use interchangeably. But having them both mean different things, and then being able to talk about those or at least analyze yourself through the lens of those two words, I think, is really valuable and may be helping to drive either insights or actions that you can take. And similarly, this idea of having two different axes for receptiveness versus...was it changeability you said was the other one? STEPHANIE: Actionability. JOËL: Actionability, I think, is really helpful when you're feeling stuck because now you can realize, oh, is it because I'm not accepting feedback or not getting good feedback? Or is it that I'm getting feedback, but it's hard to take action on it? So just all of a sudden, having those terms and having that mental model, that framework, I feel like equips me to engage with feedback in a way that is much more powerful than when we kind of used all those terms interchangeably. STEPHANIE: Yeah, exactly. I think that it's very well understood that feedback is important and having a good feedback culture is really healthy. But I think we don't always talk about the next step, which is what do you do with feedback? And with the help of this article, I've kind of come to realize that all feedback is valuable, but not all of it is good. And she makes a really excellent point of saying that the way you respond to feedback also depends on the relationship you have with the person giving it. So, ideally, you have a high trust high respect relationship with that person. And so when they give you feedback, you are like, yeah, I'm receptive to this, and I want to do something about it. But sometimes you get feedback from someone, and you might not have that trust in that relationship or that respect. And it just straight up might not be good feedback for you. And the way you engage with it could be figuring out what part of it is helpful for me and what part of it is not? And if it's not helpful in terms of helping your growth, it might at least be informative. And that might help you learn something about the other person or about the circumstances or environment that you're in. JOËL: Again, I love the distinction you're making between helpful and informative. STEPHANIE: Yeah. I think I had to learn that the hard way this year. [laughs] So, yeah, I really hope that folks find this vocabulary or this idea...or consider it when they are thinking about feedback in terms of giving it or receiving it and using it in a way that works for them to grow the way they want to. JOËL: I'm curious, in your interactions, and learning, and growth over the past year, do you feel like you've leaned a little bit more into the mentorship or the coaching side of things? What would you say is the rough percentage breakdown? Are we talking 50-50, 80-20? STEPHANIE: That's such a good question. I think I received both this year. But I think I'm at a point in my career where coaching is more valuable to me. And I'm reminded of a time a few months into joining thoughtbot where I was working and pairing with a principal developer. And he was really turning the workaround on me and asking, like, what do I want to do? What do I see in the code? What areas do I want to explore? And I found it really uncomfortable because I was like, oh, I just want you to tell me what to do because I don't know, or at least at the time, I was really...I found it kind of stressful. But now, looking back on it and with this vocabulary, I'm like, oh, that's what true coaching was because I gained a lot of experience towards my foundational skill set of figuring out how to solve problems or identifying areas of refactoring through that process. And so sometimes coaching can feel really uncomfortable because you are stretching outside of your comfort zone and that your coach is hopefully supporting you but not just giving you the help but teaching you how to help yourself. JOËL: That's a really interesting thing to notice. And I think what I'm hearing is that coaching can feel less comfortable than mentoring because you're being asked to do more of the work yourself. And you're maybe being stretched in some ways that aren't exactly the same as you would get in a more mentoring-focused scenario. Does that sound right? STEPHANIE: Yeah, I think that sounds right because, like I said, I was also receiving mentorship, and I learned about new things. But those didn't always solidify in terms of empowering me next time to be able to do it without the help of someone else. Joël, what was an article that really spoke to you this last year? JOËL: So I really appreciated an article by Adrianna Chang, who's a developer at Shopify, about "Refactoring Legacy Code with the Strangler Fig Pattern." And it talks about this approach to moving refactoring code from one implementation to another. And it's a longer-ranged process, and how to do so incrementally. And a big theme for me this year has been refactoring and incremental change. I've had a lot of conversations with people about how to spot smaller steps. I've written an article on working incrementally. And so I think this was really nice because it gave a very particular technique on how to do so with an example. And so, because these sorts of conversations kept coming up this year, I found myself referencing this article all the time. STEPHANIE: I really loved this article too. And this last year, I also saw a strangler fig tree for the first time in real life in Florida. And I think that was after I had read this article. And it was really cool to make the connection between something I was seeing in nature with a pattern in software development or technique. JOËL: We have this metaphor, and now you get to see the real thing. I was excited because, at RubyConf Mini this year, I actually got to meet Adrianna. So it was really cool. It's like, "Hey, I've been referencing your article all year. It's super cool to meet you in person." STEPHANIE: That's awesome. I love that, just being able to support members of the community. What I really liked about the approach this article advocated for is that it allowed developers to continue working. You don't have to halt everything and dedicate time to refactor and not get any new feature work done. And that's the beauty of the incremental approach that you were talking about earlier, where you can continue development. Sometimes that refactoring might be paused for some reason or another, but then you can pick back up where you left off. And that is really intriguing to me because I think this past year, I was working on a client where refactoring seemed like something we had to dedicate special time for. And it constantly became tough to prioritize and sell to stakeholders. Whereas if you incorporate it into the work and do it in a way that doesn't stop the show [laughs] from going on, it can work really well and work towards sustainability and maintenance, which is another thing that we've talked a lot about on the show. JOËL: Something that's really powerful, I think, with that technique is that it allows you to have all of the intermediate steps get merged into your main branch and get shipped. So you don't have to have this long-running branch with a big change that's constantly going stale, and you're having to keep in sync with the main branch. And, unfortunately, I've often seen even this sort of thing where you create a long-running branch for a big change, a big refactor, and eventually, it just gets abandoned, and you have not locked in any wins. STEPHANIE: Yeah, that's the worst of both worlds where you've dedicated time and resources and don't get the benefits of that work. I also liked that the strangler fig pattern kind of forces you to really understand the existing code. I think working with legacy code can be really challenging. And a lot of people don't like to do it because it involves a lot of spelunking and figuring out, okay, what's really going on. But in order to isolate the pieces to, you know, slowly start to stop making calls to the old code, it requires that you take a hard look at your legacy code and really figure it out. And I honestly think that that then informs the new code that you write to better support both the old feature and also any new features to come. JOËL: Definitely. The really nice thing about this pattern is that it also scales up and down. You can do this really small...even as part of a feature branch; maybe it's just part of your development process, even if you don't necessarily ship all of the intermediate steps. But it helps you work more incrementally and in a tighter scope. And then you can scale it up as big as changing out entire sections of a framework or...I think Adrianna's example is like switching out a data source. And so you can do some really large refactors. But then you could do it as well on just a small feature. I really like using this pattern anytime you're doing things like Rails upgrades, and you've got old gems that might not convert over where it's like, oh, the community abandoned this gem between Rails 4 and Rails 5. But now you need sort of a bridge to get over. And so I think that pattern is particularly powerful when doing something like a Rails upgrade. STEPHANIE: Very Cool. JOËL: So what would be a second article that was really impactful for you in the past year? STEPHANIE: So, speaking of refactoring, I really enjoyed a blog post called Finding Time to Refactor by a former thoughtboter, German Velasco. He makes a really great point that we should think of completeness in our work, not just when the code works as expected or meets the product requirements, but also when it is clear and maintainable. And so he really advocates for baking refactoring into just your normal development process. And like I said, that goes back to this idea that it can be incremental. It doesn't have to be separate or something that we do later, which is kind of what I had learned before coming to thoughtbot. So when I was also speaking about just my technical growth, this shift in philosophy, for me, was a really big part of that. And I just started kind of thinking and seeing ways to just do it in my regular process. And I think that has really helped me to feel better about my work and also see a noticeable improvement in the quality of my code. So he mentioned the three times that he makes sure to refactor, and that is one when he is practicing TDD and going through the red-green-refactor cycle. JOËL: It's in the name. STEPHANIE: [laughs] It really is. Two, when code is difficult to understand, so if he's coming in and fixing a bug and he pays the tax of trying to figure out confusing code, that's a really great opportunity to then reduce that caring cost for others by making it clear while you're in there, so leaving things better than you found it. And then three, when the existing design doesn't work. We, I think, have mentioned the adage, "Make the change easy, and then make the easy change." So if he's coming in to add a new feature and it's just not quite working, then that's a really good opportunity to refactor the existing design to support this new information or new concept. JOËL: I like those three scenarios. And I think that second one, in particular, resonated with me, the making things easier to understand. And in the sort of narrower sense of the word refactoring, traditionally, this means changing the structure of the code without changing its behavior. And I once had a situation where I was dealing with a series of early return expressions in a method that were all returning Booleans. And it was really hard because there were some unlesses, some ifs, some weird negation happening. And I just couldn't figure out what this code was doing. STEPHANIE: Did you draw a diagram? [laughs] JOËL: I did not. But it turns out this code was untested. And so I pretty much just tried, like, it took two Booleans as inputs and gave back a Boolean. So I just tried all the combinations, put it in, saw what it gave me out, and then wrote tests for them. And then realized that the test cases were telling me that this code was always returning false unless both inputs were true. And that's when it kind of hits me, it's like, wait a minute, this is Boolean AND. We've reimplemented Boolean AND with this convoluted set of conditional code. And so, at the end there, once I had that test coverage to feel confident, I went in and did a refactor where I changed the implementation. Instead of being...I think it was like three or four inline conditionals, just rewrote it as argument one and argument two, and that was much easier to read. STEPHANIE: That's a great point. Because the next time someone comes in here, and let's say they have to maybe add another condition or whatever, they're not just tacking on to this really confusing thing. You've hopefully made it easier for them to work with that code. And I also really appreciated, you know, I was mentioning how this article affected my thought process and how I approach development, but it's a really great one to share to then foster a culture of just continuous refactoring, I guess, is what I'm going to call it [laughs] and hopefully, avoiding having to do a massive rewrite or a massive effort to refactor. The phrase that comes to mind is many hands make light work. And if we all incorporated this into our process, perhaps we would just be working all around with more delightful code. Joël, do you have one more article that really stood out to you this year? JOËL: One that I think I really connected with this year is "Parse, Don't Validate" by Alexis King. Long-time listeners of the show will have heard me talk about this a little bit with Chris Toomey when he was a guest on the show this past fall. But the gist of the article is that the process of parsing is converting a broader type into a narrower type with the potential for errors. So traditionally, we think of this as turning a string which a string is very broad. All sorts of things are strings, and then you turn it into something else. So maybe you're parsing JSON. So you take a string of characters and try to turn it into a Ruby hash, but not all strings are valid hashes. So there's also the possibility for errors. And so, JSON.parse() could raise an error in Ruby. This idea, though, can be then expanded because, ideally, you don't want to just check that a value is valid for your stricter rules. You don't want to just check that a string is valid JSON and then pass the string along to the next person. You actually want to transform it. And then everybody else down the line can interact with that hash and not have to do a check again is this valid JSON? You've already validated that you've already converted it into a hash. You don't need to check that it's valid JSON again because, by the nature of being a hash, it's impossible for it to be invalid. Now, you might have some extra requirements on that hash. So maybe you require certain keys to be present and things like that. And I think that's where this idea gets even more powerful because then you can kind of layer this on top and have a second parsing step where you say, I'm going to parse this hash into, let's say, a shopping cart object. And so, not all Ruby hashes are valid shopping carts. And so you try to take a broader value and coerce it into a narrower value or transform it into a narrower value and potentially raise an error for those hashes that are not valid shopping carts. And then, whoever down the line gets a shopping cart object, you can just call items on it. You can call price on it. You don't need to check is this key present? Because now you have that certainty. STEPHANIE: This reminds me of when I was working with TypeScript in the summer of last year. And having come from a dynamically-typed language background, it was really challenging but also really interesting to me because we were also parsing JSON. But once we had transformed or parsed that data into this domain object, we had a lot more confidence about what we were working in. And all the functions we wrote down the line or used on the line, we could know for sure that, okay, it has these properties about it. And that really shaped the code we wrote. JOËL: So use the word confident here, which, for me, it's a keyword. And so you can now assume that certain properties are true because it's been checked once. That can be tricky if you don't actually do a transformation. If you're just sort of passing a raw value down, you'll often end up with code that is defensive that keeps rechecking the same conditions over and over. And you see this lot around nil in Ruby where somebody checks for a value for nil, and then inside that conditional, three or four other conditions deep, we recheck the same value for nil again, even though, in theory, it should not be nil at that point. And so by doing transformations like that, by parsing instead of just validating, we can ensure that we don't have to repeat those conditions. STEPHANIE: Yeah, I mean, that refers back to the analyzing conditional code that we spent a bit of time talking about at the beginning of this episode. Because I remember in that application, we render different components based on the status of this domain object. And there was a condition for when the status was something that was not expected. And then someone had left a comment that was like, technically, this should never happen. But I think that he had to add it to appease the compiler. And I think had we been able to better enforce those boundaries, had we been more thoughtful around our domain modeling, we could have figured out how to make sure that we weren't then introducing that ambiguity down the line. JOËL: I think it's interesting that you immediately went to talking about TypeScript here because TypeScript has a type system. And the "f, Don't Validate" article is written in Haskell, which is another typed language. And types are great for showing you exactly like, here's the boundary. On this side of it, it's a string, and on this side here, it's a richly-typed value that has been parsed. In Ruby, we don't have that, everything is duck-typed, but I think the principle still applies. It's a little bit more implicit, but there are zones of high or low assumptions about the data. So when I'm interacting directly with raw input from a third-party endpoint, I'm really only expecting some kind of raw string from the body of the response. It may or may not be valid. There are all sorts of checks I need to do to make sure I can do anything with it. So that is a very low assumption zone. Later on, in the business logic part of the code, I might expect that I can call a method on the object to get the price of a shopping cart or a list of items or something like that. Now I'm in a much higher assumption zone. And being self-aware about where we transition from low assumptions to high assumptions is, I think, a really key takeaway for how we interact with code in Ruby. Because, oftentimes, where that boundary is a little bit fuzzy or where we think it's in one place but it's actually in a different place is where bugs tend to cluster. STEPHANIE: Do you have any thoughts about how to adhere to those rules that we're making so we're not having to assume in a dynamically-typed language? JOËL: One way that I think is often helpful is trying to use richer objects and to not just rely on primitives all the time. So don't pass a business process a hash and be just like, trust me, I checked it; it's got the right keys because the day will come when you pass it a malformed hash and now we're going to have an error in the business process. And now we have a dilemma because do we want to start adding defensive checks in the business process to be like, oh, are all our keys that we expect present, things like that? Do we need to elsewhere in the code make sure we process the hash correctly? It becomes a little bit messy. And so, oftentimes, it might be better to say, don't pass a raw hash around. Create a domain object that has the actual method that you want, and pass that instead. STEPHANIE: Oh, sounds like a great opportunity to use the new data class in Ruby 3.2 that we talked about in an episode prior. JOËL: That's a great suggestion. I would definitely reach for something like that, I think, in a situation where I'm trying to model something a little bit richer than just a hash. STEPHANIE: I also think that there have been more trends around borrowing concepts from functional programming, and especially with the introduction of classes that represent nil or empty states, so instead of just using the default nil, having at least a bit of context around a nil what or an empty what. That then might have methods that either raise an error or just signal that something is wrong with the assumptions that we're making around the flexibility that we get from duck typing. I'm really glad that you proposed this topic idea for today's episode because it really represented a lot of themes that we have been discussing on the show in the past couple of months. And I am excited to maybe do this again in the future to just capture what's been interesting or inspiring for us throughout the year. JOËL: On that note, shall we wrap up? STEPHANIE: Let's wrap up. Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thank you so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeeeeee!!!!!!!! ANNOUNCER: This podcast is brought to you by thoughtbot, your expert strategy, design, development, and product management partner. We bring digital products from idea to success and teach you how because we care. Learn more at thoughtbot.com.

The Bike Shed
368: Sustainable Web Development

The Bike Shed

Play Episode Listen Later Jan 24, 2023 36:03


Stephanie talks about hosting a "Soup Group"! Joël got nerd-sniped during the last episode and dove deeper into Maggie Appleton's "Tools for Thought." Stephanie has been thinking a lot about Sustainable Web Development. What is sustainability? How does it relate to tech and what we do? This episode is brought to you by Airbrake (https://airbrake.io/?utm_campaign=Q3_2022%3A%20Bike%20Shed%20Podcast%20Ad&utm_source=Bike%20Shed&utm_medium=website). Visit Frictionless error monitoring and performance insight for your app stack. Maggie Appleton's Tools for Thought (https://maggieappleton.com/tools-for-thought) Tangrams (https://en.wikipedia.org/wiki/Tangram) Tessellation (https://en.wikipedia.org/wiki/Tessellation) Hexagons are the Bestagons (https://www.youtube.com/watch?v=thOifuHs6eY) Sustainable Web Development with Ruby on Rails (https://sustainable-rails.com/) Transcript: AD: thoughtbot is thrilled to announce our own incubator launching this year. If you are a non-technical founding team with a business idea that involves a web or mobile app, we encourage you to apply for our eight-week program. We'll help you move forward with confidence in your team, your product vision, and a roadmap for getting you there. Learn more and apply at tbot.io/incubator. JOËL: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Joël Quenneville. STEPHANIE: And I'm Stephanie Minn. And together, we're here to share a bit of what we've learned along the way. JOËL: So, Stephanie, what's new in your world? STEPHANIE: I'm excited to share a winter survival idea for folks out there who are, like me, in a very cold place where all your friends don't want to hang out [laughs] and bear the cold temperatures of deep winter in January. Because tonight, I'm hosting my first soup group where I'm basically just going to make a really big batch of soup and have my friends come over with bread, and we're going to eat soup and bread and be cozy. And I'm really excited because I was trying to figure out a way to combat the winter blues a little bit. And, yeah, I think this time of year can be really tough after the holidays to get people together again. At least for me, I was feeling like I haven't seen my friends in so long. And I was like, well, I could just be the person to take the initiative [laughs] and be like, "Come over to our place." And the goal is to eventually do this regularly and just have this low-stakes open invitation for anyone to come and show up however they want to. It doesn't have to be, like, big pressure or anything. And if they can't make it at any one time, then there will hopefully be one in the future where they can make it, so I'm excited. After this, I am going to make soup for ten people, and it's going to be great. [laughs] JOËL: I love this idea. Soup on a cold day is just the coziest thing. STEPHANIE: Yeah, exactly. I definitely wanted to just make people feel warm and cozy. And that's what I want, so I'm really doing this for myself. [laughs] JOËL: And you know the advantage of hosting is you don't have to go outside. STEPHANIE: Yeah, that's the real thing is I'm probably going to kick everyone out at like 11:00 p.m. and then go straight to bed, and it's going to be great. [laughs] JOËL: Have you been experimenting with a particular kind of soup recently? Are you going to bring out an old favorite? STEPHANIE: Yeah, I'm excited to make ribollita today, so kind of like a Tuscan style of veggie hearty soup. And I've just been bookmarking soup recipes left and right. [laughs] And I've outsourced the bread situation. So I'm excited to see what kind of bread people bring. And yeah, it'll be very fun and kind of surprising in a comforting way. JOËL: I'm not familiar with this soup. It's ribollita you said? STEPHANIE: Yeah, that's it. JOËL: You said it's a vegetable soup. STEPHANIE: Yeah, mostly veggies and beans. So I have this giant cabbage, a lot of kale, multiple cans of Great Northern white beans, and they're all going to get mixed together. And we'll see how it turns out. I'll update the podcast on how the soup group goes. It is the inaugural one. So I can't think of a time that I made that much soup before. So, hopefully, it goes well. We'll find out. So, Joël, what about you? What's new in your world? JOËL: So, in the previous episode, we talked a little bit about some of the things you had learned about note-taking. And you'd mentioned an article by, I think, Maggie Applebon -- STEPHANIE: Maggie Appleton. JOËL: Appleton...on tools for thought. It was linked in the show notes of that episode. And I went back and read that article, and it was so good, particularly the section, I think, on historical tools for thought and how they, over time, were sort of groundbreaking in helping us to either remember things or to think about problems or ideas in a different way, or to sort of interrogate those ideas and see if we think they're true or helpful. And these were things like writing or the number system but even some more fancy things like the scientific method for the Cartesian coordinate system. STEPHANIE: Yeah, I was really excited to share this with you because I think it was the intersection of a lot of your different interests, including note-taking, diagrams, history, and human cognition, so I'm glad that you found it interesting. JOËL: I definitely got nerd-sniped there. STEPHANIE: [laughs] JOËL: I think one thing that really struck me was the power of having multiple different representations for ideas. And one that jumped out at me was the Cartesian coordinate system, which, among other things, a really powerful tool that gave people...when this was invented, it allowed you to convert algebra problems into geometry problems. And so now, something that used to be an equation you can draw as a triangle or something. And we know how to find the area of a triangle. That's been known since the ancient Greeks and even earlier. And so now a problem that sounded hard is now easy, or at least we have a different way to think about that problem. Because if this equation is equivalent to a triangle, what does that mean? And vice versa, you can use this to convert geometry problems into algebra problems. And so sometimes the power of a new tool for thought might be in that it allows you to sort of convert between two other existing ways of representing things. And making those connections, all of a sudden gives you a whole new way of thinking about things. That blew my mind. STEPHANIE: Yeah, I agree. I think the other really cool thing is that a lot of these ideas that humans are discovering also already existed in the natural world. So when you are talking about math, you can see representations of math in plants and nature, and I was reminded of how honeycomb from bees is one of the strongest shapes. And yeah, it's really neat to draw inspiration from a lot of places and learn from things that, like, figured it out before we did. JOËL: Have you seen the video on YouTube called "Hexagons are the Bestagons?" STEPHANIE: No, I have not. Tell me more. JOËL: It's a video on YouTube. We can link it in the show notes. Basically, the hexagon shows up everywhere in nature in part because it has a lot of really fun mathematical properties. It's one of the few shapes that you can use to completely cover a surface. So if you want to subdivide a two-dimensional surface into smaller shapes without leaving any empty spaces between them, you really don't have that many options. I want to say it's like squares and triangles and hexagons are the only shapes that can do that. And hexagons have these really fun properties around strength. They also are one of the best balances between volume versus the amount of material that it takes to give you that volume and for strength and things like that. So it's good for honeycombs because you can store a lot of honey for very little amount of wax. But it's also good for all sorts of structural engineering because you can build things that are very strong yet light because they require very little metal or other material to create them. STEPHANIE: When you're saying hexagons filling a lot of space, I also thought about how they've become kind of popular in tiles or interior design in kitchens, and bathrooms, and stuff. [laughs] I've definitely seen that trend a bit. [laughs] So that's really cool just to see, like, yeah, this thing in the natural world that we have adopted for other uses. It's really fun. JOËL: I want to say this idea of taking a 2D space and being able to completely cover it without spaces with a shape is called tessellating a plane. It's a fancy term for it. And if you want to do it with just a single shape, I think there are only like three or four shapes that can do it. STEPHANIE: That's really interesting because it reminds me of those tessellation puzzles that I used to play with as a kid. Do you know what I'm talking about? JOËL: You're thinking like a tangram or something different. STEPHANIE: Yeah, yeah, tangram, that was...oh my gosh, those were fun. Wow, I was learning math as a young child, [laughs] just didn't even know it. JOËL: Another random fun fact: the logo for the Elm programming language is a tangram. STEPHANIE: [Gasps] JOËL: And the community is sort of encouraged to then remix it because the tangram is just a square tessellated out of a bunch of these shapes. But then, if you're building a library or you've got an event or something, the community will take those shapes and remix them into some other shapes that might fit your event. STEPHANIE: That's really cool. Is it a metaphor for how Elm can be used in different ways? [laughs] JOËL: I'm not sure about the story behind the logo. We'd have to look that up. STEPHANIE: That'll be a good adventure for later. [laughs] JOËL: In...I want to say Moroccan art, but I think it might be broader than just Moroccan. It might be more broadly North African or Moorish or whatever you want to call that. There's a long history of building these tessellations, I think, out of tiles, but maybe other things as well where you're doing it with a variety of shapes. So you might start...a classic one, I think is an eight-pointed...is it eight, or? I think it's an eight-pointed star, and then you sort of add other shapes around it. And those can create patterns that take a long time to repeat. And there are these beautiful geometric patterns that just keep on going and expanding without necessarily repeating over a lot of space. STEPHANIE: Whoa. That kind of blows my mind a little bit. It seems so counterintuitive, but then I feel like there are a lot of things in math that are like that as well. JOËL: So, yeah, I think a classic pattern you might start with something like an eight-pointed star. And then maybe to fill in the spaces around that central star, you might put some squares, and then maybe you put some triangles around that, and you sort of keep trying to fill in. And maybe eventually you get to another eight-pointed star, but it's not always perfectly symmetric. STEPHANIE: Someone should make a board game or something out of this idea. [laughs] JOËL: Oooh. STEPHANIE: I bet there's one that exists. But I'm just thinking about people who like jigsaw puzzles and that being the next level challenge of, like, can you figure out how things fit together without the confines of a little jigsaw shape? [laughs] JOËL: Right, right. You have a rectangle shape that you have to perfectly fill in with all of these other smaller shapes, and there is a single solution that will work. You have to figure it out. STEPHANIE: I personally would be very overwhelmed, [laughs] but it sounds fun at the same time. JOËL: So those are a lot of thoughts that I've been having inspiration reading that article that you shared on a previous episode. Have you been reading anything interesting recently? STEPHANIE: I have. I'm really excited to talk about this topic because during my investment time this past week, I've been thinking a lot about it, taking a lot of notes in Obsidian, which is a callback to the last episode, and yeah, I'm excited to kind of get into it. So what I've been reading is Sustainable Web Development with Ruby on Rails by ‎David Bryant Copeland. And I think a lot of fellow thoughtboters have referenced this book or talked a little bit about ideas from this book; at least, I've seen discussion about it in Slack, so that's kind of why I wanted to pick it up. But what really blew my mind was honestly the first chapter where he talks about why he wrote this book and basically what sustainable web development is because it is a little bit, maybe, like a buzzy word. It's like, what is sustainability? How does it relate to tech and what we do? And he basically gets down to it by saying that the software that we write is sustainable if it continues to meet our needs years into the future or has longevity and continues to be something we can iterate and work on and not feel that pain or friction, and we feel like we want to, and we feel joyful working on this codebase. So that was kind of my interpretation of his definition about sustainability. JOËL: I love that definition of sustainability about code that can grow and live for a long time. And I feel like that's not a universal value in the tech industry. And on the extreme end of that, you'll have teams that promote the idea that maybe every few years, you should throw out your old codebase and rewrite. I want to say some teams at Google may have done that as a practice for a while, and, of course, then people quote that as a best practice. To a certain extent, I want to say that's kind of what happens with Basecamp in that there are multiple versions of Basecamp. And I want to say each of those is a fresh Rails app. So there's a sense in which those or that style of development is not sustainable in the definition that you were just giving there. How do you feel about that? STEPHANIE: I definitely think the industry has a bias towards newness and change. And a lot of people want to pick up the hot, new technology and, like you said, rewrite code, especially when it's become hard to work with. And honestly, I think that could be its whole own episode, rewrites because I think you and I have pretty strong opinions about it. But I genuinely think that most of our work is, at least, you and I on the Boost team, in particular here at thoughtbot, where we embed on existing client teams, and usually, that means legacy code as well, but I think that the work of development is mostly extending existing code and trying to sustain applications that have users and are working for users. And I think that that's certainly a value that I wish were highlighted more or were invested in more because sometimes that change or wanting to hop on to do something different or do something new has a lot of consequences that I'm not sure we talk about enough as an industry. MID-ROLL AD: Debugging errors can be a developer's worst nightmare...but it doesn't have to be. Airbrake is an award-winning error monitoring, performance, and deployment tracking tool created by developers for developers that can actually help cut your debugging time in half. So why do developers love Airbrake? It has all of the information that web developers need to monitor their application - including error management, performance insights, and deploy tracking! Airbrake's debugging tool catches all of your project errors, intelligently groups them, and points you to the issue in the code so you can quickly fix the bug before customers are impacted. In addition to stellar error monitoring, Airbrake's lightweight APM helps developers to track the performance and availability of their application through metrics like HTTP requests, response times, error occurrences, and user satisfaction. Finally, Airbrake Deploy Tracking helps developers track trends, fix bad deploys, and improve code quality. Since 2008, Airbrake has been a staple in the Ruby community and has grown to cover all major programming languages. Airbrake seamlessly integrates with your favorite apps to include modern features like single sign-on and SDK-based installation. From testing to production, Airbrake notifiers have your back. Your time is valuable, so why waste it combing through logs, waiting for user reports, or retrofitting other tools to monitor your application? You literally have nothing to lose. Head on over to airbrake.io/try/bikeshed to create your FREE developer account today! JOËL: It's interesting you mentioned the types of projects that we tend to be on. I feel like there are a lot of projects that I've been brought on where my goal, specifically coming onto this project, was to make the software more sustainable for the team. It's very easy to sort of start moving very fast in the beginning with a greenfield app, and then eventually, a lot of your choices catch up to you. And then, as your team grows and your product grows, it becomes less and less sustainable. And that's often the point in the lifecycle of the product where I might join the team and try to help make things better for them. I love the keyword sustainable. I don't think that's one that I've used a lot, but it's a great label to put on that kind of work. STEPHANIE: Yeah, I agree. I think what you mentioned earlier, too, about values that, really stuck out to me in this book because it basically says, "This book is for you if you value these three things: sustainability, consistency, and quality." And all of the recommendations and techniques that he then presents in the rest of the book, using Rails, those decisions are recommended with those three values in mind. And I think, one, those values are personally important to me as a developer. But it also helped me develop some guiding principles around decision-making and provided a lot of clarity around times that I've been on teams where we were doing things that didn't quite align with my values, and I didn't enjoy it. And I couldn't really figure out why. But now I'm able to see that, oh, perhaps this team or organization was valuing something like speed, or profit, or change, or something like that that I just fundamentally value differently. And that was kind of where my internal friction or contentment or discontentment was coming from when working on these teams. So, yeah, that was really clarifying for me. JOËL: Would you say, for you, when you talk about these values, that these are fundamental or ultimate values for you when you write code? Or are they values that are a good way to sort of be a means to some other end? You know, for example, sustainability, do you care about sustainability just for its own sake? Or do you care about it because you want a product to be able to live for a long time? You're building for ten years or 20 years or however long you want this project to last. STEPHANIE: I think the thing with values is that they are really fundamental to a person's identity or belief system. In fact, the definition that I'm kind of working off of here is that values are those fundamental beliefs that drive our actions. And so when you say, like, are values driving how you write code? I think they drive everything. [laughs] But the point that he makes in this book is like, here's how they drive code and technical decisions. So the book is actually quite specific about technical recommendations that he has in the context of Rails. And it's funny because we're talking pretty abstractly and big picture about values and things like that. But then I think it's because he sets the stage to be like, everything I recommend here is what I believe to be sustainable, and good quality, and consistent. And just for an example, one of the recommendations he makes is to, when you're kind of setting up a greenfield application, is to use a SQL schema instead of the default ActiveRecord DSL, so using a structure .SQL file. Because, in his eyes, having the flexibility to write SQL and use the most you can with those tools when it comes to database work is more sustainable in the long term than using the DSL that might not have all the tools available to you that SQL does. And so he kind of gives his reasoning about, like, this is what I recommend, and here's why it contributes to sustainability, in my opinion. And so I have found myself, while I'm reading along, either agreeing, like, oh yeah, I can see his reasoning here, or maybe even disagreeing because I might think about things differently or have other considerations in mind that are more important to me and what sustainability means to me. But what I hopefully want to take away from the framework or understanding of values is evaluating technical decisions that I make based on my values as an individual but, more importantly, the values of the team or organization. JOËL: I love mental frameworks like that that give you clarity into your own thought processes or how you make decisions moving forward. Sometimes you can look at something that's very concrete. Somebody gives you some advice on maybe structuring your database schema, and that might be helpful in and of itself. But if you came away with a larger thought process, I think that's doubly valuable. As an aside here, I love this approach to writing where he sort of lays down almost like preconditions for this book. If you don't agree on these values, this book is not going to be very helpful for you. And then also, here are situations where this advice is not going to apply. Now that I've put down all these edge cases for the rest of this book, I'm going to be speaking very decisively; these are the things I recommend and not have to caveat myself all the time. It's like, yes, I know there are some edge cases where you might not want to do this if it's a one-off script or whatever it is. We've already dealt with all of those upfront. And now, I can be very confident and very direct for the whole rest of the book. And I feel like that's something I struggle with in some of my work sometimes is. I care a lot about nuance, and my audience probably cares about edge cases even more than I do. They probably care too much. Because I say something that's generally true most of the time, and I know somebody's already thinking about the one edge case where that's not true. And that doesn't matter for the main point I'm trying to make. So it's always a struggle to know when to caveat a statement that I'm making. But if you caveat too much, then you undermine your whole point. And so I like this idea of putting some caveats up front and then just saying, like, now we're in the 80% case. Within the 80% case, these are things I think are true. STEPHANIE: Yeah, that's a really good point. I agree he is very clear about the intended audience. And so when you read this book, you are either on board because you value the same things he does, or you're not because you are focused and your goals are things that are different from him. So I think it was really helpful to get on the same page, even in a piece of content or in a piece of writing. Because I want to use my time well as a reader, so I want to make sure that what I am consuming makes sense for me, and I will find it worthwhile. David takes a really strong stance on what quality means. And even though that is a pretty subjective value, he describes it as doing things right the first time and acknowledging the reality that we likely won't have the time to go back and clean things up after they've been shipped. So, on this client project, I found myself wanting to refactor things as part of my process, suggesting different implementations to do things the quote, unquote, "right way," or the best way we could, and not everyone shared that sentiment. I sometimes got pushback, and that was challenging for me to figure out how I wanted to navigate that situation and what I was willing to let go and what I wasn't. And so I'm curious if you've ever been in a consulting position like that where maybe the team and organization's values were a little bit different from your understanding, or if they just weren't clear at all, and you were driving towards something that seemed very nebulous. JOËL: I think I've been on both sides of that, both sometimes saying, "Look, we need to maybe slow down," or "Here's a thing that we need to do otherwise that's going to cost us on the longer term. Here's an area where we need to invest in quality today." And sort of on the other side where I'll feel like someone is really pushing an overengineered solution claiming it's going to make life a whole lot better, "If we invest three months upfront today, and maybe in three or four years, it'll pay off if certain things happen," that don't really necessarily line up with the immediate goals. A lot of this, I think, comes down to understanding the client, and their business, and their goals. Sometimes there is a really important deadline for something that has to happen based on an event in the real world. If you were building software for something that had to do with, let's say, the World Cup, you don't want it shipping in January 2023. That's just pointless. And so you've got to prioritize shipping things. And sometimes you say, "Okay, well, do we ship a few broken things? Or do we prefer to ship something that's a little bit smaller, more tightly scoped, but that holds well together?" That again, you have to really understand the client, their business, their needs. So I think for me those values of sustainability, quality...I forget what the third one was that you'd mentioned. STEPHANIE: Consistency. JOËL: Consistency, yes. They all sort of inform how it's going to mesh with the product I'm working on, the goals of that product. Where's it going in the next three months, six months, 12 months? Where's it coming from? Who's the team that I'm working with? Am I with a team of 300 people that are just committing to the main branch all the time with no tests, and we're constantly fighting regressions? Then sustainability looks very different there than a one other-person team, and we're trying to ship something for the World Cup. STEPHANIE: Oh yeah, I have a lot of thoughts there too. Because I do agree that it can look different and sometimes shift a little bit depending on the situation. What you were just describing about team makeup that is really interesting to me because, yeah, sustainability can look different for different teams. If you have, let's say, a lot of earlier career developers on your team, maybe you really want to focus on readability and making sure that they're able to navigate the codebase and figure things out over something like more advanced patterns and skills that will just cause them friction. But maybe you have a team where you all agree that that's what sustainability means to you is choosing those more advanced technical patterns and committing to them and figuring out how to maintain that because it's important to you. And the other thing that you brought up that is also mentioned in this book is that the more information developers have about the future and direction of the business, the better code we can write. For some reason, I've found myself in situations where I don't know all too much about what we are working towards or what the goals of the business are both in the short term and the long term. And I try to make the best guess I can. But I think in those scenarios, at least moving forward, I would really like to be better about pushing product folks or leadership to explain to me why we're doing what we're doing, kind of share the information that they have so that we can build the best product that we can. I think sometimes that information doesn't get shared for some reason. They kind of think that engineers are going to go do their engineer thing, and we'll focus on long-term strategy over here. But yeah, I truly believe that the more information we have, the better quality work we can produce. JOËL: I 100% agree. And I think that's what we see in a lot of classic agile literature talking about things like cross-functional teams or even the client or the product team should be integrated with the development team. You're all one team working together rather than someone has an idea, and then the technical team executes on it. We see that also in some of the domain-driven design literature as well, where oftentimes projects start, and you sit down with a subject matter expert, and they just walk you through all of the business aspects. And particularly for the purpose of domain-driven design, you talk about a lot of the terms that make sense for the business. You build up a glossary of terms. I think they call it a ubiquitous language of things that are specific to your business and how does that work on a day-to-day basis. STEPHANIE: Do you have any strategies for getting more clarity around the work and why you're building it if it's not yet available to you? JOËL: I think there are sort of two scenarios where you have to do that; one of them that comes up maybe more often for us as consultants is onboarding onto a new client. There's a whole new business that we may know nothing about, and we have to learn a lot of that. And so, as part of the onboarding process, I think it's really valuable to have conversations with people who are not part of the dev team to learn about the business side of things. On a per-feature basis, if you've already been onboarded on a project, you've been there for a while, it's often good to go back to the person who maybe created a ticket, a product person who's asking for a feature, and ask, "Why? Why do you want this?" Ideally, maybe that's even part of the ticket-creating process because the two teams are more integrated, and product team is like, here's a problem we're trying to solve. Here's what we think would be a solution. Or maybe even just "Here's a business problem. We need a technical solution. Can you do that for us?" But I've often followed up with people outside of the engineering team to ask follow-up questions. And why are we doing this? And sometimes it's even you have to do like five Whys where it's like, "Oh, we're doing this because we need to do this thing for this customer. They asked for it." And it's like, "Okay, well, why are they asking for that?" "Oh, it's because they have this problem." And why are they having this problem?" And eventually, like, "Oh, I see. Okay." The real solution has nothing to do with what was asked, and you come up with something that's maybe much tighter scoped or will better solve, and everybody's a winner in that case. But it does require following up. So I guess the short and boring answer is talk to people outside the engineering team. STEPHANIE: That's a great point. I think the questions that we as engineers ask can drive more clarity to product people as well if we continue to ask those five levels of why in ways that they maybe didn't think about either. We have the opportunity to do that if we want to do our work well, too. That's kind of exciting to me that it isn't just okay, we're handed some work to do, and they've done all of that strategic thinking separately. And having to implement those details, we can kind of start to chip away at what are we really doing here? And you mentioned talking to people outside of the engineering team. I just was thinking that pairing with non-developers would also be a really great task to do, especially when you get a ticket that's a bit ambiguous and you have questions. And you can always comment on the ticket or whatever and ask your questions. But perhaps there's also a good opportunity to work things through synchronously. In some ways, I think that is a more natural opportunity for that conversation to evolve rather than it being like, okay, I answered these questions, and now I'm going to move on to whatever else I have to do. JOËL: So you mentioned pairing. It's often good to have someone maybe outside the development team pair with you on a technical thing, but sometimes it's good to flip the script. If you're building especially software for an internal team, it can be really valuable to just shadow one of them for a couple of hours or a day. I did a project where we were building a tool for an internal sales team. And I had the privilege to shadow a couple of the sales members for a few hours as they're just doing their job. And I'm just asking all the questions like, "Oh, why do you do it that way? And what is the purpose behind this?" And I learned so much about the business by doing that. STEPHANIE: I love that we took this idea of sustainable development and went beyond just technical design decisions or aspects of how we do our jobs. Because there is so much more that we can do to foster the value of sustainability or whatever other values that you might have, and yeah, I feel really excited to try both these technical strategies from the book and also the collaborative aspects as well. JOËL: I'm really excited about some of these ideas that are coming up from the book. I think today we basically just talked about the introduction, the idea of sustainability. But I think as maybe you read more in the book, maybe we can do another episode later on talking about some of the more specific technical recommendations, how they relate to sustainability and maybe share some of our thoughts on that. STEPHANIE: Yeah, I definitely am excited to keep y'all updated on this journey. [laughs] JOËL: On that note, shall we wrap up? STEPHANIE: Let's wrap up. JOËL: Show notes for this episode can be found at bikeshed.fm. This show has been produced and edited by Mandy Moore. If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. If you have any feedback, you can reach us at @_bikeshed or reach me at @joelquen on Twitter. Or at hosts@bikeshed.fm via email. Thank you so much for listening to The Bike Shed, and we'll see you next week. Byeeeeeeee!!!!!!!! ANNOUNCER: This podcast is brought to you by thoughtbot, your expert strategy, design, development, and product management partner. We bring digital products from idea to success and teach you how because we care. Learn more at thoughtbot.com.

The Bike Shed
367: Value Objects

The Bike Shed

Play Episode Listen Later Jan 17, 2023 34:00


Joël's been traveling. Stephanie's working on professional development. She's also keeping up a little bit more with Ruby news and community news in general and saw that Ruby 3.2 introduced a new class called data to its core library for the use case of creating simple value objects. This episode is brought to you by Airbrake (https://airbrake.io/?utm_campaign=Q3_2022%3A%20Bike%20Shed%20Podcast%20Ad&utm_source=Bike%20Shed&utm_medium=website). Visit Frictionless error monitoring and performance insight for your app stack. Maggie Appleton's Tools for Thought (https://maggieappleton.com/tools-for-thought) Episode on note-taking with Amanda Beiner (https://www.bikeshed.fm/357) Obsidian (https://obsidian.md/) Zettelkasten (https://zettelkasten.de/posts/overview/) Evergreen notes (https://notes.andymatuschak.org/Evergreen_notes) New Data class (https://ruby-doc.org/3.2.0/Data.html) Joël's article on value objects (https://thoughtbot.com/blog/value-object-semantics-in-ruby) Episode on specialized vocabulary (https://www.bikeshed.fm/356) Primitive Obsession (https://wiki.c2.com/?PrimitiveObsession) Transcript: AD: thoughtbot is thrilled to announce our own incubator launching this year. If you are a non-technical founding team with a business idea that involves a web or mobile app, we encourage you to apply for our eight-week program. We'll help you move forward with confidence in your team, your product vision, and a roadmap for getting you there. Learn more and apply at tbot.io/incubator. STEPHANIE: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Stephanie Minn. JOËL: And I'm Joël Quenneville. And together, we're here to share a little bit of what we've learned along the way. STEPHANIE: So, Joël, what's new in your world? JOËL: I've been traveling for the past few weeks in Europe. I just recently got back to the U.S. and have just gotten used to drinking American-style drip coffee again after having espresso every day for a few weeks. And it's been an adjustment. STEPHANIE: I bet. I think that it's such a downgrade compared to European espresso. I remember when I was in Italy, I also would really enjoy espresso every day at a local cafe and just be like sitting outside drinking it. And it was very delightful. JOËL: They're very different experiences. I have to say I do enjoy just holding a hot mug and sort of sipping on it for a long time. It's also a lot weaker. You wouldn't want to do a full hot mug of espresso. That would just be way too intense. But yeah, I think both experiences are enjoyable. They're just different. STEPHANIE: Yeah. So, that first day with your measly drip coffee and your jet lag, how are you doing on your first day back at work? JOËL: I did pretty good. I think part of the fun of coming back to the U.S. from Europe is that the jet lag makes me a very productive morning person for a week. Normally, I'm a little bit more of an evening person. So I get to get a bit of an alter ego for a week, and that helps me to transition back into work. STEPHANIE: Nice. JOËL: So you've also been on break and have started work again. How are you feeling productivity-wise, kicking off the New Year? STEPHANIE: I'm actually unbooked this week and the last week too. So I'm not working on client projects, but I am having a lot of time to work on just professional development. And usually, during this downtime, I also like to reassess just how I'm working, and lately, what that has meant for me is changing my note-taking process. And I'm really excited to share this with you because I know that you have talked about this on the show before, I think in a previous episode with a guest, Amanda Beiner. And I listened to that episode, and I was really inspired because I was feeling like I didn't have a note-taking system that worked super well for me. But you all talked about some tools you used and some, I guess, philosophies around note-taking that like I said, I was really inspired by. And so I hopped on board the Obsidian train. And I'm really excited to share with you my experience with it. So I really like it because I previously was taking notes in my editor under the impression that, oh, like, everything is in one place. It'll be like a seamless transition from code to note-taking. And I was already writing in Markdown. But I actually didn't like it that much because I found it kind of distracting to have code things kind of around. And if I was navigating files or something, something work or code-related might come up, and that ended up being a bit distracting for me. But I know that that works really well for some people; a coworker of ours, Aji, I know that he takes his notes in Vim and has a really fancy setup for that. And so I thought maybe that's what I wanted, but it turns out that what I wanted was actually more of a boundary between code and notes. And so, I was assessing different note-taking and knowledge management software. And I have been really enjoying Obsidian because it also has quite a bit of community support. So I've installed a few plugins for just quality-of-life features like snippets which I had in my editor, and now I get to have in Obsidian. I also installed things like Natural Language Dates. So for my running to-do list, I can just do a shortcut for today, and it'll autofill today's date, which, I don't know, because for me, [laughs] that is just a little bit less mental work that I have to do to remember the date. And yeah, I've been really liking it. I haven't even fully explored backlinking, and that connectivity aspect, which I know is a core feature, but it's been working well for me so far. JOËL: That's really exciting. I love notes and note-taking and the ways that we can use those to make our lives better as developers and as human beings. Do you have a particular system or way you've approached that? Because I know for me, I probably looked at Obsidian for six months before I kind of had the courage to download it because I didn't want to go into it and not have a way to organize things. I was like; I don't want to just throw random notes in here. I want to have a system. That might just be me. But did you just kind of jump into it and see, like, oh, a system will emerge? Did you have a particular philosophy going in? How are you approaching taking notes there? STEPHANIE: That's definitely a you thing because I've definitely had the opposite experience [laughs] where I'm just like, oh, I've downloaded this thing. I'm going to start typing notes and see what happens. I have never really had a good organizational system, which I think is fine for me. I was really leaning on pen and paper notes for a while, and I still have a certain use case for them. Because I find that when I'm in meetings or one-on-ones and taking notes, I don't actually like to have my hands on the keyboard because of distractions. Like I mentioned earlier, it's really easy for me to, like, oh, accidentally Command-Tab and open Slack and be like, oh, someone posted something new in Slack; let me go read this. And I'm not giving the meeting or the person I'm talking to my full attention, and I really didn't like that. So I still do pen and paper for things where I want to make sure that I'm not getting distracted. And then, I will transfer any gems from those notes to Obsidian if I find that they are worth putting in a place where I do have a little bit more discoverability and eventually maybe kind of adding on to my process of using those backlinks and connecting thoughts like that. So, so far, it's truly just a list of separate little pages of notes, and yeah, we'll see how it goes. I'm curious what your system for organizing is or if you have kind of figured out something that works well for you. JOËL: So my approach focuses very heavily on the backlinks. It's loosely inspired by two similar systems of organization called Zettelkasten and evergreen notes. The idea is that you create notes that are ideas. Typically, the title is like a thesis statement, and you keep them very short, focused on a single thing. And if you have a more complex idea, it probably breaks down into two or three, and then you link them to each other as makes sense. So you create a web of these atomic ideas that are highly interconnected with each other. And then later on, because I use this a lot for either creating content in the future or to help refine my thinking on various software topics, so later on, I can go through and maybe connect three or four things I didn't realize connected together. Or if I'm writing an article or a talk, maybe find three or four of these ideas that I generated at very different moments, but now they're connected. And I can make an article or a talk out of them. So that's sort of the purpose that I use them for and how I've organized things for myself. STEPHANIE: I think that's a really interesting topic because while I was assessing different software for note-taking and, like I said, knowledge management, I discovered this blog post by Maggie Appleton that was super interesting because she is talking about the term tools of thought which a lot of these different software kind of leveraged in their marketing copy as like, oh, this software will be like the key to evolving your thinking and help you expand making connections, like you mentioned, in ways that you weren't able to before. And was very obviously trying to upsell you on this product, and she -- JOËL: It's over the top. STEPHANIE: A little bit, a little bit. So in this article, I liked that she took a critical lens to that idea and rooted her article in history and gave examples of a bunch of different things in human history that also evolved the ways humans were able to express their thoughts and solve problems. And so some of the ones that she listed were like storytelling and oral tradition. Literally, the written language obviously [laughs] empowered humans to be able to communicate and think in ways that we never were before but also drawings, and maps, and spreadsheets. So I thought that was really cool because she was basically saying that tools of thought don't need to be digital, and people claiming that these software, you know, are the new way to think or whatever, it's like, the way we're thinking now, but we also have this long history of using and developing different things that helped us communicate with each other and think about stuff. JOËL: I think that's something that appealed to me when I was looking at some of these note-taking systems. Zettelkasten, in particular, predates digital technology. The original system was built on note cards, and the digital stuff just made it a little bit easier. But I think also when I was reading about these ideas of keeping ideas small and linking them together, I realized that's already kind of how I tend to organize information when I just hold it in my brain or even when I try to do something like a tweet thread on Twitter where I'll try to break it up. It might be a larger, more complex idea, but each tweet, I try to get it to kind of stand on its own to make it easier to retweet and all that. And so it becomes a chain of related ideas that maybe build up to something, but each idea stands on its own. And that's kind of how in these systems notes end up working. And they're in a way that you can kind of remix them with each other. So it's not just a linear chain like you would have on Twitter. STEPHANIE: Yeah, I remember you all in that episode about note-taking with Amanda talked about the value of having an atomic piece of information in every note that you write. And since then, I've been trying to do that more because, especially when I was doing pen and paper, I would just write very loose, messy thoughts down. And I would just think that maybe I would come back to them one day and try to figure out, like, oh, what did I say here, and can I apply it to something? But it's kind of like doing any kind of refactoring or whatever. It's like, in that moment, you have the most context about what you just wrote down or created. And so I've been a little more intentional about trying to take that thought to its logical end, and then hopefully, it will provide value later. What you were saying about the connectivity I also wanted to kind of touch on a little bit further because I've realized that for me, a lot of the connection-making happens during times where I'm not very actively trying to think, or reflect, or do a lot of deep work, if you will. Because lately, I've been having a lot of revelations in the shower, or while I'm trying to fall asleep, or just other kinds of meditative activity. And I'm just coming to terms with that's just how my brain works. And doing those kinds of activities has value for me because it's like something is clearly going on in my brain. And I definitely want to just honor that's how it works for me. JOËL: I had a great conversation recently with another colleague about the gift of boredom and how that can impact our work and what we think about, and our creativity. That was really great. Sometimes it's important to give ourselves a little bit more blank space in our lives. And counter-intuitively, it can make us more productive, even though we're not scheduling ourselves to be productive. STEPHANIE: Yes, I wholeheartedly agree with that. I think a lot about the feeling of boredom, and for me, that is like the middle of summer break when you're still in school and you just had no obligations whatsoever. And you could just do whatever you wanted and could just laze around and be bored. But letting your mind wander during those times is something I really miss. And sometimes, when I do experience that feeling, I get a little bit anxious. I'm like, oh, I could be doing something else. There's whatever endless list of chores or things that are, quote, unquote, "productive." But yeah, I really like how you mentioned that there is value in that experience, and it can feel really indulgent, but that can be good too. MID-ROLL AD: Debugging errors can be a developer's worst nightmare...but it doesn't have to be. Airbrake is an award-winning error monitoring, performance, and deployment tracking tool created by developers for developers that can actually help cut your debugging time in half. So why do developers love Airbrake? It has all of the information that web developers need to monitor their application - including error management, performance insights, and deploy tracking! Airbrake's debugging tool catches all of your project errors, intelligently groups them, and points you to the issue in the code so you can quickly fix the bug before customers are impacted. In addition to stellar error monitoring, Airbrake's lightweight APM helps developers to track the performance and availability of their application through metrics like HTTP requests, response times, error occurrences, and user satisfaction. Finally, Airbrake Deploy Tracking helps developers track trends, fix bad deploys, and improve code quality. Since 2008, Airbrake has been a staple in the Ruby community and has grown to cover all major programming languages. Airbrake seamlessly integrates with your favorite apps to include modern features like single sign-on and SDK-based installation. From testing to production, Airbrake notifiers have your back. Your time is valuable, so why waste it combing through logs, waiting for user reports, or retrofitting other tools to monitor your application? You literally have nothing to lose. Head on over to airbrake.io/try/bikeshed to create your FREE developer account today! JOËL: So you mentioned recently that you've had a lot of revelations or new ideas that have come upon you or that you've been able to dig into a little bit more. Is there one you'd like to share with the audience? STEPHANIE: Yeah. So during this downtime that I've had not working on client work, I have been able to keep up a little bit more with Ruby news or just community news in general. And in, I think, an edition of Ruby Weekly, I saw that Ruby 3.2 introduced this new class called data to its core library for the use case of creating simple value objects. And I was really excited about this new feature because I remembered that you had written a thoughtbot blog post about value objects back in the summer that I had reviewed. That was an opportunity that I could make a connection between something happening in recent news with some thoughts that I had about this topic a few months ago. But basically, this new class can be used over something like a struct to create objects that are immutable in their values, which is a big improvement if you are trying to follow value objects semantics. JOËL: So, I have not played around with the new data class. How is it different from the existing struct that we have in Ruby? STEPHANIE: So I think I might actually answer that first by saying how they're similar, which is that they are both vehicles for holding pieces of data. So we've, in the past, been able to use a struct to very cheaply and easily create a new class that has attributes. But one pitfall of using a struct when you're trying to implement something like a value object is that structs also came with writer methods for all of its members. And so you could change the value of a member, and that it kind of inherently goes against the semantics of a value object because, ideally, they're immutable. And so, with the data class, it doesn't offer writer methods essentially. And I think that it freezes the instance as well in the constructor. And so even if you tried to add writer methods, you would eventually get an error. JOËL: That's really convenient. I think that may be an area where I've been a little bit frustrated with structs in the past, which is that they can be modified. They basically get treated as if they're hashes with a slightly nicer syntax to interact with them. And I want slightly harder boundaries around the data. Particularly when I'm using them as value objects, I generally don't want people to modify them because that might lead to some weird bugs in the code where you've got a, I don't know, something represents a time value or a date value or something, and you're trying to do math on it. And instead of giving you a new time or date, value just modifies the first one. And so now your start date is in the past or something because you happen to subtract a time from it to do a calculation. And you can't assign it to a variable anywhere. STEPHANIE: Yeah, for sure. Another kind of pitfall I remember noticing about structs were that the struct class includes the enumerable module, which makes a struct kind of like a collection. Whereas if you are using it for a value object, that's maybe not what you want. So there was a bit of discourse about whether or not the data class should inherit from struct. And I think they landed on it not inheriting because then you can draw a line in the sand and have that stricter enforcement of saying like, this is what a data as value object should be, and this is what it should not be. So I found that pretty valuable too. JOËL: I think I've heard people talk about sort of two classes of problems that are typically solved with a struct; one is something like a value object where you probably don't want it to be writable. You probably don't want it to be enumerable. And it sounds like data now takes on that role very nicely. The other category of problem is that you have just a hash, and you're trying to incrementally migrate it over to some nicer objects in some kind of domain. And struct actually gives you this really nice intermediate phase where it still mostly behaves like a hash if you needed to, but it also behaves like an object. And it can help you incrementally transition away from just a giant hash into something that's a little bit more programmatic. STEPHANIE: Yeah, that's a really good point. I think struct will still be a very viable option for that second category that you described. But having this new data class could be a good middle ground before you extract something into its own class because it better encapsulates the idea of a value object. And one thing that I remember was really interesting about the article that you wrote was that sometimes people forget to implement certain methods when they're writing their own custom value objects. And these come a bit more out of the box with data and just provide a bit more like...what's the word I'm looking for? I'm looking for...you know when you're bowling, and you have those bumpers, I guess? [laughs] JOËL: Uh-huh. STEPHANIE: They provide just like safeguards, I guess, for following semantics around value objects that I thought was really important because it's creating an artifact for this concept that didn't exist. JOËL: And to recap for the audience here, the difference is in how objects are compared for equality. So value objects, if they have the same internal value, even if they're separate objects in memory, should be considered equal. That's how numbers work. That's how hashes work. Generally, primitives in Ruby behave this way. And structs behave that way, and the new data class, it sounds, also behaves that way. Whereas regular objects that you would make they compare based off of the identity of the object, not its value. So if you create two user instances, not ActiveRecord, but you could create a user class, you create two instances in memory. They both have the same attributes. They will be considered not equal to each other because they're not the same instance in memory, and that's fine for something more complex. But when you're dealing with value objects, it's important that two objects that represent the same thing, like a particular time for a unit of measure or something like that, if they have the same internal value, they must be the same. STEPHANIE: Right. So prior to the introduction of this class, that wasn't really enforced or codified anywhere. It was something that if you knew what a value object was, you could apply that concept to your code and make sure that the code you wrote was semantically aligned with this concept. And what was kind of exciting to me about the addition of this to the core class library in Ruby is that someone could discover this without having to know what a value object is like more formally. They might be able to see the use of a data class and be like, oh, let me look this up in the official Ruby docs. And then they could learn like, okay, here's what that means, and here's some rules for this concept in a way that, like I mentioned earlier, felt very implicit to me prior. So that, I don't know, was a really exciting new development in my eyes. JOËL: One of the first episodes that you and I recorded together was about the value of specific vocabulary. And I think part of what the Ruby team has done here is they've taken an implicit concept and given it a name. It's extracted, and it has a name now. And if you use it now, it's because you're doing this data thing, this value object thing. And now there's a documentation page. You can Google it. You can find it rather than just be wondering like, oh, why did someone use a struct in this way and not realize there are some implicit semantics that are different? Or wondering why did the override double equals on this custom class? STEPHANIE: Yeah, exactly. I think that the introduction of this class also provides a solution for something that you mentioned in that blog post, which was the idea of testing value objects. Because previously, when you did have to make sure that you implemented methods, those comparison methods to align with the concept of a value object, it was very easy to forget or just not know. And so you provided a potential solution of testing value objects via an RSpec shared example. And I remember thinking like, ooh, that was a really hot topic because we had also been debating about shared examples in general. But yeah, I was just thinking that now that it's part of the core library, I think, in some ways, that eliminates the need to test something that is using a data class anyway because we can rely a little bit more on that dependency. JOËL: Right? It's the built-in behavior now. Do you have any fun uses for value objects recently? STEPHANIE: I have not necessarily had to implement my own recently. But I do think that the next time I work with one or the next time I think that I might want to have something like a value object it will be a lot easier. And I'm just excited to play around with this and see how it will help solve any problem that might come up. So, Joël, do you have any ideas about when you might reach for a data object? JOËL: A lot of situations, I think, when you see the primitive obsession smell are a great use case for value objects, or maybe we should call them data objects now, now that this is part of Ruby's vocabulary. I think I often tend to; preemptively sounds bad, but a lot of times, I will try to be careful. Anytime I'm doing anything with raw numbers, magic strings, things like that, I'll try to encapsulate them into some sort of struct. Or even if it's like a pair of numbers, it always goes together, maybe a latitude and longitude. Now, those are a pair. Do I want to just be passing around a two-element array all the time or a hash that would probably make a very nice data object? If I have a unit of measure, some number that represents not just the abstract concept of three but specifically three miles or three minutes, then I might reach for something like a data class. STEPHANIE: Yeah, I think that's also true if you're doing any kind of arithmetic or, in general, trying to compare anything about two of the same things. That might be a good indicator as well that you could use something richer, like a value object, to make some of that code more readable, and you get some of those convenient methods for doing those comparisons. JOËL: Have you ever written code where you just have like some number in the code, and there's a comment afterwards that's like minutes or miles or something like that, just giving you the unit as a comment afterwards? STEPHANIE: Oh yeah. I've definitely seen some of that code. And yeah, I mean, now that you mentioned it, that's a great use case for what we're talking about, and it's definitely a code smell. JOËL: It can often be nice as you make these more domain concepts; maybe they start as a data object, but then they might grow with their own custom methods. And maybe you extend data the same way you could extend a struct, or maybe you create a custom class to the point where the user...whoever calls that object, doesn't really need to know or care about the particular unit, just like when you have duration value. If you have a duration object, you can do the math you want. You can do all the operations and don't have to know whether it is in milliseconds, or seconds, or minutes because it knows that internally and keeps all of the math straight as opposed to just holding on to what I've done before, which is you have some really big number somewhere. You have start is, or length is equal to some big number and then comment milliseconds. And then, hopefully, whoever does math on that number later remembers to do the division by 1,000 or whatever they need. STEPHANIE: I've certainly worked on code where we've tolerated those magic numbers for probably longer than we should have because maybe we did have the shared understanding that that value represents minutes or milliseconds or whatever, and that was just part of the domain knowledge. But you're right, like when you see them, and without a very clear label, all of that stuff is implied and is really not very friendly for someone coming along in the future. As well as, like you mentioned earlier, if you have to do math on it later to convert it to something else, that is also a red flag that you could use some kind of abstraction or something to represent this concept at a higher level but also be extensible to different forms, so a duration to represent different amounts of time or money to represent different values and different currencies, stuff like that. JOËL: Do you have a guideline that you follow as to when something starts being worth extracting into some kind of data object? STEPHANIE: I don't know if I have particularly clear guidelines, but I do remember feeling frustrated when I've had to test really complicated hashes or just primitives that are holding a lot of different pieces of information in a way that just is very unwieldy when you do have to write a test for it. And if those things were encapsulated in methods, that would have been a lot easier. And so I think that is a bit of a signal for me. Do you have any other guidelines or gut instincts around that? JOËL: We mentioned the comment that is the unit. That's probably a...I wasn't sure if I would have to call it a code smell, but I'm going to call it a code smell that tells you maybe you should...that value wants to be something a little bit more than just a number. I've gotten suspicious of just raw integers in general, not enough to say that I'm going to make all integers data objects now, but enough to make me pause and think a lot of times. What does this number represent? Should it be a data object? I think I also tend to default to try to do something like a data object when I'm dealing with API responses. You were talking about hashes and how they can be annoying to test. But also, when you're dealing with data coming back from a third-party API, a giant nested hash is not the most convenient thing to work with, both for the implementation but then also just for the readability of your code. I often try to have almost like a translation layer where very quickly I take the payload from a third-party service and turn it into some kind of object. STEPHANIE: Yeah, I think the data class docs itself has an example of using it for HTTP responses because I think the particular implementation doesn't even require it to have attributes. And so you can use it to just label something rather than requiring a value for it. JOËL: And that is one thing that is nice about something like a data object versus a hash is that a hash could have literally anything in it. And to a certain extent, a data object is self-documenting. So if I want to know I've gotten to a shopping cart object from a third-party API, what can I get out of the shopping cart? I can look at the data object. I can open the class and see here are the methods I can call. If it's just a hash, well, I guess I can try to either find the documentation for the API or try to make a real request and then inspect the hash at runtime. But there's not really any way to find out without actually executing the code. STEPHANIE: Yeah, that's totally fair. And what you said about self-documenting makes a lot of sense. And it's always preferable than that stray comment in the code. [laughs] JOËL: I'm really excited to use the data class in future Ruby 3.2 projects. So I'm really glad that you brought it up. I've not tried it myself, but I'm excited to use it in future projects. STEPHANIE: On that note, shall we wrap up? JOËL: Let's wrap up. STEPHANIE: Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeeeeeeeee!!!!!!!!!!!! ANNOUNCER: This podcast is brought to you by thoughtbot, your expert strategy, design, development, and product management partner. We bring digital products from idea to success and teach you how because we care. Learn more at thoughtbot.com.

The VBAC Link
TVL Holiday Special #3 Stephanie with My Essential Birth + Preparing Physically

The VBAC Link

Play Episode Listen Later Dec 19, 2022 43:31


For our final holiday special podcast episode, we want to help you feel as physically prepared as possible when going for your VBAC!Stephanie of My Essential Birth joins Meagan to share her wisdom from her own two VBAC births as well as what she has helped women learn through her many years as a birth worker. You will hear tips on how to choose and vet providers, three free exercises that might just make all the difference during your labor, and the secret lesson Stephanie has learned that she wants all of our listeners to know. Additional LinksStephanie's Website and CoursePregnancy and Birth Made Easy PodcastBebo Mia's WebinarHow to VBAC: The Ultimate Prep Course for ParentsFull Transcript under Episode DetailsFull TranscriptMeagan: Turn your love of babies and bellies into cash. If you love babies and bellies and want to provide care and support to families, then Bebo Mia's webinar is the right place for you. Get answers to those burning questions like how to be the voice you wish you had at your birth and how babies and families can be supported by doulas. Learn all about the different kinds of doulas. You can work in fertility, pregnancy, birth, postpartum, or just enjoy working with those squishy babies. Supporting families by becoming a birth worker, aka doula, is perhaps an option that hasn't even crossed your mind. That's why we want you to join this webinar. You can have great earning potential while doing something you love. Bebo Mia is the one-stop shop for education, community, and mentorship. Reserve your spot today at bebomia.com/freewebinar.Meagan: Hello, hello you guys. It is the end of the year. This is Meagan with The VBAC Link and I have another holiday edition for you. Today is one that I am so excited about because this is someone that I know personally. She's a dear friend of mine and we have taken similar journeys through our doula careers, so it's really fun to be with someone that I already know and that we have the same mindset and goals for all of you out there. This is Stephanie and she is amazing. So amazing. She is a mom and a doula. She's had a VBAC and she actually has an amazing course through My Essential Birth. That's correct, right? My Essential Birth? Stephanie: Yep. Meagan: It's a course on how to prepare and get ready for birth. She has the same drive, I feel like, and passion as I do to get the information out to all of you and to help you know what is best for you whether it be, again, scheduling a repeat Cesarean or having a VBAC or maybe you're a first-time mom and you just want to know how to go along the way, seriously, Stephanie is going to be that person for you. So I'm so excited today to have her on. Welcome, Steph. Stephanie: Thank you. That's quite an introduction. I love it. Come to my podcast. Do the same thing. Meagan: No, no seriously. I was going to say, she has a full-on introduction here too. But you are amazing. You are so amazing and I love what you have done with My Essential Birth. You're busy. You've got three kids. You've got three kids and something too that is really fun is every single birth has been so different which I think just broadens your knowledge and passion, even more, to do what you do because for me, my births were all so different and I don't know, I really don't know if I would be here today if I didn't have all of those births. Stephanie: Yeah, 100%. Yes. Meagan: Don't you feel like these experiences in our lives have brought us here today and have brought passion to our hearts? But yeah. On top of that, you homeschool. You do so many things. You wear so many hats, so I'm so grateful for you taking the time today to talk to us about all of the amazing things that you do. But I think one of the really cool things right off the bat is, let's talk about your VBACs and how you really got started in all of this. Stephanie: Yeah, I think you really hit the nail on the head because 100%, if I hadn't had the experiences with the births that I have had, I wouldn't have not only the passion but the knowledge from seeing things go wrong. It makes me think of when I was 16 and I got my first car and it was a piece of crap and everything broke down on it so I had to learn about things [inaudible]. Meagan: Yes. Stephanie: No, I'm not comparing my body to a car, but I will say that those experiences totally shaped the way that I do what I do today and the passion behind it. My first baby– now, mind you, in my head, this was my goal. I wanted to go unmedicated. It was what I wanted to do. I just wanted to have that experience for myself for no particular reason. That's just what I wanted to do. We got around 34-35 weeks and I was reading a birth story online. Mind you, this was 13, 14 years ago, so it was a little bit ago not like what we see today with birth stories and stuff, but I'm at work and bawling because I'm super pregnant. I'm like, “That's what I want my birth to be like,” so I researched the classes that kind of went along with this book and I reached out to some local birth educators. It was this 12-week series and I had four or five weeks left to go. There was this one lady that was like, “Okay, I'll do these intensive courses on the weekend if you could make it.” I'm over like, “My husband works every weekend. We're super broke.” She was going to do it for this bigger prize. I'm like, “It's fine. I'll wing it. It's going to be fine.”Fast forward to that birth and missing some red flags, things like my provider telling me when first of all, he didn't want to have the conversation until 36 weeks about what the birth was going to be like, so I told him early on, “I don't want to have an epidural. I want to go unmedicated.” He was like, “We don't talk about that until 36 weeks.” That was a red flag, but I didn't know any better. Meagan: Interesting, yeah. Because that's what they do. Stephanie: Uh-huh and I was like, “Okay. Sure.” Totally. He was super old school. There were a couple of things and just the way that he talked to me that I should have caught on, but when 36 weeks came and I said, “I really want to go unmedicated,” and whatever and he was talking about, “Well, I actually let my patients get their epidurals much earlier than others. Why be in pain?” And I'm like, “No, it's really important to me.” And then he continued with, “Well, women with size 5.5 shoes and smaller tend to have Cesarean births.” Now, mind you, I'm a small person. I'm 5'0”. My shoe size is 5.5 and I'm sitting there just, “You've got to be freaking kidding me,” because my grandmother who was 4'10”, and her grandmother. I'm just going down the line like, “Nobody would be here. What are we talking about?” But at the same time, I'm a new mom. It's my first birth. I'm scared, so I stayed with him, and anyways, the cascade of intervention that happened was my water broke with just a trickle. I didn't have contractions. The provider ended up telling me once I was at the hospital that I needed to have Pitocin and I say that because I remember asking the nurse, “Did he say that word need?”She was like, “I'll come back.” But she was like, “He said need.” So I said, “Okay, well then I must need Pitocin.” So we took Pitocin. That baby did not do well with it. He couldn't crank up the Pitocin enough to make the contraction strong enough to actually make labor progress because my baby's heart rate would drop. That was, in my opinion, a medically-caused Cesarean because yes, when I have a baby in distress, then there we are. So that was my first experience with birth. I didn't connect with my baby right away. On top of being a new mom and figuring out life, I had just had abdominal surgery. I was a mess of emotions and then the next two births are where I found some redemption and healing and passion and power for women's bodies and what we can do. During my second birth, we had moved overseas to Germany and I was meeting with a doctor. I'd met with an OB but it was actually midwives who you give birth with. I had taken a really good birth course and I had been practicing a lot of stuff. I did not understand a ton about positioning though for my baby and so I had two days of prodromal labor which is not that big of a deal. Two days of prodromal labor, then finally things kicked in and I was in full active labor, but then I had pushing contractions at 4 centimeters, so now, my doula brain goes, “Oh, it's a positional thing. I have all of these ideas,” but then, I was like, “Oh my gosh. I'm not going to make it.” And then too, the wonderful German nurse there– there was a little bit of a language barrier for sure, but I was like, “I really want to get into the water.” She was like, “Oh, later. And also, I have something, honey, that will take all of that away. You just let me know if you want a little bit. We'll just stick it in the bum. A little bit of pain meds.” At the time, I was like, “Yeah, that's a good idea. Let's try that.” But I had the pain meds. That ended up being like, I was comfortable before two contractions before my water broke. It took the edge off enough that my body was like, “Let's get things started,” but then the contractions were right back on. I did end up with an epidural for that birth. My baby did fine with the Pitocin. I pushed that baby out vaginally. I wasn't forced into another Cesarean or anything and that birth was amazing. I was very, very pleased with the way that that birth went. And then we were moving from Germany back to the United States, particularly to North Dakota. If you know anything about North Dakota, they don't even have– my midwife was not a licensed midwife on purpose. You cannot be a licensed midwife and deliver babies outside of a hospital setting. They can get arrested. Meagan: Yeah. Yeah. It's illegal. Stephanie: It's not the black market, but she's not licensed. She was a direct-entry midwife. So we were moving back from overseas to North Dakota and I called the hospital first before I met with a home birth midwife. They told me, “Well, we don't really care that you've had a vaginal birth after Cesarean. You had a Cesarean before, so you need to plan for another scheduled Cesarean birth,” so talk about my red flags now. Meagan: You're like, “Nope. Nope.” Stephanie: No way. I'm going to do whatever I have to do. So I did. I reached out to a home birth midwife. I found a doula and all of those things that I probably should have done with baby #1. We planned for me to have an unmedicated experience at home. I was really excited about that up until 35, 36 weeks. I had a breech baby for one and that breech baby, we were able to get him turned, so that part went away, but then it was the mental game of, “Can I actually do this? You've never not had an epidural.” All of that self-talk starts happening and it's not good. My doula was like, “Here's a list of affirmations. Take what you like. Leave the rest and start saying them out loud several times a day every day.” And so I did that and within a week or so, I was like, “Oh my gosh.” I went from being scared and nervous to confident and excited. I was like, “I can do this.” So that baby had a week of prodromal labor. It was about 5 or 6 days of prodromal labor and then things get moving and I have some active labor that hit, but my contractions never really got closer than about 6 minutes apart. They would last a minute to two minutes long, but they were never those super crazy close, consistent. Things kept going off in my head like, “If I was in the hospital, I definitely would have been offered a Cesarean birth.” It wouldn't have been a question, especially in that hospital. These contractions were coming. My midwife, we finally call her and I'm like, “Look. I've been in prodromal labor and now it's active labor, but they're not closer than 6 minutes.” She checks me and I'm 6 centimeters. I was like, “My labor is progressing on my own.” It was so cool. And then it was another 12 hours from that point and I had my baby. But it was incredible. Those contractions and just knowing that my body was doing what it was meant to do. There was a point where I was like, “Oh my gosh. I'm so tired. I need to sleep.” For sure, we went upstairs. I slept for 45 minutes. I had two contractions. It was another moment where I was like, “Yeah.” If I was at the hospital, somebody would say, “Oh, she's stalling. We've got to do something.” Whatever. But those two contractions and the second one, I woke up and I was like, “Oh my gosh, what is happening? I can't do this anymore.” Sure enough, I'm thinking, this better be transition. My midwife comes in. She had heard me. She was sleeping downstairs. She comes to the door. She's like, “Do you want me to check you?” I'm like, “Yes, please. Let's see where I'm at.” She's like, “You're 9.5 with a bouncy lip of cervix. You're good to go. Let's get you to go to the bathroom. You can get in the birth tub now.” So we did that and i can laugh about it now, but I went downstairs. I went to the bathroom and after I was done peeing, I had my first pushing contraction. I remember telling my husband, “I don't want to give birth on the toilet. I have to get out of here.” 4.5 hours later because of the mental blocks that I had– we can laugh about that now, but at the time, it was very serious. Like, “I'd better get to the birth tub.” Meagan: Yeah. I'd better get out of here. Stephanie: Yeah, but it was wonderful. I will tell you the differences. The major differences for me in the spaces that I was in for being able to give birth unmedicated and as a VBAC, my birth team made the biggest difference. When I was at home and feeling like, “Oh my gosh. I can't do this anymore. Oh my goodness. I've been pushing so long. I'm so tired,” everyone was like, “But you are doing it. You're doing great. Keep it up.” I'm like, “Oh. I can take that in and chill and feel supported.” So I did. We kind of joke about, first of all, I was making noises that my husband the next day told me, “You sound like the screaming goats.” I was like, “Oh my gosh. I do.”Meagan: I was called a cow. My husband was like, “You're a mooing cow in there.” I'm like, “Thank you so much.”Stephanie: Well, the best part of this story, I actually love this story, the next day, my husband is sitting at the table and showing our little boys the screaming goat video. His mom's walking down the stairs and goes, “You recorded her?!” Meagan: Uh-uh!Stephanie: So I'm like, “Okay, yeah. I get it. I get it. I really did sound like that.” Meagan: You really did sound like that. That is so funny. Stephanie: But anyways, I'm pushing all this time and I do remember hitting a point even during pushing, I'm like, “Oh my gosh. I can't do this.” I was scared. I had never pushed a baby out before. Instead of holding my breath and bearing down, I was purposely breathing through my nose and not leaning into that pushing. My husband was finally like or I told him, “You need to make the bed. I need to get out of the tub,” because in my head, all I'm thinking about was, “If I can't do this, then I'm going to have to go to the hospital. We're going to have to call an ambulance. The lights are going to be on. There's going to be people I don't know.” I had to walk myself through all of those things. Meagan: You were really deep in that space. Yeah. Stephanie: Yeah. I was like, “No. This has to happen here because I can't deal with all of that.” So I told my husband, “Go upstairs. Make the bed.” I was like, “Make sure you get the lining down so we don't mess up the mattress and all of that.” When he went upstairs, it was the first time that I paused and tuned into myself. I just said a quick prayer and for me, I call God Heavenly Father. “Heavenly Father, please. I can't do this alone. I'm scared.” My husband comes down the stairs. I'm just finishing that prayer. He's ready to lift me out of the water. He was like, “Come on. Let's go. Let's go now.” He went to lift me and I'm like, “No. It's happening.” Two pushes later, that baby was out. Meagan: Oh, that just gave me major chills. Stephanie: It was the most spiritual experience of my life. I love everything about it. Yes, it was probably one of the hardest things I've ever done physically. Mentally, how it pushes you to your limits, and then you feel like you are the strongest woman alive. You can do anything. You're a good mother. You're all of the things. It was that feeling and looking at what I had done through having good support that I was like, “No. We're lying to women. You know what? If I could do this, anyone can. So now I'm going to become a birth educator and now I”m going to work with women one-on-one. I know that you can do this.” So that's where the passion came from. Those were my birth stories. Meagan: I love it. I love it. Oh, that just gave me such chills. You know what's interesting is I don't think I've ever even heard all of your birth stories like that. Stephanie: Oh really? Meagan: I don't think I have. We have some similarities. We have some similarities. Stephanie: I know. I've read through some of yours too. I love it. Yeah. Meagan: Even more. I don't think I realized. Yeah, maybe I have and it was a long time ago and I forgot, but there are a lot of similarities. I love it. You've had these VBACs. You found this passion and here you are today. So in past episodes, we've talked about mentally preparing and mentally getting into that space. You just did that. You just talked about that which is so important. It is so crucial to be in that space because when we're out here, we can't dive into birth. I feel like I did the same thing. I wish that it was recorded so I could really show people how big of a tantrum I was throwing, but I was legitimately throwing a tantrum in my driveway pacing back and forth saying, “If my water wouldn't have just broken, this would be totally different. This is happening all over again.” I was really spiraling and everyone just sat there. My neighbor was seeing me. She was like, “Oh!” I'm like, “I'm in labor.” She stopped and was like, “Is she okay?” Rick was like, “She's just gonked or something right now.” I had her watching me. My mom was watching me. The kids were like, “Mom!” I'm throwing my hands and voicing everything that was in my head out loud getting it out there but I needed to do that. I needed to do that but as soon as I could get that out, I remember the drive. We were getting in the car to go to the birth center and meet my midwife. I had my baby later that night, but it was the morning before I had my baby and he was just like, “So, how did that feel?” I was like, “So good.” I just remember labor coming on so much stronger. You have to get in that head space. We know there is the headspace, but what about the physical? I feel like there is so much goodness that you talk about. The physical aspect of preparing for birth and not even just preparing to actually give birth, but preparing and creating that team and creating that environment. One of the first things is knowing your stuff. How can our listeners know their stuff? Right now, they are listening to this, so this is what you can do to know your stuff. But yeah. When you say ‘know your stuff', what would that all entail? What would you suggest?Stephanie: Yeah, this is kind of the tricky thing that I'm always weighing one thing against the other where it's knowing what you want for your birth and how to get there and then making sure that you're vetting your provider. They really do go hand in hand but it's really tricky because just depending on what order you take, you may have to change up one or the other. But when it comes to understanding what you need in order to have the birth that you desire, one of the things that I tell moms to do is, “Take a meditative moment. Close your eyes and take some deep breaths. Picture yourself from that very first contraction through to when you give birth. What does that look like? Where are you? Who is around you? What are the lights like? What do you smell? What do you see?”That will help you decide. It gives you some idea of how to get there or what you're going to need in order to get there. I'll do this exercise with moms and moms that were planning to give birth at a hospital but never make it there in their minds. They're at home. They don't ever get in the car to go to the hospital. They've had their baby at home. So I think really understanding what you are looking for. And even for a mom that has that experience, she's planning to give birth at a hospital, but she has this really calm, relaxing thing at home, it doesn't necessarily mean that she needs to be giving birth at home although it could, maybe it's more of, “So I need to have control over my body, control over the situation. I need to be in my own clothes,” and those sorts of things. Meagan: Oh, I love that you just said that. Stephanie: And really understanding what is creating that image in your mind. But of course, I'm going to talk about taking a good birth course because not only is that what I did that was so life-changing for me but that is what I help moms do today just like you have a birth course where you talk about preparing for VBAC. A good birth course is going to include all of those things like how to stay healthy and low-risk with nutrition, and good exercise that you can do not just moving your body and keeping your heart rate, but what are things positionally that you can do for yourself and your baby? How are you going to stretch the perineal area or use the specific muscles that are going to be used for birthing and labor time? That's going to be all the way through understanding each phase of labor, how to work with your birth partner, how they can support you, how relaxation can be so important and meditation, all the way through to birth and postpartum. That includes every situation that can happen on the way. When you walk into your birth space, are you going to have an IV or wear your own clothes? Do you want to have intermittent fetal monitoring or do you want to be on the monitor the whole time? If you're talking induction, what are your options? So I think really understanding what your options are, and some of that changes as your birth changes or as other options are provided whether or not you have gestational diabetes or if you're GBS positive. Those are different decisions you have to play with and make, but if you like listening to podcasts, taking a good birth course, watching birth videos, if you're gathering all of that information and coming together for yourself deciding what you want for yourself, then you can move into asking the right questions to help that provider because that really is the next step. You can have this wonderful birth that you have thought of and dreamed of in your mind and if your provider is not on the same page, if they are not supportive, you might not get it at all and it's not even your fault. Meagan: I know. That is so hard because sometimes we don't know what it looks like to have that supportive provider. We don't know what it looks like because for me, with my first birth, I went to my OB and he was really nice and welcoming, and charming. I was like, “Cool. He's rad. He's great,” and then there were the red flags but I didn't see those red flags. It's so hard to know how to find that provider and you say to vet your provider. What do you mean by vetting your provider and what tips would you give to start that process and know right away what you really want to look for? Stephanie: Yeah. I'm glad you asked that. I think probably one of the best things you can do is meet with more than one and different practices. Meagan: Yes. Yes. Different practices are such a big thing because even the one provider in the same practice, they're going to have similarities so it is so important to branch out. When I was going that with my VBAC baby, I did. I went to multiple people and I could physically feel the difference without even speaking to anybody. Stephanie: Yes. 100%. I always said that I didn't believe I was intuitive at all just as a person, I don't feel like I am in touch with myself. If that's you, you're wrong. Just like you explained right there, we do. You know when you have conversations with other people or you walk into a room. There's a feeling there and how you're treated matters. The problem is, I think and I mean, I'm guilty of it too. I think we put providers on this pedestal and they're kind of untouchable. They're above us in some way because they're gone to school and they've got knowledge about things that we don't. In some ways, maybe that's true. That's why we hire them because they have skills that we need that we can't meet while we are in our vulnerable state. The other side of that is that they are also a person and how they treat us matters. And so when you are asking questions and meeting with providers, how are you feeling? Were you respected? Were you rushed when you bring up something? Providers will actually eye roll or laugh at some of the things that you say. That's a red flag. Meagan: It's so true. Yes. Stephanie: I say too, you know what? Go meet with a birth center out-of-hospital provider. You don't have to plan on giving birth there at all. Pay attention to how you are treated. How does that feel for you? For people that are maybe interested in that and they are like, “Oh, that's so scary and my husband doesn't want to or my birth partner really doesn't want me out of the hospital,” great. Go take him and have a free interview with an out-of-hospital care provider and just see how you feel. If you hate it or it's not for you, then that's great but I think that you need to have the contrast. I think you deserve to have the contrast. It's the same with doulas. I'm like, “You don't know if you want a doula? Great. Go meet with one anyways. It's a free consult and then you can decide.” But vetting a provider, like I said, you have to have some questions going in. VBAC-specific moms, they're going to want to know things like, “Okay. For a mom like me, I'm healthy and low-risk. It's my second baby and I've only had one Cesarean birth. What does it look like for someone like me in your practice having a vaginal birth after a Cesarean? What are your percentage rates? Do you use the VBAC calculator or how do you decide? Do you induce? What are your reasons for induction and can I say no?” You always can but it's always fun to ask a provider, “Can I say no?” The answer should always be yes but it might not be. “We'll talk about it when we get there.” So you have to have some specific questions that you're bringing in to decide if this is somebody that you can handle and you are probably maybe not going to match up on every single thing. That's okay too, but are those big things being met? I think that's what helps you decide, “Is this going to be a good match for me or not?” Meagan: Yeah. I love that. And just tuning into your overall feeling. Like you said, providers can eye roll and they can be subtle. They can be subtle, really subtle, right? Even midwives can do that too. Stephanie: Oh totally, yes. Meagan: OBs, midwives, it's so important to really tune into that. I think it's so important to do that even before becoming pregnant too. Sometimes to find an OB—if you are thinking that you want to become pregnant soon and you have an OB or a midwife, start there. That's totally fine, but it's okay to branch out and say, “I'm not expecting yet. I'm preparing. I want to find that provider right from the beginning.” Sometimes that doesn't happen, but I think it's good to do if you can. I mean, I wasn't pregnant and I went to 12 providers. Stephanie: I love it. Meagan: 12 providers which were maybe excessive. Maybe, but that's what I needed. I needed to go and I needed to hear all of their things and feel all of that in those environments. I chose the provider that I thought was totally amazing. He still is. I'm not saying he's not, but for me, I thought he was perfect. He was exactly what I needed out of everybody and then I still changed at 24 weeks, right? And so a lot of people are like, “Why would you change? He's so supportive.” I'm like, “He is so supportive and I still feel all the good, but something is not resonating.” That's okay too. Even if you do find your provider. Say at your appointment, you find your provider and you're not feeling it or you're getting things like Stephanie where it's like, “Hey, this is what I want to do.” “We don't talk about that yet.” Those types of things, if they are not willing to hear you and they don't want to know how they can help you in this birth experience, are red flags. Don't feel like you have to stay like both Stephanie and I did because I felt like I had to stay too. I felt like I was cheating on my provider if I left him. He had gone this far with me. He had supported me this far, but at the same time, I truly believe I probably wouldn't have had that second Cesarean. I really don't believe that if I would have changed, but it's okay because it's my birth story and that's why I'm here, but it's okay. It's okay if you're feeling off and you want to change. It's okay to do that. Stephanie: Yeah. I think you can't shout that from the rooftops enough because it's true. You do feel like, “Oh, I'm going to hurt their feelings or something.” No, you're not and if you do, who cares? You're never going to see them again. Let it go. Meagan: Exactly. Stephanie: It's so important for you and your future. It's such an important moment for you. It doesn't matter. It should trump that. Meagan: It should trump that. Someone else's feelings. That's the hardest thing. We have so many people out there. If you are a people pleaser, you're not alone and it's easy to please your provider. You want to please your provider, but remember, they are working for you. They are there for you. If they're not pleasing you, it's okay to leave. It is okay to leave and so yeah. It's a hard thing to do, but I do encourage people to tune in, follow their hearts, tune into that and do what's best for them because if they don't truly vet their provider, it can make or break an experience. Stephanie: Yeah, it can. A good provider is going to help make it just like you said. My midwife and my doula who were in that third birth, oh my gosh. They are a part of my life forever whether they like it or not. You are bonded with those people forever and you need that kind of support in your life. Meagan: Right, yes. Yes. Okay, so we're talking about knowing your stuff and vetting your provider. Now, let's talk about putting in the work. We've got these things. Now, going for it. What things would you suggest? Stephanie: Yeah as far as putting in the work, I really recommend– and I have it on my website as well and you can tell me if you like these ideas or not, but I recommend these three exercises that you can do every day. First is the forward-leaning inversion. You're literally—you get up on a low-lying chair or couch probably with support. Put a pillow down in front of you. Get your elbows on the ground with your bum in the air and you hold that for three breaths. You do that once a day. If you're somebody who has heartburn or something, obviously, you're maybe going to want to not do that depending on how the heartburn is or there are a couple of people who shouldn't do that. Basically, that is really good because it releases certain ligaments. It allows more room for baby. It allows for really good positioning. That's something that you can do to make sure baby is in a good position. Meagan: Every day. Stephanie: Every day. An easier, more comfortable labor. The other thing you're going to do is pelvic tilts. You can choose to do how many you want, but I like to do them at least when I get up in the morning and before I go to bed. That's 20-40 tilts. That's in the hands-and-knees position. You're tilting your pelvis forward and into a flat back, forward and into a flat back. Again, that's strengthening certain areas. It's helping baby's position. Those are really, really good for you to be doing. The third one is the squat. This is a deep-seated squat. It's not like we are going to grab weights and do a weighted squat or anything like that. This is like how you see people in third-world countries who don't have chairs or new babies, toddlers when they go down to squat and play with something, look at that squat because that's the one that you are going for. The reason for that is because it stretches the perineal area. It strengthens the muscles in your legs. Chances are when it was pushing time, you're going to be in some kind of squat. Now maybe not, but chances are the majority of us are going to end up there. The other thing about squatting is that it shortens the birth canal, it makes it easier to be able to push baby out and that's why we end up in that position but if you're practicing that squat specifically, and this is where my husband was so good. “I'll tell you what, for every minute you squat for the day, I will give you a minute of massage at the end of the night.” I was like-- Meagan: Oh my gosh. Done. Done, done, done. Stephanie: An hour a night, I am not joking. So he was so good supporting me that way, but I'll tell you what, when I started squatting and it was probably later in my pregnancy like 34-35 weeks. When I started squatting, it was 1-2, maybe 3 minutes before my legs were numb, my feet hurt and I had to stand up. Everything was tingling, but a couple of weeks in, I could hold it for 15 minutes comfortably. So when I was telling you before that I was pushing for 4.5 hours, I was in a birth tub in a squatted position for that amount of time— Meagan: Wow. Stephanie: --and I remember thinking, “I'm so glad I practiced these squats because I wouldn't have had the stamina.” As far as physical prep, those are things that you can do every single day. Meagan: I love that. Stephanie: Thank you. I know and I'm like, you and I have taken some similar training and stuff. It's valid. It's real. Meagan: It really is. Stephanie: The other things that you can do are, let's stay healthy and low-risk. That means you're eating a high-protein diet. You're drinking a lot of water. You're taking your prenatals, well-balanced. That matters because it can keep things like preeclampsia at bay. It's also going to make you feel better and give you more energy, so there are a lot of benefits to that. But my favorite part of staying healthy and low-risk is that you remain in charge of your birth decisions. That's why it matters to me so much. It's not even just for the health of myself and my baby. It also comes down to, “I want to have a say as to how all of this goes.” So those are some of the physical things. Then we move into the, once I understand how birth works, what are the signs that I'm in labor? What are the signs I'm in active labor? How do I work with my body? Learning things like relaxation and I do that through relaxation practice. Even just a simple one, and you can do this with your birth partner or by yourself, but you set up this stage. So use your senses. You should be leaning back in a chair or in your bed lights dimmed with essential oil or a consistent smell that your body gets used to smell. You just practice breathing deep into your belly. Imagine how you breathe when you wake up in the morning. First thing, pay attention to how you breathe when your eyes first open. It's really deep belly breaths so try to aim for that. Do that for 10 minutes. Just go from your head to your toe and be like, “Okay. I'm going to feel the hairs on my head relax, and then my eyebrows, and then my jaw.” All the way down. The thing is, it's not easy to do when you're not used to relaxing but when you utilize all of those senses, then it becomes something called muscle memory. So if I know my body knows because I've been doing this for the last several months that every time the lights are dimmed and I smell lavender essential oil and I'm breathing into my belly, then when you do those things during labor, it's like, “Oh, lights are dimmed and lavender,” then you don't really have to think about it. Meagan: It's intuitive. Stephanie: Yes. “I'm supposed to relax now.” And then obviously you need to practice relaxation. Once you get good at that, you can practice it with the lights on, with the TV on, with your husband or kids walking through the room because that's the reality of birth and especially if you're in a hospital. Meagan: Yes, yes. Stephanie: But learning relaxation is really important. And then you move into—there's a lot more to do with that like meditation and the mental stuff and all of that. Labor rehearsal where you practice with ice and other things. There is plenty that you can do, but I would say relaxation, your three exercises, and staying healthy and low-risk are probably just top of the list things that you can do on a daily basis. Meagan: Oh my gosh. I love it. So good, so good. I love that you talked about preparing and then it becomes muscle memory. It's so true. It's so, so true. I encourage if you're ever in a moment where you're feeling stressed or overwhelmed to dive into that because there are going to be moments in labor and birth when you might feel stressed and overwhelmed. If you can practice doing that in those moments, oh my gosh. It's going to be so beneficial. So I know we're almost out of time, but I wanted to ask you what is a secret lesson or something no one really talks about that you wish you would have known ahead of time when preparing for time? Stephanie: That would be that you can say ‘no' to anything. I feel like I teach this all day long and I talk about it a lot. I don't know how often moms let that register because they will know that and then you'll get with their provider and they're doing non-stress tests or whatever and it's like, all of a sudden, oh crap. I need this and this and this. No. You can actually say ‘no' to literally anything. Meagan: Anything, yeah. Stephanie: Anything, yeah. They can't do anything. The best that they can do is make you sign, what is it? Meagan: An AMA. Stephanie: A medical release, yeah. AMA, against medical advice. Meagan: Against medical advice. Stephanie: Sign it. Sign it. It's your body. You get to choose. And then kind of like I talked about, when I talk about health and nutrition, I think a lot of times, moms don't register. “Okay, yeah. I get it. I'm supposed to be healthy.” But it's so you can be low-risk and in charge of your birth. I think that's a really important part of that. Meagan: Yes. I think so too. It's so hard. It's so hard to be in that moment and be like, “Uh, okay.” When you're like, “I really wanted to say no. I had a prenatal last night with a client and they were like, “One of the biggest things that we don't want to do is go in and just say yes to everything. That's one of their biggest goals is not to just say yes to everything. They're not saying, “We want to refuse everything,” they're just saying, “We want to be educated and we want to know what we're saying yes to.” It's so important to know. If you are saying yes, know why you are saying yes. And if not, it's okay to say no or “One moment. Let me think about it.” It's okay because there are times where things are going to be thrown at you and it is hard to say, “No” or actually, “I want more time” or “I'm not sure about that right now” but you can. You can. You have the right to say no. You have the right. So it's so important to know. I love that. Any last final tips for someone preparing for VBAC that you would like to give to our listeners? Stephanie: I think we've kind of touched on this before. It just really matters who you pick for your provider. I know we kind of talked about some things that warrant a red flag or time to interview somebody else or something, but really, if you've got that education and you've got that provider piece, you're setting yourself up for success. It should be somebody that supports you, not tolerates the opportunity to try for a VBAC, but somebody who believes in the natural process of birth and that having a vaginal birth after a Cesarean is more healthy and safer for mom and baby than having another abdominal surgery. I think that matters that you've got somebody that believes that way. Meagan: Totally. I love that. Oh, well thank you so much for being here with us today. I want you listeners to know that she has the three free, that's what you say, right? Stephanie: Yes, three free exercises. Meagan: Three free exercises. I'm having a hard time lately with tongue twisters. Three free exercises, so we are going to be providing that in our email. If you're not subscribed to our email, please check it out because we are going to be providing so many new things and some really exciting upcoming things with The VBAC Link are going to be happening. We are going to be providing that and then will you tell everybody where they can find you? Because everyone needs to know where you're at and follow you. Stephanie: Thank you, yes. So I too have a podcast. It is called Pregnancy and Birth Made Easy. Pregnancy and Birth Made Easy is the podcast so anywhere you listen to podcasts, you can take that in. I'm also on Instagram @myessentialbirth, Facebook, TikTok, all the things, and then if you are looking for information on the birth course or anything else in regards to where some of the podcast show notes and some of that live, it's myessentialbirth.com. Meagan: Yes and all of these will be listed in our show notes today so if you want to go follow her which I promise you that you do, go click that and give her a follow because her content is amazing. Her podcast is amazing and it's been such an honor to have you here today. Stephanie: Thank you, Meagan. I love what you do too and I love that we get to do this together. Meagan: Me too. Yeah, so before we let everyone go, I didn't really give a full, “Hey, we know each other,” but we actually were in the same doula course. We became doulas together which seems like forever ago, but it was so fun to be there and to learn. You had already had your VBACs, hadn't you? Stephanie: I did. Meagan: Yes and I hadn't yet. I had only had my two Cesareans and so I just remember you being so inspirational to me and motivating me. I was like, “Okay. She could do it. She's here. She is doing this too. We have the same interests,” and I just connected to you so much. Stephanie: Same, yeah. Well then, and now look at you with The VBAC Link. You just took off. I love it. Meagan: I love being here and I love being here with all of our listeners, so again, listeners, thank you so much for being here with us today, and thanks again, Steph. Stephanie: Thank you.ClosingWould you like to be a guest on the podcast? Tell us about your experience at thevbaclink.com/share. For more information on all things VBAC including online and in-person VBAC classes, The VBAC Link blog, and Meagan's bio, head over to thevbaclink.com. Congratulations on starting your journey of learning and discovery with The VBAC Link. Advertising Inquiries: https://redcircle.com/brandsPrivacy & Opt-Out: https://redcircle.com/privacy

The Bike Shed
365: Career Progression

The Bike Shed

Play Episode Listen Later Dec 13, 2022 37:55


Joël has been thinking a lot recently about array indexing. Stephanie started volunteering at the Chicago Tooele Library, a non-profit community lending library for Chicagoans to borrow tools and equipment for DIY home projects! It's the end of the year and often a time of reflection: looking back on the year and thinking about the next. Stephanie and Joël ponder if open source is a critical way to advance careers as software developers. This episode is brought to you by Airbrake (https://airbrake.io/?utm_campaign=Q3_2022%3A%20Bike%20Shed%20Podcast%20Ad&utm_source=Bike%20Shed&utm_medium=website). Visit Frictionless error monitoring and performance insight for your app stack. Chicago Tool Library (https://www.chicagotoollibrary.org/our-organization) Circulate and Ruby For Good (https://github.com/rubyforgood/circulate) Glue Work (https://noidea.dog/glue) Being the DRI of your career (https://cate.blog/2021/09/20/being-the-dri-of-your-career/) The Manager's Path (https://www.oreilly.com/library/view/the-managers-path/9781491973882/) Kingship (https://acoup.blog/2022/10/07/collections-teaching-paradox-crusader-kings-iii-part-iii-constructivisting-a-kingdom/) What technologies should I learn? (https://thoughtbot.com/blog/what-technologies-should-i-learn) Learning by Helping (https://thoughtbot.com/blog/learning-by-helping) "Comb-shaped" Careers (https://killalldefects.com/2020/02/22/specializing-vs-generalizing-careers/) Transcript: STEPHANIE: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Stephanie Minn. JOËL: And I'm Joël Quenneville. And together, we are here to share a little bit of what we've learned along the way. STEPHANIE: So, Joël, what's new in your world? JOËL: I've been thinking a lot recently about array indexing. I feel like this is one of the areas where you commonly get confused as a new programmer because most languages start array indexing at zero. And what we really have here are two counting systems, either an offset so how many spaces from the beginning of the array, or a counting system where you count 1,2,3,4. At first, it feels like why would computers ever go with the offset approach? It's so illogical. Counting 1,2,3,4 would feel natural. But then, the more I think about it, the more I've started seeing the zero-based pattern show up in everyday life. One example, because I enjoy reading history, is how we talk about centuries. You might talk about the 19th century is the Victorian age, roughly. But you might also refer to the 19th century as the 1800s. So we've kind of got these two names that are a little bit off by one. And that's because when you're counting the centuries, you count first century, second century, third century, fourth century, and so on. But when we actually go by the first two digits, you start with the zeros, then the 100s, then the 200s, 300s, and so on. And so we have a zero-based counting system and a one-based counting system, and we sort of have learned to navigate both simultaneously. So that was really interesting to me to make a connection between history and programming and the fact that sometimes we count from zero, and sometimes we count from one. STEPHANIE: Yeah, I will have to admit that I always get confused when we're talking about centuries and making the mental connection that 19th century is the 1800s. It always takes me a bit of an extra second to make sure I know what I'm hearing, and I'm attributing it to the right year. I think another example where I get a bit tripped up is the numbering of floors because, in the U.S., we are counting floors using the one-based counting system, whereas I think in Europe and places outside of North America, to my knowledge, the first floor will be considered the ground floor, and then the second floor will be the first floor and onward. So that is a zero-based counting system that I can recall. JOËL: I never noticed there was a pattern. I just thought every building was arbitrary in where it counted from. STEPHANIE: Yeah, I do think it's a cultural thing. I would be really curious to know more about the history of how those counting systems get adopted. JOËL: So that's a fun thing that I've been exploring recently. What's new in your world, Stephanie? STEPHANIE: I am really excited to talk about a new real-life update. I started volunteering at the Chicago Tooele Library, which is a non-profit community lending library in my city for Chicagoans to borrow tools and equipment for DIY home projects. What I really like about it is they use a pay-what-you-can model so everyone can have access to these resources. It reduces the need for people to buy new things all the time, especially for little one-off projects. And they also provide education to empower folks to learn how to do things themselves, which I thought was really cool. And another thing that I think might be a little relevant to this audience is that I actually first encountered the Tooele library through its open-source software, which is a Ruby for Good project called Circulate. So the Tooele Library had previously been using this software that was built by community members to do all of their lending. And I got to see it in action when I saw a librarian use it to rent out tools to community members. And then I also interfaced with it myself as a member of the Tooele Library. I've borrowed things like saws, cooking appliances like air fryers that they also had. And when I was first a guest on this show, I borrowed a microphone from them to do this podcast because I was just a guest at the time and didn't want to commit to buying a whole new microphone, so that was a really awesome way that I got to benefit from it. JOËL: It's a fantastic resource for the community. STEPHANIE: Yeah, I love it so much. If anyone is in Chicago and wants to check it out, I highly recommend it. And even if you're not in Chicago, if the idea of a lending library interests you, you can check out the software on Ruby for Good. And it's no longer being used by the Chicago Tooele Library, but it would be really cool to see it be picked up by other people who might want to start something similar in their own hometowns. JOËL: So you mentioned you're volunteering here. So this means you're going in person and helping people check out items from the library. STEPHANIE: Yeah, I did my first volunteer librarian shift about a month ago, and right now, they're in the middle of moving from one location to another, so they've had a lot of in-person workdays to get some of that done. But even before that, I had contributed a little bit to the open-source repo, which is just a pretty standard Rails project, so I felt super comfortable with getting my feet wet in it. And it was, I think, my first open-source contribution. I find that some of the other open-source software, especially developer tooling, is a little scary to get into. So this was a really accessible way for me to contribute to that community, just leveraging the skills that I have for my day-to-day work. JOËL: Would you recommend this project for our listeners who are looking to maybe get their own first contribution in open source? STEPHANIE: The Circulate project is actually on a bit of a hiatus right now. But I would definitely suggest people fork it and play around with it if they want to. I also know that Ruby for Good has a bunch of other projects that are Rails apps and have real users and are having an impact that way. So if anyone wants to get into open source in a way that feels accessible and they're building a product that people are using, I definitely recommend checking that out. MID-ROLL AD: Debugging errors can be a developer's worst nightmare...but it doesn't have to be. Airbrake is an award-winning error monitoring, performance, and deployment tracking tool created by developers for developers that can actually help cut your debugging time in half. So why do developers love Airbrake? It has all of the information that web developers need to monitor their application - including error management, performance insights, and deploy tracking! Airbrake's debugging tool catches all of your project errors, intelligently groups them, and points you to the issue in the code so you can quickly fix the bug before customers are impacted. In addition to stellar error monitoring, Airbrake's lightweight APM helps developers to track the performance and availability of their application through metrics like HTTP requests, response times, error occurrences, and user satisfaction. Finally, Airbrake Deploy Tracking helps developers track trends, fix bad deploys, and improve code quality. Since 2008, Airbrake has been a staple in the Ruby community and has grown to cover all major programming languages. Airbrake seamlessly integrates with your favorite apps to include modern features like single sign-on and SDK-based installation. From testing to production, Airbrake notifiers have your back. Your time is valuable, so why waste it combing through logs, waiting for user reports, or retrofitting other tools to monitor your application? You literally have nothing to lose. Head on over to airbrake.io/try/bikeshed to create your FREE developer account today! JOËL: So, as we're recording this, it's the end of the year. It's often a time of reflection and looking back on the year and maybe even thinking about the next year and progression. I'm curious since you said this was your introduction to the world of open source, do you think that working on open source is a critical way to advance our careers as software developers? STEPHANIE: That's a good question. Honestly, I think my answer would be, no, it's not critical. I think it's one avenue for people to explore and increase their impact on the community and increase their technical knowledge, especially if it's in an area that they are not quite working in in their day-to-day, but they're really interested in diving deeper in. But I do think there's sometimes a lot of pressure to feel like open source is this shining beacon of opportunity for you to dive into and that it'll bring a lot of meaning to the work that you do. And people, obviously, and for a good reason, talk about how special it is that open source is part of the industry that we work in, but I don't necessarily think it's critical. I do certainly feel inspired by people who create open-source tools or contribute to Ruby or Rails. But I don't necessarily think that it's something that should be a rule and that everyone needs to get into it or contribute to it. Because there are many ways that people can have an impact having influence on the community, and that way is one. But there's also a lot of value, even just focusing on the team that you're on and your company internally. JOËL: I appreciate the nuance there because I think like you said, we often view open source as the main thing that everyone should be doing to get ahead. And there are a lot of different ways to improve your skill and then to get ahead in your career, which are not always correlated. One kind of really basic way that I was shocked at how much it helped me was I was learning a new language, Elm. I joined their online Slack community and just hung out in the chat room and answered the most beginner questions because I barely knew the language at the time. And most of these could be found just by looking up the documentation or by opening up a REPL and experimenting with a thing and giving an answer, which are skills that, as a programmer who's got some experience, I take for granted but that not everyone has that as a reflex. Because Googling, searching documentation, crafting experiments in the REPL those are all skills that you have to learn to build over time. But answering those very basic questions over and over over the course of a few months actually taught me so much about the language, and I'm not doing anything fancy. STEPHANIE: That's awesome. I have a friend who, during a time when I think she was struggling with her confidence in her technical skill and was feeling a bit stuck at work, spent an afternoon answering Stack Overflow questions on basic Ruby and Rails, and that gave her a lot of joy. Because she recognized that she was the person Googling those questions and needing to find answers many years ago, and that was one way that she could pay it forward. And I think she had a lot of empathy, like I said, for those people who are needing a little help, and it felt really good for her to be able to provide it. JOËL: It's a way to have an impact on other people while also solidifying your own knowledge. STEPHANIE: Yeah, exactly. JOËL: So we've mentioned a couple of different ways where you can level up your skills, that might be through helping out other people online, that could be through open source. But I'd like to zoom out a little bit and look at not just improving your technical skills but thinking about career in general when you're looking out over the next 10, 20, 30 years. Do you have an approach that you like to take when you're thinking that broadly? STEPHANIE: For me, I have had trouble thinking about a five or 10-year plan because things often don't turn out the way that I envisioned them. And so I think I've come to realize that leaning into how I feel about things in any given moment is more valuable and oftentimes more accurate to what I really want. Because I can have an idea of what I want my career to look like, but the things that ring most true are what I'm feeling in the moment. And so you mentioned we're releasing this episode at the end of the year. I do tend to do a little bit of recap about how my year went if I spent it doing things that fulfilled me and made me feel good, if I grew in the ways that I wanted, even separate from any performance review. I know that this is a time of reflection for a lot of people. And I don't personally ascribe to New Year's resolutions, but I do like to think about themes or intentions. And those are things that ground me rather than setting particular goals that I may or may not achieve; I may realize I want to change. So yeah, I really recommend just sitting with yourself and spending time thinking about what you want, and that could mean a promotion, but that could also mean a more interesting project using new technology. It could mean more responsibility and decision-making power. It could mean a move into management. I think it's different for everyone. And so when people have asked me about advice or what they should do in terms of coming to a crossroads between jobs or between projects, I think that you really can't tell anyone else what is the right move for them; only they can decide. JOËL: And tech, it's such a broad field. There are so many different roles and paths you can take through it. Well, there's junior engineer, engineer one, engineer two, engineer three, that's just the same everywhere. And there's only one way forward; it's up or stagnation, and that's it. Like you really get to choose your own adventure in this industry, and that's exciting and maybe a little bit terrifying. STEPHANIE: Oh yeah, for sure. I like that you brought up the different levels and roles that you could have because I have found companies that provide a career ladder or engineering ladder that has been useful for me in the past in figuring out if the next step at the company that I'm at is what I want. And it's helpful. It's very clear to me, okay, these are the skills that I need to get promoted into this next level. But other times, that description describes something that I'm not interested in, and that is also really helpful information. JOËL: Was there ever a moment in your own career where you had to navigate some of these decisions to decide what path you wanted to take as opposed to just following a ladder up? STEPHANIE: Oh yeah. I was presented opportunities to start getting a feel for management or overseeing a team as a lead. And people had really great feedback for me that that was something that I had shown leadership in, and they thought I would do a great job in that role. But I actually decided to kind of hit the brakes a little bit on that particular route because what I realized I wanted at the time was to focus more on being an IC and deepening my technical knowledge. And that was really tough. I do also think that a lot of women are pushed into management because they end up doing a lot of the glue work that comes with unblocking people, supporting people, and project management and those are all skills that, like, quote, unquote, "lend themselves towards management." But just because we do that work doesn't necessarily mean that that's the direction that we want our careers to go in. And so that was a really tough thing that I had to do was to make it really clear that I wasn't quite ready for that yet. And I might be in the future, but in that moment, just standing my ground and being like, actually, I want to focus elsewhere instead. JOËL: That's really valuable, knowing yourself and knowing where you want to go, what the next step is. Are there any exercises you like to do to try to figure that out for yourself? Because I know something that I've struggled with sometimes is not being quite sure what I want. STEPHANIE: I journal a lot in my personal life and also about work. I think I tend to revisit that in my notes, especially about things I've learned or things that I felt excited about in terms of projects and what I've been unlearning, and just going through all of the things that I've collected over the year and synthesizing that information. I also really like to lean on my friends and peers. So I really enjoy a good one-on-one when we just talk about those types of things, you know, dreams, hopes, goals. I like to lean on my manager a lot, too, because oftentimes, they're able to see things about my work over the past year that maybe I was just too in the weeds to be able to have that higher level perspective about. As a third-party observer, they see a lot of things that you might not be able to, either on your current project or even opportunities for you to step into at a higher level in the company. So yeah, I think that, in some ways, it's a solitary activity, but it doesn't always have to be. JOËL: I remember having a really good conversation with my manager as well, at some point, talking about that decision of am I interested in maybe moving into the management track? Do I want to stay on the IC side of things? And that was a really good conversation to have. STEPHANIE: So after having those conversations and kind of figuring out what direction you wanted to go, were there times when you had to actively make that choice or advocate for yourself? JOËL: Yes. One of the things that I realized that I care about is investing in other people, and sort of the mentoring, supporting side of things which you might think is kind of a management activity. But management is a little bit different than that. I prefer the coaching aspect than the management aspect. And so what I wanted to do at some point once, I realized that that's what I wanted and that a management position would not fulfill that desire, I started looking to see is there a way to craft that role within the company? A common thing that happens, I think, in workplaces is that you are given roles or titles for things that you already do. Clearly, if there's something that I care about, I needed to be doing it already in my day-to-day work, and I needed to be doing it at a fairly high level. And so I focused efforts there, trying to say I want to get better at this. I want to do this in the opportunities that I do have in my current role. And then eventually, I did go to my manager and said, "Look, this is what I am looking for in the next step." Had a discussion about whether or not management could be a fit or if we could customize a management role for this, and eventually decided that an IC role would be a better fit for that. And among other things, we introduce at thoughtbot the role of principal developer, which is kind of the next step on our career ladder. It can be a little bit different emphasis for different people on the team who have that role, but, for me, a big part of that was putting more impact on the broader team as its focus. STEPHANIE: That's really cool. I really appreciate that you were able to come to the table with what you wanted and able to have a discussion about, okay, so management might not be the right fit. But how can we create this new role that not only benefited you but also benefited the rest of the company because that hadn't been an area that they had quite figured out yet. But by doing that, you essentially did exactly the kind of coaching and making an impact [chuckles] that you had also shared you had been wanting because you just opened this new door for others to also eventually work towards. And I think that's really awesome. That reminds me a lot of the idea of being directly responsible for yourself and your career. There's a really good blog post by a woman named Cate, who is an engineering director at DuckDuckGo. I'll link it to the show notes. But she writes a lot about how you have to own your own career and find opportunities to have that agency. And you can always ask. Like, you might not get everything that you want, but by asking and by bringing it up, you at least can start the conversation rather than expecting or just hoping that things will turn out the way that you want without having said anything. A couple of things that she says in the article that I also really like is the idea of expecting less from your job and more from your career. JOËL: Hmmm. STEPHANIE: At any given point, your job might not check all of the boxes, but maybe they check some, and that is worthwhile. And once you get to a point where maybe the job is not really doing anything towards the direction you want your overall career to go, that might be time to reevaluate. And then she also mentions learning from feedback and asking for feedback, and making sure that beyond the things that you're able to identify, learning from others areas that you can work on to have a better impact on your team is also really important in progressing your career quickly. JOËL: So how is this mindset of owning your career path maybe different than the default that a lot of people might assume in our industry? It sounds like it's a much more proactive approach. We talked already about doing the work to figure out what you want out of a career, what you care about, as opposed to just being told what you should care about by others. Are there other aspects that you have to sort of own as part of owning that career? STEPHANIE: I mean, I think it's just vital to having a work experience that is fulfilling and brings you joy and doesn't bog you down. I know we all have to work, but we also all have the capacity to exercise our agency there. I know we did talk a little about management earlier, and I wanted to also plug a book, "The Manager's Path" by Camille Fournier, which is about management. But she has a really excellent first chapter about how to be managed and what you can expect from having to be an employee with a manager but also what power you have in that dynamic. She says that while you can be given opportunities and have areas of growth pointed out to you, your manager can't read your mind, and they can't tell you what will make you happy. And so I have seen a lot of people spend time worrying about if they're doing the right things to get to the next level. But oftentimes, we just haven't really talked enough about how that next level is really totally different. And there are so many routes that that could take, whether that is becoming an open-source maintainer, or producing content like blog posts or podcasts even, or speaking at conferences, or management. Once I realized that there were so many different opportunities available to me, I did feel a bit liberated because it does seem like, oh, you're just supposed to level up your technical skills until you've become this superstar coder. But that's not what everyone wants, and I think that's okay. JOËL: And, like you said, there are so many different areas where you might choose to focus or invest time into, and you don't have to do them all. You don't have to be the super prolific open-source person, and also keynoting at conferences, and also publishing the book, and also, you know, whatever you want to add in there. So once you know your goals, how do you make those goals a reality? We've been talking a lot about know yourself and have some goals. But at some point, you have to translate those goals into actions that will take you one step at a time towards those goals, and sometimes that translation step is hard. STEPHANIE: It is hard. I think this is another place where I would work with my manager on, especially if I'm on a project where I'm not quite seeing those opportunities. Like I said, usually having another perspective or another set of eyes on what you're working on can make it clear, like, specific and concrete aspects that you can spend your energy on. So if it's wanting to get better at testing, it's like, okay, what does the current test suite look like, and what are some opportunities that you can provide new value to the test suite to make an impact on the team? Or what are some refactoring opportunities you can make if you are wanting to have more of that experience outside of the regular ticketed feature work that you have to do? JOËL: I think it's interesting that you mentioned impact on the team because not only do you want to level up some skills, but if nobody knows about it, your odds of getting that promotion or getting recognized for it are very low. So not only do you have to get good at technical systems, you have to get good at social systems as well. I was recently reading an article about the role of kingship in medieval Europe and how it's very much a role that needs to play out in public in order to build legitimacy so that people will do what you say. You need to be seen to do the things that everybody has in their mental kind of checklist are things that a good king does. And some of those are somewhat divorced from the reality of what actually is effective governance. It could be various public rituals that you do that people see and are like, oh yes, you're doing this parade every year. You're looking the part of a good king; therefore, I think of you as a good king. It could be military campaigns because there are a lot of those in the Middle Ages. And there's this interesting cycle where kings that have long and effective reigns then get to influence what the next generation of kings are going to have to do in order to look legitimate because people will point back at you and be like, well, Stephanie was an effective ruler, and she did X,Y,Z. And so, in order to look the part of an effective ruler, you should be doing those same things. STEPHANIE: That's fascinating. In some ways, I struggle with the idea that you have to prove that you're, you know, doing the kingly things and worthy of that title. But I do think that there is some degree of truth to that in your career as well, where you want to make sure that the work you're doing is visible. And you also just, in general, bring up a really good idea about the importance of leadership in career progression. And I think that in my experience, and from what I've observed, that is a vital way to progress your career is to just start demonstrating leadership qualities, and that could look like reaching out to new team members and helping them with onboarding. That could mean updating the documentation, just taking the initiative, and doing that. That could also mean starting to voice more of your opinions about risks or red flags about a certain technical implementation or a project because you have amassed the experience to be able to make those decisions and put in your two cents and then making sure that the choices that are made are the right ones. JOËL: Additionally, I think even when you're doing things that are a little bit more inward-focused, like learning something new, you can generally find some kind of artifact that you can take and share more broadly with a team. So maybe you experimented with something, and you wrote up a small code example to showcase the thing that you're trying out; make a Gist on GitHub and share it with your team. If you learn something new, maybe write a blog post about it. Maybe even just start a thread in Slack and start a conversation on something that you learned recently. These can be really low effort, but I always look for opportunities to take things that I have learned, things where I'm sort of working a little bit more inwardly on myself and see how can I share that with the rest of the team? Both because it benefits the team, they get to benefit from the impact of some of what you've done but also, it helps a little bit with making sure that your work is visible. STEPHANIE: Yeah, absolutely. JOËL: So we've been talking a lot about improving ourselves technically, but there's one question that we've danced around that we haven't actually addressed, and I'm curious about your thoughts here. For someone who's early career, do you think it's more valuable to be a specialist, someone who goes all in deep on one technology and becomes great at it? Or is it better to go more broad, become a generalist, and know a little bit about a lot of things? From the point of view of what will help move my career forward. STEPHANIE: I personally do think there is an aspect of being a generalist for a little while, a few years maybe, to get a taste of what is available to you. I think that is valuable before really committing to decide, okay, like, this is what I want to specialize in. Honestly, as a generalist myself, I still do feel a bit like I don't know what I want to dive deep into and commit myself a little bit to being like, okay, I'm going to have to sacrifice learning all of these other things to really focus on this one aspect. So I have found that being a generalist also kind of gives me the flexibility to work on different projects that might require learning a new language, or at least one that I am less familiar with. And I know that that's a skill in and of itself, being able to move on to different things and gather information and the skills you need to start contributing and working effectively quickly. So, honestly, I think I can really only speak to that experience, but it has served me well and is, for the most part, enjoyable to me at this present moment. What about you? Do you have any thoughts about generalist versus specialist? JOËL: I think, in a certain sense, there's no right answer. Like we said earlier, there are multiple paths to a career in tech, and you can go through both. I think something that I've seen be less effective, especially very early career folks, is trying to go too broad, jumping on every new language or framework every couple of weeks, every month, and just dipping your toe in it and then moving on to something else and never really learning deeply, or synthesizing, or building a mental model of things. And so you're kind of stuck in the shallow end forever, and it's hard to break through into that initial level of expertise. So I think, especially very early career people, I tend to recommend pick one language or technology and focus on getting good at that and then branch out. And, of course, you're never doing everything in a vacuum because there are a bajillion dev skills you need to learn beyond a language or framework. So I often categorize three areas to focus on that I like to recommend for people; one is pick a primary language or framework and get good at it. Two, learn some evergreen skills, these are things like version control, so Git, SQL, using the command line. And these are not things that you need to master on day one because you're going to use these your entire career. So learn a few things, move on, come back to them next month, learn a few more things, and just keep coming back there every now and then over the course of your entire career to deepen those skills, and that will serve you very well. And then, finally, some random thing you're interested in. I find that I learn so much faster and so much more deeply on topics that I'm interested in or passionate about. And that interest can be very random sometimes, and it can also be fleeting. It can be, oh, I was interested in a thing for a little bit, and I dug into it, and then I moved on to something else. If I have a career or learning plan, I like to leave that room for spontaneity to say there will be things that are maybe not strategically important as my next step, but I can learn them because I'm interested in them because they bring me joy. And then later on, maybe that will actually be the foundation of something important two years down the line where I can draw on that knowledge. STEPHANIE: You bring up a really interesting point. I do think my interpretation of generalist did line up more with the idea of those evergreen skills. So I think also about debugging and testing, and those are just part of the things that you're doing every day. And that might look different from project to project depending on what language or framework you're using and what testing philosophy people on your team abide by. But yeah, those are areas that I do think investing in will serve you well across projects and help put you in a position where you can jump into anything and be like, okay, I have these core foundational beliefs and skills about this work and now, okay, let me figure out how to apply them to the task at hand. JOËL: Are you familiar with the metaphor of the T-shaped developer? STEPHANIE: I don't think so. JOËL: So the idea is that you want to balance out a broad set of skills that you're a generalist at, that you know a little bit about them with a few things that you are a deep expert in. So you have that horizontal bar, but you also have a deep area of expertise which creates a kind of a T shape. In a sense, maybe that's just trying to say, like, do both. But I was recently reading an article that was advocating for not only a T-shaped developer as a sort of starting point but then also beyond that, over the course of a long career, you have plenty of opportunities to develop more than one specialization. And so now you start having a very broad base of general knowledge as well as multiple areas that you have spent significant time becoming an expert in. And this article referred to this idea as a comb-shaped developer, and that's something you work up to over the course of years or decades in tech. STEPHANIE: That's very cool. I love the idea that you might start out as a T-shaped but what you're doing is kind of like adding to your harness of skills and it being an additive process. You'd have more teeth in your comb [laughs] rather than it replacing something or a set of skills. On that note, shall we wrap up? JOËL: Let's wrap up. STEPHANIE: Let's wrap up. Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeee!!!!!!!!! ANNOUNCER: This podcast was brought to you by thoughtbot. thoughtbot is your expert design and development partner. Let's make your product and team a success.

The Bike Shed
364: Constructive vs Predicative Data

The Bike Shed

Play Episode Listen Later Dec 6, 2022 34:07


Stephanie and Joël attended RubyConf Mini, and both spoke there. They discuss takeaways and highlights from the conference. The core idea for this episode is explained in this article: Constructive vs. Predicative Data (https://www.hillelwayne.com/post/constructive/). This came up recently in a conversation at thoughtbot about designing a database schema and what constraints could be encoded in the schema directly versus needing some kind of trigger or Rails validation to cover it. This episode is brought to you by Airbrake (https://airbrake.io/?utm_campaign=Q3_2022%3A%20Bike%20Shed%20Podcast%20Ad&utm_source=Bike%20Shed&utm_medium=website). Visit Frictionless error monitoring and performance insight for your app stack. RubyConf Mini (https://www.rubyconfmini.com/) Episode on CFP - The Bike Shed 352: Case Expressions (https://www.bikeshed.fm/352) Podcast panel: The Ruby on Rails Podcast Episode 446: I'm Giving A Talk on Thursday (https://www.therubyonrailspodcast.com/446) Slides for FP talk: Functional Programming for Fun and Profit!! (https://speakerdeck.com/jennyshih/functional-programming-for-fun-and-profit?slide=107) Episode on language: The Bike Shed - 356: The Value of Specialized Vocabulary (https://www.bikeshed.fm/356) Constructive vs. Predicative data (https://www.hillelwayne.com/post/constructive/) Avoid the Three-state Boolean Problem (https://thoughtbot.com/blog/avoid-the-threestate-boolean-problem) Transcript: JOËL: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Joël Quenneville. STEPHANIE: And I'm Stephanie Minn. And together, we're here to share a bit of what we've learned along the way. JOËL: So something that's very recent in both of our worlds has been that both you and I, Stephanie, attended RubyConf Mini, and we both spoke there. What are some of your takeaways or highlights from the conference? STEPHANIE: Seeing you in person was definitely a highlight. I really enjoyed that. Because we're working remotely, I don't, you know, get to be in an office with you day to day. And it was really awesome to hang out with you, I think, for the first time as co-hosts of the podcast. And we both, I think, met some people at the conference too that were listeners. And it was really awesome to share that experience with you. JOËL: I had the interesting experience of several people who told me they recognized me by my voice, which I think is a common thing for podcasters, but as a new host, I was surprised by that. STEPHANIE: Yeah, that's weird. As a podcast listener, too, I definitely know exactly what you're talking about where it's like, oh yeah, I can identify someone by their voice. But to then be that person that people can recognize is pretty weird. I also really enjoyed being an audience member of the podcast panel that you are on at the conference with other podcast folks. It was moderated by Brittany Martin. And yeah, I just thought you represented The Bike Shed really well and spoke for both of us about podcasting in a way that I really appreciated. JOËL: And for any of our listeners who were not able to be there in person, Brittany has published that episode as a podcast, and we will link to it in the show notes. STEPHANIE: Another thing I really liked about RubyConf Mini was the smaller scale. I think it was about 150 or so attendees, which felt very different from traditional Ruby Central conferences with several hundreds of people. I heard a lot from other folks there that they really liked the regional aspect of it, the intimacy of the smaller conference. I think I got more of an opportunity to run into people that I'd met at the conference over the next few days. And there was, yeah, definitely a sense of tighter knit community there, you know, when you meet someone, and then you bump into them on the way into a talk, and then you can ask how their day was going and any highlights that they had. And yeah, I guess I haven't really attended a conference that size before, and so that felt like a very special experience for me. JOËL: I 100% agree. I think the smaller format definitely makes it a little bit more intimate, makes it much easier, I think, to build some of those social connections, to meet with people, and to have some good conversations. I think the format of the conference as well favored that. There were, I think, larger breaks between talks that encouraged people to hang out and talk. And, as you said, because it's smaller, you also get to see the same people over the course of a few different breaks instead of being like, oh, I met a stranger on the morning of day one, and then in the afternoon, I met another stranger. And it's just constantly introducing yourself. One thing that was really interesting to me is the experience of being a speaker is very different than just attending. As a speaker, you get to go to the speaker dinner and connect with a lot of the other speakers there. Some of them might be quote, unquote "famous people" that you're not quite comfortable just walking up to and introducing yourself. But in the smaller dinner, you just find yourself sitting next to them and enjoying some food or a drink and getting conversations. It's also much easier to have people come up to you during the conference. Because you're a speaker, people will come and talk to you. So if you tend to be a little bit more introverted, as long as you can get over your fear of being on stage and public speaking, it actually makes social connection interaction much easier to be a speaker. I would recommend to any of our listeners who were wondering how can I get more out of a conference? How can I get better connections, better conversations? Consider being a speaker. STEPHANIE: Yeah, absolutely. We've talked about this before; I think when we chatted about writing our CFPs for this conference that speaking doesn't have to be a really big, scary thing, but everyone has something to say. I think we had mentioned in previous episodes that your talk topic came out of just a discussion that you had internally, and you were like, wow, enumerables are so cool, like, let me dig deeper into them and just share what I learned. So I totally recommend it. And this conference was my first in real-life speaking opportunity as well, and that felt super different from my experience last time doing it virtually, you know, talking about how much I love that sense of community all the time. But it really felt true for me this time around, where I could see the audience react to the things I was saying, like, maybe go off the cuff a little bit. And then yeah, at the end, having people come up to me was really awesome to just talk about pairing, which is what I spoke about, and just share our experiences. And they asked what I thought about some things, and it was really cool to just be able to spread that knowledge around. And one thing I noticed you did a lot was come up to speakers after they wrapped up their talks. You were almost always the first person to get up and congratulate them and just get the ball rolling on following up on the things they talked about. Is that something that you really enjoy doing or find particularly valuable as an audience member or speaker? JOËL: Yes, both. I think, as a speaker, it's really validating to have people come up to you after the talk and either just tell you they liked the talk or ask a question. I generally don't like to do just open questions after a talk from the audience because then you get the classic; this is more of a comment than a question or people who will tell you that you had a typo on one of your code slides. Like, none of that is useful to anyone. So, if you're really interested, come talk to me afterwards. And then that actually makes me feel like my talk connected with people, and people were paying attention, people enjoyed it, people were learning. So I try to pay that forward as well for talks that I listened to, go up to the speaker, and tell them one thing that I appreciated about the talk or a thing that I learned, or something that got me excited in their content. STEPHANIE: Yeah, I'm sure that it's very appreciated. And it also breaks the awkward silence at the end when the speaker finishes and people aren't sure if it's okay for them to get up and start moving around. Yeah, I thought that was a really good way to kind of just encourage people to start chatting with each other and moving into those break times that we mentioned earlier, those opportunities to socialize. JOËL: Another thing that I think is really fun that you can do at in-person conferences, and I know you were doing it a lot, is going to see the talks of friends and colleagues and sitting in the front row and just being there to cheer them on and encourage them. Again, I think that makes a big difference when you are on stage, and you see these people who are your friends and colleagues there to support you. It gives you that boost of confidence. And when you're there in the audience, it's fun to cheer on somebody else. STEPHANIE: Oh yeah. You gave me a lot of thumbs-ups during my talk, and I really appreciated that. [laughs] So I'm curious if there were any talks that stood out to you that you got to see. JOËL: And I was really inspired by your talk, pair programming. I think there are a lot of things that I can take from that to improve the way I pair. I was also inspired by Aji's talk, Aji Slater, on automating manual tasks that you have to do in an iterative way. That one really hit home because, on my current project, I have been doing a lot of manual things. And I just have random snippets of code, like, some shell script lines or Ruby console lines, that I copy-paste out of Slack conversations because I've shared them with other people who are doing similar work. And I realized that a lot of his advice would apply to the work that I'm doing and how that could really make things better. So that was one of those talks I was listening to, and I was like, oh, you know what? Monday morning, when I go back to my project, this is something that I'm going to start doing. This is something I'm going to change in the way I do my day-to-day work. STEPHANIE: Yeah, absolutely. I have so many tasks that I would like to get automated, and think that one day I will magically have more time in my schedule to get to it. But I liked that his talk gave pretty concrete strategies for baking it into your regular, like you said, day-to-day workflow, and that lowers the activation energy to getting them done. And then those things can be iterated on and could eventually become, in an ideal world, a fully-fledged feature that you put together from doing those repetitive tasks. And yeah, they provide a lot of value not just to you but can eventually provide value to your co-workers and then even your users in the future. JOËL: Were there any talks that stood out for you? STEPHANIE: One talk that I really enjoyed was Jenny Shih's about Functional Programming for Fun and Profit. I have attended a lot of functional programming talks within the Ruby realm, at least to try to get a better sense of how it can apply to my work and the languages and paradigms that I use. And honestly, what I liked about it was that it didn't get too in the weeds about functional programming. What she did was provide mental models for understanding the paradigm that I think was a good vehicle for understanding things very generally. And, for me, like,¬¬ a talk, it's really hard to pay attention to lines of code and to read code on the fly while people are presenting. For me, that is just not how I like to consume that information. And so she provided themes and, like I said, those mental models, which I know you really like to use a lot too in teaching people new concepts. For me, I didn't fully learn what a monad was, once again, but at least having that repeated exposure to those foundational aspects, I think, will eventually lead me to be able to grok those things a little more comprehensively the next time I see it or whenever I decide to dig deeper. JOËL: What was a mental model that was shared that connected with you particularly? STEPHANIE: So one of the main mental models that she shared was thinking about a program in terms of these three dimensions: value, behavior, and time. She had a nice slide that showed the difference between the object-oriented paradigm, where value and behavior are contained by objects, where time is kind of inherently wrapped up in those objects that hold information about the state through values and behavior. Whereas in her functional programming example, those three dimensions were a bit separate. And I found that distinction to be really helpful in separating things that felt very implicit before, but it was nice to see them broken out into very clear concepts in terms of building blocks of a program. JOËL: So it's helpful then when thinking...when you look at code, if you can think about it in those three different dimensions to help think about, am I taking a functional or other approach in this particular dimension when working with this code? STEPHANIE: Yeah, exactly. I think it also gave me more of a vocabulary to describe the pros and cons of each and a lens of thinking about which I might want to choose for the particular problem at hand. JOËL: So you mentioned there's a visual for these three dimensions from the slides. Are those slides publicly available? STEPHANIE: They are. I will link to them in the show notes. JOËL: So all of these talks were recorded. They're not yet available to the public, but I think the plan is to publish them on YouTube sometime in the new year, so that means probably January 2023. And a big shout out to the AV team and everyone who is involved in recording these. STEPHANIE: Yeah, I am definitely looking out for a link to my talk so I can send it to my mom. I also wanted to give a little shout-out to the organizers of RubyConf Mini: Jemma Issroff, Emily Samp, and Andy Croll. JOËL: Woo! STEPHANIE: They put on just a really awesome conference, and I feel very grateful that I got a chance to attend with you, Joël. JOËL: It was definitely a delightful experience. STEPHANIE: Delightful. That's a reference to Joël's talk for those of you who are listening. MID-ROLL AD: Debugging errors can be a developer's worst nightmare...but it doesn't have to be. Airbrake is an award-winning error monitoring, performance, and deployment tracking tool created by developers for developers that can actually help cut your debugging time in half. So why do developers love Airbrake? It has all of the information that web developers need to monitor their application - including error management, performance insights, and deploy tracking! Airbrake's debugging tool catches all of your project errors, intelligently groups them, and points you to the issue in the code so you can quickly fix the bug before customers are impacted. In addition to stellar error monitoring, Airbrake's lightweight APM helps developers to track the performance and availability of their application through metrics like HTTP requests, response times, error occurrences, and user satisfaction. Finally, Airbrake Deploy Tracking helps developers track trends, fix bad deploys, and improve code quality. Since 2008, Airbrake has been a staple in the Ruby community and has grown to cover all major programming languages. Airbrake seamlessly integrates with your favorite apps to include modern features like single sign-on and SDK-based installation. From testing to production, Airbrake notifiers have your back. Your time is valuable, so why waste it combing through logs, waiting for user reports, or retrofitting other tools to monitor your application? You literally have nothing to lose. Head on over to airbrake.io/try/bikeshed to create your FREE developer account today! JOËL: Coming back from the conference, I recently had a really interesting conversation with some other colleagues at thoughtbot. We were looking at a database schema for a new application and talking about some of the trade-offs involved in how that schema is structured, so what tables we want to have. Do we want to have indexes? Things like that. And particularly around some of the assumptions are business rules that would come into play. So we're looking at...we'd drawn out this Entity Relationship Diagram (ERD). In it, we're looking at all the tables, and something that comes up immediately is like, oh, it's possible to have some bad data that could show up in these columns. Or it's possible that this relationship could exist where this table has a foreign key on this table, but really, that should never happen in this particular way of working. And so then the question became, how do we try to prevent these things that currently the schema allows but that are not valid in this particular business domain? Do we want to change the schema somehow and make that stricter or find some way to prevent it? Do we want to add some kind of validation that will check some business rules first before inserting or updating a record? I'm curious, have you ever been in a situation like that where you had to balance those two approaches to enforcing business rules on your database? A classic small example of this is a situation where let's say, you have a users' table and you have a name column on there. And you want to ensure that that name must always be present; all users must have names. Do you try to enforce that via the schema with a NOT NULL constraint? Or maybe you try to enforce that with a validation, maybe a presence validation at the Rails level. Or if you're really into SQL, maybe some fancy trigger, but do it in a validation style rather than trying to force this using the schema. And our particular scenario was a little bit more complex than just one column; it was more to do with associations. But I think this sort of problem shows up even in constraints as small as a required field. STEPHANIE: That's really interesting. I think that, in my experience, when we are spinning up new tables, at that point, we do try to put some intentional thought into what the schema should look like and what requirements we might need to encode at the database level. But things that are more complex might need a little more code, like Ruby code. I have then pushed to an ActiveRecord validation. One thing that I think is important to know is that when you do set those things on the schema, it's harder to change. And so you usually have to feel pretty confident that that's what you want. Otherwise, you'll run into issues later if that does have to change and making changes to whatever existing data you might have. But it's also pretty common to just do your best when you are deciding on a database schema and then having to make adjustments down the line as you know more about your domain. JOËL: This conversation reminds me a little bit of the idea of database normalization. I think that might almost fit as a subset of general tactics of using the schema to ensure your data is more correct. When you are generating new tables, let's say you're creating a greenfield app and you need to create four or five tables; how much emphasis do you put on database normalization when you're initially designing those? STEPHANIE: I think for a greenfield project when you are setting everything up and creating tables for your main domain models, there is an aspect of it that should be considered because you're in this unique position where nothing really is in existence yet. And you do want to try to set yourself up to be successful and hopefully have information about your main use case for this app and can kind of make decisions about the schema then. At least in my experience, that has been part of the conversation, though, to be fair, because it's so early, you do have the opportunity to change things without as much effort or pain. But I think it's worth considering when you're just sitting down and working through what those models are going to look like. JOËL: And for our listeners who may not have heard the term normalization before, it's a series of...you can think of them as rules that you apply to your database design to try to avoid data redundancies in your tables. There are different levels of this; they're typically referred to as normal forms. So you'll see things like first normal form, second normal form, third normal form; those are kind of the fancy terms for them. But they generally involve breaking out other tables so that you don't have data redundancies. And in many ways, this is similar to principles such as the single-responsibility principle that we apply to objects when we're designing our objects in an OO system. But this is more at the table level for databases. STEPHANIE: I do think that it is so hard, maybe even impossible, to plan something out, to not have any of those redundancies, to begin with. And I do think sometimes they are a bit inevitable. But I also have had the experience of having to figure out what the heck I'm looking at when I am querying data and see all these things that are duplicated or maybe slightly different. And yeah, I think when you are in that position of starting a greenfield application, it is really interesting to see how you make those decisions about what needs to be enforced and where. Where did you end up landing, or what did you discuss in this conversation with the co-worker? JOËL: I think we went with a bit of a hybrid approach. Some things, we can use the schema to prevent bad data, and then some things either cannot be represented with a schema, or it's possible, but it's really cumbersome and painful. And so, we chose to try to enforce it with a validation. To me, this feels very similar to a problem in typed languages. So some communities that use a lot of types try to use those types to only allow data to come through that's in a valid shape. And so you'll hear things like make impossible states impossible or make illegal states unrepresentable. And that works for many things, but it's not always possible to enforce all of your business constraints through a schema. Or sometimes it's possible but just not practical. And so, I think there is a balance of finding when you can use the schema or when it's better to use the validation.¬ STEPHANIE: Yeah, I think my general rule of thumb is, like I mentioned earlier, things I feel really confident about that we want to make sure that we have in our database or in our data for sure. I do lean towards requiring those in a schema, and it also communicates that confidence or communicates that intent that it's something that at one point was decided is important. And so, if a future developer comes in, it would take a lot of work for them to write a migration, to remove some database constraint. Whereas I think sometimes validations at the Rails level are potentially a little more open to change and then even more so if you get to validating on the client side. JOËL: That can get to be a really, like, it's a useful tool, but one that you can really hurt yourself with. If you modify your validations at the Rails level or at the front-end level, but then you don't backfill those changes on your data in the database, then you might have records in your database that if you were to load them into memory and hit save on them again, would refuse to save because they no longer match the validations. And on longer-lived applications, I've seen that happen sometimes where not all rows in the database pass the Rails validations. STEPHANIE: Yeah, I think I've seen that be a problem either for developers who then have to backfill that data or write some migration to change some of the data to meet the new requirements, or just unexpected bugs on the users who discover something new but like you said, have been there long enough before those things were implemented. JOËL: The more I think of this, I think maybe constraints that are enforced at a validation level might still require changing the data in your database. So if you had a constraint enforced via a schema, you don't have a choice. You have to write some way to migrate that data so that it fits the new schema. You can kind of lie to yourself with validation and not change the historic data, and sometimes that is the case; you want to keep the old data and only prevent new data from being written in the old format. But if you need consistency, then you probably need a data migration regardless of which approach you take. STEPHANIE: Yeah, that definitely sounds like the more robust way to go about it for sure. JOËL: I have an article that I like to reference a lot by Hillel Wayne on Constructive Versus Predicative Data, which is basically looking at these two general approaches to enforcing data correctness and formalizing them a little bit. So do you try to enforce them based on the construction or the shape of the entity that you're creating, be that a database table, an object, a type, something like that? Or do you enforce it via some kind of predicate? So that could be a validation or other similar logic that runs kind of at runtime to enforce your constraints. STEPHANIE: That's interesting. I hadn't heard of those terms before, but I think they provide a lens through which you can look at the problem. Did the article end up suggesting different strategies for solving that problem, or was it more theoretical in different ways to look at it? JOËL: I think the article does two things. First, like you said, it gives us the words to talk about those approaches. And having those labels now, I start seeing them everywhere. I see them in databases, I see them in objects, I see them when doing types across a variety of languages. So that's already a huge win for me. I think you and I had done an episode a couple of months back where we talked about the value of having labels to put to ideas. And I think for me reading that article gave me those two labels. And all of a sudden, it really helped to make connections that I wasn't seeing before. The second thing that the article does is, I think, explore some of the limitations that each approach has and when you might want to use one versus another. The constructive approach, so using a schema, is more consistent because you know it is impossible for the program to create data that's in the wrong shape. That being said, not all constraints can be represented in a constructive manner, or it might be possible but really cumbersome. Also, sometimes it's not really invalid data; it's just sort of undesirable data. So you might want a looser schema. And let's say that you're storing some kind of intermediate state or some kind of raw input from another system that you might want to layer validations on top of, but you don't want to reject that data out of your database. You want that sort of incomplete or imperfect data in your system. Something that I find myself doing more and more these days when I create new tables is to really lock down the schema as much as possible. I think that might be contrary to maybe the way a lot of people in the community like to work. Some people might prefer to start with a very loose schema with no constraints and then work towards making things stricter as they explore the domain, and that's kind of the default that Rails has. If you're creating a new table, all columns, for example, are nullable by default. Personally, I will put a null false on every column and every migration that I make unless somebody can make a convincing case otherwise, and even then, I might try to think of is there any possible way that we could avoid that scenario and put that null false. Part of the reason for that is that it is much easier to loosen constraints on existing data than to tighten them afterwards. So if I have a column where no value is allowed to be null, and then later on we decide, you know what? It is okay for some of them to be null, I can change the requirement on that column, and I don't need to make any changes to the existing data. It just works. If the reverse happens, if I have a column that allows a bunch of nulls and then I want to make that column required, now I have to go and find a way to backfill all the empty spots in that column. And that could be a very challenging process. It might even be impossible. There might be some values there that it's just like, the user did not supply them at the time because we didn't ask for them. And now there's nothing we can put in there. So do you put in, like, unknown or not available? Then you have to ask yourself some really difficult questions about your data. STEPHANIE: Yeah, absolutely. I think I agree with you there. Another thing I like to do is provide default values for columns, especially ones where they can't be null, because, like you were saying, that helps me have a better understanding of just what is going on in the database. An issue I have seen come up involves a Boolean column where if a default value of false, for example, if that's what we're going with, is not encoded in the schema, you end up with potentially three values for a Boolean, which would be true, false, and null, and that I think has been -- JOËL: The infamous three-state Boolean. STEPHANIE: Yeah, exactly, the three-state problem, which is just inherently contradictory to what a Boolean is, to begin with. And I've definitely run into issues with that where you have to decide, or figure out, or write code to determine is null false? Is that what we mean here? It's not clear. But if you, like you said, locked it down at the beginning, provided those default values, that puts in those guardrails to prevent things from getting out of hand. JOËL: It also makes it easier for users of your database, application, whatever to interact with your code. I've run into this a lot when working with GraphQL APIs. And the default in many GraphQL server implementations is to make all fields nullable by default. When you build your schema, you have to add some extra things there to say, "This field is non-nullable," which means that a client that's now consuming it, anytime they deal with the data they need to check, is it present or not? You can't have the confidence that that data is there. And so it can force a lot of extra checks on the client. Or I guess you could just take it on faith and hope nothing breaks. STEPHANIE: Yeah, it's funny you mention that because I definitely think there's like spheres of impact. So as a developer, you maybe start having to write code that checks those kinds of things, like if it's null or not in your code. Then that can even extend to, like you said, your users or consumers of the API, who then have to contend with data that they have no control over. And I've been there too, and that can be frustrating as well. JOËL: We've talked a lot about data correctness and different ways to achieve it, different strategies. Why is this something that we care so much about? STEPHANIE: I think data correctness is really important from a developer experience perspective. And it's way easier to fix a bug in your code than it is to wrangle a lot of accumulated bad data. JOËL: Yeah, sometimes bad data is not fixable at all, and those are situations where you have a really bad day as a developer. STEPHANIE: Agreed. JOËL: Well, on that note, shall we wrap up? STEPHANIE: Let's wrap up. Show notes for this episode can be found at bikeshed.fm. JOËL: This show has been produced and edited by Mandy Moore. STEPHANIE: If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. JOËL: If you have any feedback for this or any of our other episodes, you can reach us @_bikeshed, or you can reach me @joelquen on Twitter. STEPHANIE: Or reach both of us at hosts@bikeshed.fm via email. JOËL: Thanks so much for listening to The Bike Shed, and we'll see you next week. ALL: Byeeeeeeee!!!!!!! ANNOUNCER: This podcast was brought to you by thoughtbot. thoughtbot is your expert design and development partner. Let's make your product and team a success.

The Bike Shed
361: Working Incrementally

The Bike Shed

Play Episode Listen Later Nov 8, 2022 30:28


thoughtbotter Stephanie Minn joins The Bike Shed as co-host!

The Bike Shed
356: The Value of Specialized Vocabulary

The Bike Shed

Play Episode Listen Later Sep 27, 2022 39:20


Guest and fellow thoughtbotter Stephanie Minn and Joël chat about how the idea of specialized vocabulary came up during a discussion of the Ruby Science book. We have all these names for code smells and refactors. Before knowing these names, we often have a vague sense of the ideas but having a name makes them more real. They also give us ways to talk precisely about what we mean. However, there is a downside since not everyone is familiar with the jargon. This episode is brought to you by Airbrake (https://airbrake.io/?utm_campaign=Q3_2022%3A%20Bike%20Shed%20Podcast%20Ad&utm_source=Bike%20Shed&utm_medium=website). Visit Frictionless error monitoring and performance insight for your app stack. Stephanie's previous talk (https://www.youtube.com/watch?v=m0dC5RmxcFk) Non Violent Communication (https://www.goodreads.com/book/show/71730.Nonviolent_Communication) RubyConfMini (http://www.rubyconfmini.com/) Ruby Science book (https://books.thoughtbot.com/books/ruby-science.html) Connascence as a vocabulary to discuss coupling (https://thoughtbot.com/blog/connascence-as-a-vocabulary-to-discuss-coupling) Wired series "5 levels of teaching" (https://www.youtube.com/playlist?list=PLibNZv5Zd0dyCoQ6f4pdXUFnpAIlKgm3N) Transcript: JOËL: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Joël Quenneville. And today, I'm joined with fellow thoughtboter Stephanie Minn. STEPHANIE: Hey, Joël. JOËL: And together, we're here to share a little bit of what we've learned along the way. Stephanie, what is new in your world? STEPHANIE: Thanks for asking. I am on a new project I just started a few weeks ago, and I'm feeling the new project vibes, I think, kind of scoping out what's going on with the client with the work that they're doing. Trying to make a good impression. I think lately I've been in that mode of where can I find some work to do even when I'm just getting on boarded and learning the domain, trying to make those README updates in the areas that are a bit outdated, and yeah, just kind of along for the ride. One thing that has been surprising already is that in my second week, the project pivoted into a different direction than what I was expecting. So that has been kind of exciting and also pretty interesting to see sometimes this stuff happens. I was brought on thinking that we were working on rebuilding the front end in React and TypeScript, pulling out pieces of their 15-year-old Rails monolith. So that was kind of one area that they decided to start with. But recently, they actually decided to pivot to just revamping the look of the existing pages in the Rails app using the same templates and forms. So it's kind of shifted from more greenfield-esque work to figuring out what the heck's going on in this legacy codebase and making it a little bit more modern-looking and cleaning out the cobwebs, I suppose as we find them. JOËL: As a consultant, how do you deal with that kind of dramatic shift in expectations? STEPHANIE: I think it's tough because I necessarily wasn't in those conversations, and so I have to come at it with the understanding that they have a deep knowledge of the business and things that are going on behind the scenes that I don't, and I am coming in kind of with a fresh set of eyes. And it definitely raises some questions for me, right? Like, why now? What were the trade-offs that were made in the decisions? And I hope that as a consultant, I can poke and prod a little bit to help them with the transition and also figuring out its impact on the rest of the team in a way maybe someone who is more familiar with the situation and more tied to the politics of the org might not have that perspective. JOËL: I have a lot of questions here. But actually, I'm thinking that onboarding as a topic would probably make a good standalone episode. So maybe we'll have to bring you back for a future episode to talk about how to onboard well and how to deal with surprises. STEPHANIE: Yeah, I think that's a great idea. What about you, Joël? What's going on in your world? JOËL: I'm doing an integration with a third-party gem, and I am really struggling. And I've gotten to the point where I'm reading through the source of the gem to try to figure out some weird errors, some things that come up that are not documented. I think that's a really valuable skill. Ideally, you're not having to bring it out too often, but when you do, being able to drop into the code can really help unblock you or at least make some amount of progress. STEPHANIE: Are you having to dig into the gem's code because you weren't able to find what you needed from the documentation? JOËL: That's correct. I'm getting some cryptic errors where the gem is crashing, and I'm finding some lines in my logs that point back to the gem. And now I'm trying to reconstruct what is happening. Why is it not behaving the way it should be based on the documentation that I read? STEPHANIE: Oh, that's tough. Getting into gem code is uncharted territory. JOËL: It's nice when you're working with an open-source gem because the source is there, and you can just follow the stack trace and go through the code. Sometimes it's long and tedious, but it generally gives you results. It definitely is intimidating. STEPHANIE: Yeah. When you're facing this kind of problem where you have no idea where the light at the end of the tunnel might be, how long do you spend with it? At what point do you take away with what you've learned and try to figure out a different approach? JOËL: That's a good observation because digging through the source of a gem can definitely be a time sink. I think how much time I want to budget depends on a variety of other factors. How big of a problem is this? If I can't figure it out through reading the source, do I have alternate approaches to debug the problem, such as asking for help, opening an issue, reaching out to somebody else who's used it, complaining about it on The Bike Shed and hoping someone responds with an answer? There are other options that I can do that might leave me blocked but maybe eventually give me results. The advantage with reading the source is that you're at least feeling like you're making progress. STEPHANIE: Nice. Well, I wish you luck on that journey. [laughs] It sounds pretty tough. I'm sure that you'll get to one of those solutions and figure out how to get unblocked. JOËL: I hope so. I'm pursuing a few strategies in tandem. So I've asked for help, but I'm also reading the source code. And between the two of those, I hope I'll get to a good solution. So, Stephanie, last time you were on the show, you talked about your experience creating talk proposals for RubyConf. Have you heard back from them since then? STEPHANIE: I have. I will be speaking at RubyConf Mini this year. And I'm really excited because this will be my first IRL conference talk. So last time, I recorded my talk for RubyConf, and this time I will be up on a stage in front of real people. JOËL: That's really exciting. Congratulations. STEPHANIE: Thanks. JOËL: What is the topic of your talk? STEPHANIE: I will be talking about pair programming and specifically pair programming through the lens of a framework called Nonviolent Communication, which is a framework I learned about through a friend who recommended the canonical book on it. And it's a self-help book, to be totally frank, but I found it so illuminating. It really changed how I communicated in my relationships in my personal life. And the more time I spent with it, the more I realized that it would be a great application in pair programming because it's so collaborative and intimate. I've experienced the highs and lows of pair programming. You can feel so good when you are super connected with your pair. You make a lot of progress. You meet whatever professional goals that you might be meeting, and you have someone along for the ride the whole time. It can be just so rewarding. But it can also be really challenging when you are having more of those interpersonal conflicts, and navigating that can be tough. And so I'm really excited to share this style of communication that might help others who want to take their pair programming to the next level and get the most out of that experience no matter who they're pairing with. JOËL: I'm excited to hear this talk because pair programming has always been an important part of what we do at thoughtbot. And I think now that we're remote, we do a lot of remote pair programming. And the interpersonal interactions are a little bit different there than when you're physically in a room with each other, or you have to maybe pay a little bit more attention to them. I'm really excited to hear that. I think that's going to be really useful, not just for me but for a lot of the audience who are there. STEPHANIE: Thanks. Joël, you have a talk accepted at RubyConf Mini too. JOËL: Yes, I also had a talk accepted titled Teaching Ruby to Count. And it's going to be all about series, enumerators, enumerables, and ranges in Ruby and the cool things that you can do with them. So I'm really excited to share about that. I've done some deep dives on these topics, and I'm excited to share that with the broader Ruby community. STEPHANIE: Nice. I'm really excited to hear more about it. JOËL: Did you submit more than one proposal this year? STEPHANIE: This year, I didn't. But I would love to get to a point where I have a lot of content on the backburner and can pull it out when CFP season rolls around to just have some more options. Yeah, I have all these ideas in my head. I think we talked about how we come up with content in our last episode. But yeah, having a content bank sounds really nice for the future, so maybe when that season rolls around, it is a lot easier to get the ball rolling on submitting. What about you? Did you submit more than one? JOËL: I submitted two, but this is the one I was most excited about. I think the other idea was maybe a little bit more polished, but this one was a newer one I came up with towards the end of the CFP period. And I was like, ooh, I'm excited about this. I've just done a deep dive on enumerators, and I think there are some cool things to share with the community. And so that's what I'm excited to share about, and maybe that came through the proposal because that is what the committee picked. So I'm super happy to be talking about that. STEPHANIE: Nice. Yeah, I was just thinking the same, that your excitement about it was probably palpable to the committee. JOËL: For any of our viewers who are interested in coming to watch the talks by Stephanie and myself and plenty of other gifted speakers, this will be at RubyConf Mini in Providence, Rhode Island, from November 15th to 17th. And if you can't make it in person, the videos will be published online early in 2023. And we'll definitely share the links to that when they come out. So as we mentioned in your last episode, thoughtbot has a book club where we've been discussing the book Ruby Science, which goes through a lot of code smells and talks about some various refactoring patterns that can be used to fix them. Most recently, we looked at a code smell that has a very evocative name; it's called shotgun surgery. STEPHANIE: Yeah, it's a very visceral name for sure. I think that is what prompted this next topic that we're about to discuss because someone in the book club, another thoughtboter, mentioned that they were learning this term for the first time. But it made a lot of sense to them because they had experienced shotgun surgery and didn't have the term for it previously. Joël, do you mind giving the listeners a recap of what shotgun surgery is? JOËL: So shotgun surgery is when in order to make a change to a codebase, you have to make a bunch of little changes in a lot of different files, a lot of different locations. And that means that all of these little pieces are weirdly coupled to each other in a way that to make one change, you have to make a bunch of little changes in a lot of places. And that results in a very high churn diff, and that's a common symptom of this problem. STEPHANIE: Nice. Thanks for explaining. MID-ROLL AD: Debugging errors can be a developer's worst nightmare...but it doesn't have to be. Airbrake is an award-winning error monitoring, performance, and deployment tracking tool created by developers for developers that can actually help cut your debugging time in half. So why do developers love Airbrake? It has all of the information that web developers need to monitor their application - including error management, performance insights, and deploy tracking! Airbrake's debugging tool catches all of your project errors, intelligently groups them, and points you to the issue in the code so you can quickly fix the bug before customers are impacted. In addition to stellar error monitoring, Airbrake's lightweight APM helps developers to track the performance and availability of their application through metrics like HTTP requests, response times, error occurrences, and user satisfaction. Finally, Airbrake Deploy Tracking helps developers track trends, fix bad deploys, and improve code quality. Since 2008, Airbrake has been a staple in the Ruby community and has grown to cover all major programming languages. Airbrake seamlessly integrates with your favorite apps to include modern features like single sign-on and SDK-based installation. From testing to production, Airbrake notifiers have your back. Your time is valuable, so why waste it combing through logs, waiting for user reports, or retrofitting other tools to monitor your application? You literally have nothing to lose. Head on over to airbrake.io/try/bikeshed to create your FREE developer account today! STEPHANIE: I think I came away from that conversation thinking about the idea of learning new terms, especially technical ones, and the power that learning those terms can give you as a developer, especially when you're communicating with other people on your team. JOËL: So you mentioned the value in communication there. Some terms have a very precise meaning, and so that allows you to communicate a very specific idea. How do you balance having some jargon and some terminology that allows you to speak very precisely versus having to learn all the terms? Because the more narrow the term is, the more terms you need to talk about all the different things. STEPHANIE: That's a great question. I don't know if I have a great answer because I think I'm still on my journey. I have always noticed when developers I work with have that really precise, articulate technical vocabulary, probably because I don't. I am constantly referring to functions or classes as things, like, that thingy over there talks to this thing over here, and then does something. [laughs] And I think it's because I maybe didn't always have that exposure to very precise technical vocabulary. And so I had an understanding of how things worked in my head, but I couldn't necessarily map that to words. And I'm also from California, so, I don't know, maybe some of that is showing through a little bit. [laughs] But I've been trying to incorporate more technical terms when I speak and also in written form, too, such as in code review, because I want to be able to communicate more clearly my intentions and leave less room for ambiguity. Sometimes I've noticed when you do speak more casually about code, turns out other people can interpret it in different ways. And if you are using, like you said, that narrower technical term for it, that leaves less room for misunderstanding. But in the same vein, I think a lot of people are like me, where they might not know the technical terms for things. And when you start using a lot of jargon like that, it can be a bit exclusive to folks earlier in their career, especially since software as an industry we have folks from all different backgrounds. We don't necessarily have the expectation of assured formal training. We want to be inclusive of people who came to this career from different places and make sure that we are speaking the same language. And so it's been top of mind for me thinking about how we can balance those two things. I don't know, what do you think? JOËL: I want to speak to some of the value of precision first because I think there are a few different points. We have the value of precision, then we have the difficulty of learning vocabulary, and how are we inclusive of everyone. But on the topic of precision, I don't know if you saw not too long ago, another fellow thoughtboter, Matheus Sales, published an article on the thoughtbot blog about the concept of connascence. And he introduces this as a new set of vocabulary, not vocabulary that he's created but a vocabulary that is out there that not that many developers are aware of for different ways to talk about coupling. So it's easy in a pull request to just say, "Oh, well, that thing looks coupled. How about this other way?" And then I respond, "Well, that's also coupled in a different way." And then we just go back and forth like, "Well, mine is more coupled than yours is," or whatever. And connascence provides a more precise, narrow vocabulary to talk about the different ways that things are coupled and which ones are more coupled than others. And so it allows us to break out of maybe those unproductive discussions because now we can talk about things in a more granular way. STEPHANIE: Yeah, I loved that blog post. It was really exciting for me to pick up a new term to describe something that I had experienced, or seen in codebases, or felt the pain of, and be able to describe it more accurately. I'm curious, Joël, if you were to use that term next time, how would you make sure that folks also have the same level of familiarity with it? JOËL: I think on a pull request, I would link to Matheus' article depending on...I might give a little bit of context in a comment. So I might say something like, "This area here is coupled. Here's a suggested refactor. It's also coupled but in a different way. It's because we've moved up this hierarchy of connascence from, you know, connascence of names to some other form" (I don't have them all memorized.) and then link to the article. And hopefully, that becomes the start of a productive discussion. But yeah, having the resources you can link to people is great. And that's one of the nice things about text communication on a pull request is that you can just link to external resources that people can find helpful. STEPHANIE: To continue talking about the value of precision and specialized vocabulary, Joël, I think you are a very articulate communicator. And I'm curious from your perspective if you have always been this way, if you've always wanted to collect technical terms to describe exactly what you want to convey, or if this was a bit of a journey for you to get to this level of clear communication in your technical speaking and writing. JOËL: It's definitely been a journey. I think there are sort of two components to this; one is being able to communicate clearly to others; make sure that they understand what you're talking about. So for that, it's really important to be able to put yourself in somebody else's shoes. So when I'm building a conference talk or writing up a blog post, I will try to read it or go through my slide deck and try to pretend that I am the audience. And then I ask myself the questions: where do I get confused? Where am I going to have questions? Maybe even where am I going to roll my eyes a little bit and be like, eh, I didn't agree with that leap of logic there; where are you going? And then shift back in author mode and say, how can I address these? How can I make my content speak to you in an area where maybe you disagreed, or you were confused? So I kind of jump between moving from the audience seat to back to the author and try to make that material as much as possible resonate with those people. STEPHANIE: Do you do that in more real-time communication, such as in meetings or in pairing? JOËL: I think that's a little bit harder to do. And then it's maybe a little bit more of asking directly, either pausing to let people interject, or you can ask the question directly and say, "Are you familiar with this term?" That can also sometimes be tricky to manage because you don't want to make it sound like you think they don't know anything. But you can also make it sound really natural in a conversation where you're like, "Oh, we're going to do this thing with a strategy pattern. Have you seen a strategy pattern before? Are you familiar with this? Great, let's keep moving." And if not, maybe it's like, "Hey, let's take a few minutes to talk about what the strategy pattern means." STEPHANIE: I think you are really great at asking the audience about their level of familiarity with the content, especially in book club. I have definitely experienced just as a developer pairing, or in meetings, or whatnot times when people don't pause and ask. And usually, I have to muster up the courage to interrupt and ask, "Hey, what is X, Y, and Z?" And that is tough sometimes. I am certainly comfortable with it in a space where there is trust developed in terms of I don't feel worried that people might question my level of familiarity or experience. And I can very enthusiastically say, "Hey, I don't know what this means. Could you please explain it?" But sometimes it can be a little tough when you might not have that relationship with someone, or you haven't talked about it, talked about assumptions about your knowledge or experience level upfront. And so I have found that to be a really good way to build that trust to make sure that we aren't excluding folks is to just talk about some of that stuff, even before we start pairing or before a meeting. And that can really help with some of those miscommunications that might come down later in the process. JOËL: It's interesting that you bring up miscommunication because I think sometimes, even though certain jargon can be very precise, sometimes people will not use it to mean exactly what its dictionary definition is. And so sometimes two people are using the same term, and you're not meaning quite the same thing. And so sometimes I'll be pairing with someone, and I'll have to sort of pause and say, "Hey, wait a minute, you're using the term adapter in a certain way that seems to be a little bit different than the way I'm using it. Can you maybe tell me what your personal definition is? And I'll tell you mine, and we can reconcile those two together." Sometimes that can also feel like a situation where maybe I'm hazy on the topic. Like, I have a vague sense of it, and maybe it does or does not align with the way the other person is using it. And so that's an opportunity for me to ask them to define the term for me without completely having to say, "I have no idea what this term is. Please, oh, great sage, explain the meaning." STEPHANIE: Are there times that you feel more or less comfortable doing that kind of reset? JOËL: I think sometimes the fear is in breaking flow. And so you're doing a thing, and then somebody is trying to explain something, and you don't want to break out of that. Or you're trying to explain something, and you have to decide, is it worth making sure to explain a term, or do you keep moving? So I think that is a big concern. And there is just the interpersonal concern of if there is less trust, do I want to put myself out there? Does somebody else maybe not feel comfortable you asked them to explain a term? Maybe they're using it wrong. It's not always good in a pairing situation to just come up and say, "Hey, that's not technically the adapter pattern; you're wrong. Let me pull out The Gang of Four book. You see on page 54..." that's not productive. STEPHANIE: Yeah, for sure. JOËL: So a lot of it, I think...and maybe this ties into your topic of communication while pairing. But ideally, you're working constructively with a person. And so debating definitions is not generally productive but asking someone, "What do you mean when you say this?" I find is a very helpful way to lead into that type of conversation. STEPHANIE: Yeah, that's a great strategy because you're coming from a place of curiosity rather than a place of this is my definition, and it's the right definition, and so, therefore, you are wrong. [laughs] JOËL: It's interesting the place that jargon occupies in our imagination of expertise. If you've ever seen any movie where they're trying to show that somebody is technically competent, they usually demonstrate that a person is competent by having them just spout out a long chain of jargon, and that makes them sound smart. But I think to a certain extent; maybe we believe it in the industry as well. If somebody can use a lot of terms and talk about a system using this very specific jargon, we tend to think that they're smart or at least look up to them a little bit. STEPHANIE: Yeah, which I think isn't always the best assumption because I've certainly worked with folks who did throw out a lot of jargon but weren't necessarily, like you were saying, using it the way that I understood it, and that made communicating with them challenging. I also think what true expertise really is is having the knowledge that when you use a jargony term that not everyone might be familiar with it, having the awareness to pause and ask someone how they're doing with the vocabulary and be able to tailor how you explain that term to that other person. I think that demonstrates a really deep level of understanding that doesn't get enough credit. JOËL: I 100% agree. Jargon, vocabulary, it's a means to an end, not an end in and of itself. So the goal is to communicate clearly to others and maybe to help yourself in your own learning. And if you're not accomplishing those goals, then what's the point? I guess maybe there is another personal goal which is to sound smart, but that's not really a good goal, [laughs] especially not when the way you do that is by confusing everybody else in the room because they don't understand you, to make you try to feel smarter than them. Like, that's bad communication. STEPHANIE: Yeah, for sure. I've definitely experienced listening to someone explain something and have to really think very hard about every single word that they're saying because they were using terms that are just less common. And so, in my brain, I had to map them to things that made sense to me, and things that I was familiar with that were the same concepts. Like, I was experienced enough to have that shared understanding, but just the words that they used required another layer of brain work. Maybe we could have found a happy medium between them communicating the way that they expressed themselves the best with my ability to understand easily and quickly so that we could get on the same page. JOËL: So you mentioned that there are sometimes situations where you're aware of a particular concept, but maybe you're just not aware that the term that somebody else is using maps to this concept you already understand. And I know that for me, oftentimes, being able to give a name to something that I understand is an incredibly powerful thing. Even though I already know the idea of passing objects to another object in this particular configuration, or of wrapping things in some way or whatever the thing that I'm trying to do, all of a sudden, instead of it being a more nebulous concept in my head or a list of 10 steps or something like that, now I have one thing I can just point to and say it is this. So that's been really helpful for me in my learning to be able to take a label and put it on something that I already know. And somehow, it cements the idea in my head and also then allows me to build on it to the next things that I want to learn. STEPHANIE: Yeah, absolutely. It's really exciting when you're able to have that light-bulb moment when you have that precise term, or you learn that precise term for something that you have been wrestling with or experiencing for a while now. I was just reminded of reading documentation. I have a very vivid memory of the first time I read; I don't know, even the Rails official docs, all of these terms that I didn't understand at the time. But then once I started digging into it, exploring, and just doing the work, when I revisited those docs, I could understand them a lot more comprehensively because I had experience with the things (There I am using things again.) [laughs] and seeing the terms for them and that helping solidify my understanding. JOËL: I'm curious, in your personal learning, do you find it easier to encounter a term first and then learn what it means, or do the reverse, learn the concept first and then cap it off by being able to give it a name? STEPHANIE: That's a good question. I think the latter because I've certainly spent a lot of time Googling terms and then reading whatever first search results came up and being like, okay, I think I got it, and then Googling the same term like two weeks later because I didn't really get it the first time. But whenever I come across a term for a concept I already am familiar with, it is like, oh yes, uh-huh! That really ends up sticking with me. Matheus Sales' blog post that you mentioned earlier is a really great example of that term really standing out to me because I didn't know it at the time, but I suppose was seeking out something to describe the concept of connascence. So that was really cool and really memorable. What about you? Do you have a preferred way of learning new technical terms? JOËL: I think there can be value to both approaches. But I'm with you; I think it generally is easier to add a name to a concept you already understand. And I experienced this pretty dramatically when I tried to get into functional programming. So several years ago, I tried to learn the language Haskell which is notorious for being difficult to learn and very abstract and technical. And the way that the Haskell community typically tries to teach things is learn the fundamentals first, very top-down, learn the theory, and then, later on, you can do things in practice. So it's like before you can write an actual program, let us teach you about applicatives, and monads, and all these things that are really difficult to learn. And they're kind of scary technical terms. So I choked out partway through, gave up on Haskell. A year later, got back into it, tried it again, choked out again. And then, eventually, I pivoted. I started getting into a similar language called Elm, which is similar syntax but compiles to JavaScript for the front end. And that community has the opposite philosophy when it comes to teaching. They want to get you productive as soon as possible. And you can learn some of the theory as you go along. And so with that, I felt like I was learning something new all the time and being productive as well, like, constantly adding new features to things in an application, and that's really exciting. And what's really beautiful there is that you eventually learn a lot of the same concepts that you would learn in something like Haskell because the two languages share a lot of similar concepts. But instead of saying first, you need to learn about monads as a general concept, and then you can build a program; Elm says, build a bunch of programs first. We'll show you the basic syntax. And after you've built a bunch of them, you'll start realizing, wait a minute, these things all kind of look alike. There are patterns I'm starting to recognize. And then you can just point to that and say, hey, that pattern that you started recognizing, and you see a bunch of times that's monad. You've known it all along, and now you can put a label on it. And you've gotten there. And so that's the way that I learned those concepts. And that was much easier for me than the approach of trying to learn the abstract concept first. STEPHANIE: Monad is literally the word I just Googled earlier this week and still have a very, very hazy understanding of. So maybe I'll have to go learn Elm now. [chuckles] JOËL: I recommend a lot of people to use that as their entry point into the statically typed functional programming world, just because of how much more shallow the learning curve is compared to alternatives. And I think a lot of it has to do with that approach of saying, let's get you productive quickly. Let's get you doing things. And eventually, patterns will emerge, and you can put names on them later. But we'll not make you learn all of the theory upfront, all the jargon. STEPHANIE: Now that you do understand all the technical jargon around functional programming, how do you approach communicating about it when you do talk about Elm or those kinds of concepts? JOËL: A lot of it depends on your audience. If you have an audience that already knows these concepts, then being able to use those names is really valuable because it's a shortcut. You can just say, oh yeah, this thing is a monad, and so, therefore, we can do these actions with it. And everybody in the audience just already knows monads have these properties. That's wonderful. Now I can follow to step two instead of having to have a slow build-up. So if I'm writing an article or giving a talk, or even just having a conversation with someone, if I knew they didn't know the term, I would have to really build up to it, and maybe I wouldn't introduce the term at all. I would just talk about some of the properties that are interesting for the purpose of this particular demo. But I would probably have to work up to it and say, "See, we have this simpler thing, and then this more complex thing. But here are the problems that we have with it. Here's a change we can make to our code that will make it work." And you walk through the process without necessarily getting into all of the theory. But with somebody else who did know, I could just say, "Oh, what we need here is monad." And they look at me, and they're like, "Oh, of course," and then we do it. STEPHANIE: What you just described reminds me a lot of the WIRED Video Series, five levels of teaching where they have an expert come in and teach the same concept to different-aged people starting from young kids to an expert in their field as well. And I really liked how you answered that question just with the awareness that you tailor how you explain something to your audience because we could all benefit from just having that intentionality when we communicate in order to get the most value out of our interactions and knowledge sharing, and collaborative working. JOËL: I think a theme that underlies a lot of what you and I have talked about today is just that communication, good communication is the fundamental value that we're going for here. And jargon and vocabulary can be something that empowers that but used poorly; it can also defeat that purpose. And most importantly, good communication starts with the audience, not with you. So when you work back from the audience, you can use the appropriate vocabulary and words that serve everybody and your ultimate goal of communicating. STEPHANIE: I love that. JOËL: So, Stephanie, thank you so much for joining us on The Bike Shed today. And as we wrap up, I wanted to ask you, what is a really fun piece of vocabulary that you've learned that you might want to share with the audience? STEPHANIE: So lately, I learned the term WYSIWYG, which stands for What You See Is What You Get to describe text editing software that lets you see and edit the content as it would actually be displayed. So that was a fun, little term that someone brought up when we were paring and looking at some text editing code. And I was really excited because it sounds fun, and also, now I had just an opportunity to say it on a podcast. [laughs] JOËL: It's amazing that an acronym that is that long has enough vowels in the right places that you can just pronounce it. STEPHANIE: Oh yeah. JOËL: WYSIWYG. That's a fun word to say. STEPHANIE: 100%. I also try to pronounce all acronyms, regardless of how pronounceable they actually are. [laughs] Thanks for asking. JOËL: With that, shall we wrap up? STEPHANIE: Let's wrap up. JOËL: The show notes for this episode can be found at bikeshed.fm. This show is produced and edited by Mandy Moore. If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. If you have any feedback, you can reach us at @_bikeshed, or reach me at @joelquen on Twitter, or at hosts@bikeshed.fm via email. Thank you so much for listening to The Bike Shed, and we'll see you next week. Byeeeeeeee!!!!!! ANNOUNCER: This podcast was brought to you by thoughtbot. thoughtbot is your expert design and development partner. Let's make your product and team a success.

Up Next In Commerce
Becoming More Than a Brand Inside and Out

Up Next In Commerce

Play Episode Listen Later Aug 12, 2021 45:15


Everything you put out as a brand should be interesting, it should be relevant to your consumer, and you and your employees should be proud of the final product. So why then are so many brands finding that the people who work so hard on and actually create the marketing materials aren't sharing the end result? Max Summit is a marketing consultant who has worked with some of the biggest brands in the world — Adidas, Lululemon, Athleta, the list goes on — and regardless of the brand, whether they sell online or in brick and mortar, Max knows that true connection with customers start with the connection to the internal employees. On this episode of Up Next in Commerce, Max discusses all the ways that brands should be doing internal pulse checks and reinventing their mission in order to make their marketing materials hit home with consumers. Plus, she explains how brands should be thinking about ways to become resources for customers beyond just being a provider of goods and services, and she gives examples from her days at Lululemon that any company can learn from and where VR and AR can come into play. Enjoy this episode!Main Takeaways:Who's Sharing What?: To gauge the health and success of your company's creative, doing an internal pulse check is necessary. Are employees sharing the work they have produced? Are they proud and willingly talking and posting about the latest project they are working on? Do a post-mortem to gauge how a project went, what aspects were wins and where things could have gone better and allow everyone to share freely and openly how they really feel.Who Knows What?: The boots on the ground at retail stores are often the people with the most knowledge of the consumers and what they want. Brands need to create a more connected communication structure that allows everyone in retail to interact with HQ and the ecommerce team to paint the most holistic view of the customer and then create products and marketing content for them.Who's Engaging with What?: One of the biggest struggles brands face is getting consumers to engage both initially, and long-term. So brands have to hook a consumer quickly, and keep bringing them back with an interesting, exciting, and valuable experience. Virtual and augmented reality experiences are a recent way that brands have been solving this problem, and the creativity and utility that VR and AR offers sets the table for it to be a major way that brands and consumers interact for years to come.  For an in-depth look at this episode, check out the full transcript below. Quotes have been edited for clarity and length.---Up Next in Commerce is brought to you by Salesforce Commerce Cloud. Respond quickly to changing customer needs with flexible Ecommerce connected to marketing, sales, and service. Deliver intelligent commerce experiences your customers can trust, across every channel. Together, we're ready for what's next in commerce. Learn more at salesforce.com/commerce---Transcript:Stephanie:Hey everyone, and welcome back to Up Next in Commerce. This is Stephanie postles, CEO at Mission.org and your host. Today on the show we have Max Summit, who is a brand marketing consultant. Max, welcome to the show.Max:Thanks Stephanie, I'm really happy to be here.Stephanie:I'm happy to have you too. So with you, I want to start back in your personal story. Growing up in Brazil, you have a very interesting story around medical issues and growing up in this very creative household, very intriguing household. So, I want to hear just your background before we dive into what you're doing today.Max:Sure. Absolutely. Let's see, the elevator pitch here. So I was born in Boston, but actually raised in Brazil. I am the proud daughter of a ballerina turned designer my mother, and my father was very musically inclined, he had a lot of passions around art and music even though eventually he really poured I think the majority of his time into tech and entrepreneurship. But my upbringing in Brazil I think was anything but traditional.Max:My stepbrother and I, we used to spend our summers down in the beach barefoot on the sand, falling asleep to the stars at night. My granddad would sometimes pick us up after school on a Friday, we would drive down to the beach and we'd spend the weekend on the boat, which was awesome and really lovely. I think as a child, you take in these experiences as they come but when you live as an adult, you oftentimes, I think, look back and reminisce and you think, "How can I also provide that for the next generation or for myself and my own kids?"Max:So yeah, I think it was a very interesting upbringing, very dynamic, I think absolutely it was not traditional by any means. I think that existence and that relationship that I was taught at a young age to be embracive of nature and be embracive of human experiences I think ultimately led me down to this path in brand marketing unknowingly, but that's where I am today is just really embracing, I think, storytelling and identifying the unique patterns and behaviors of organizations that can really communicate something to the world and to the people around them in a way that I think makes sense for today's audience and today's consumer.Stephanie:Yep. Yeah. I love that. I'm just having an entire movie playing out in my head, imagining you on the beaches also now I'm like, "I need to go to Brazil. That's the next step for me?"Max:Yeah, it's funny. I'm definitely painting a more poetic existence, I definitely think my brother and I, we were quite mischievous as well as I think that playful character and that playful nature, I think also lends itself well for a role in marketing. Although sometimes in a leadership position, you can't be as playful as you like to be, but it's definitely I think helped me get to where I am today, for sure.Stephanie:I love that. And tell me a bit about, I know you had a medical scare I think it was around 15 or something. And I was reading a quote where you're saying, "That changed the way I thought about everything," and I wanted to hear a bit about that because I'm sure it's impacted even where you're at today.Max:Yeah. Absolutely, as I said I grew up in Brazil, sports I think is very much a part of the culture and the DNA there. I did everything from soccer, to swimming, to [inaudible], and eventually I think I really found my place in volleyball. That was really the sport where I felt most comfortable. Again, I had great mentors and great coaches who identified long-term potential and I think saw an ability for me to do it even professionally at some point in my life and my family and I really invested a lot of time and energy going to games, getting the proper coaching, the proper training. And I was in a final match, a pre-qualifier for you to be on the national team.Max:And I came down from a jump serve and I remember hearing this massive, shattering pop that went from my ankle all the way down to my hip. And essentially I ripped six ligaments on my leg, my achilles, my hip tendon, my ACL and my MCL, you name it and eventually it was just one go. And it was in that recovery phase where in post-op I went through surgery and I was recovering, and we're flying back from Brazil where my leg really began to swell and the pain intensified over the course of the plane ride.Max:And when we landed back in Boston, it had really gotten to a place where it felt extremely uncomfortable and my mother and I, of course back then there wasn't a lot of research and knowledge around clotting and how that happens postoperatively and how flying can sometimes intensify that. So, I think we were really uneducated around some of those medical complications that you can face, so we shrugged it off as it was a 13 hour plane ride, your leg is probably swollen from the compression or decompression.Max:We didn't really think much of it and we went to bed, and I woke up in the middle of the night really screaming, had really intensified pain, not really understanding what was happening. And I remember my mother was really rushing up upstairs because I was calling for her, I was yelling like, "Mom, mom, mom, something's wrong." And when we pulled the sheets over, my leg was gangrene. It was blue, black, every color that you can imagine I think all the capillaries were just exploding subcutaneously.Max:And one of the last things that I remember was actually my mother grabbing me by my shoulders to try to calm me down. And this feeling of almost, I would say I think I'll use this on the interview as well, like a champagne cork when it explodes, it just happens in an instance. And when that sensation happened, everything just melted away and what we found out weeks later when I woke up in the hospital, was that the expansion of the leg was really what's known as a DVT, a deep vein thrombosis.Max:And the clotting had literally originated from my ankle and had gone all the way to my knee and a piece of it dislodged and went into my lung. And when that happens, your body's deprived of oxygen and it shuts down, and I experienced all of this at age 15, which I think for a normal 15 year olds everyone is planning prom, everyone's playing around their first boyfriend. If they're lucky, maybe they're celebrating their one year anniversary with their high school sweetheart. And for me, I spent the majority of my 15 years in a hospital bed at Mass General in Boston.Max:I think the realization of life and how fragile it is and how limited our time is, and it can be on this planet, I think was reintroduced to me at an age where most teenagers aren't thinking of that. And I think it's allowed me to move through the world a little bit more intentionally, and in a way I think I've been seeking a greater sense of purpose since so that if I were to find myself in another hospital bed hopefully I won't have as many regrets or as desires as I thought I had at age 15.Stephanie:Wow. Wow. I have goosebumps with your story right now. I feel like we could just make that the entire episode, talking about how to live an intentional life. Oh my gosh, that's wild. Yeah.Max:Definitely. I think if anything too, COVID has in a way, I think shed light for a lot of individuals. I think a lot of families, a lot of my close friends and even professional mentors, I think everyone has used this as an opportunity to self-assess and to reevaluate and really measure the scales of lifeStephanie:That's amazing story. So, I want to dive into the brand aspect of things. You said an interesting quote early on before the interview, that you stumbled into it, you did not plan to get into this world, but when you look at your roster of brands that you've served, it's wild. So, first talk about how you got into this world and also some logos just to show people you know obviously what you're doing.Max:Sure. I'm definitely lucky, I'm going to say I think luck is a big aspect of it. But yeah, essentially I studied philosophy and English in college which is so bizarre to think that someone who studied those two fields would eventually end up in marketing. But I think the way everything cascaded and fell into play was really at the root of it was just having fantastic leaders and mentors who identified my potential, who I think understood the reward that comes with molding someone and bringing them into the process and giving them the right opportunities that I think really shed light on their personal aspects, but also their professional aspirations.Max:And the way I fell into this industry was, so actually I started in non-profit worlds, really volunteering, taking gigs as they came mostly in the creative parts. I did a lot of pre-production post-production work then I eventually went into graphic design, I did a graphic design residency for about two years and then eventually got pulled into copywriting then from copywriting I did video. So, doing the gamut of all the art functions and I realized in that process it actually sucked at all of them. I was like, I was good enough to have a general understanding at introductory level, but I very quickly on realized that I was never going to be the director of copywriting or the director of photography-Stephanie:Which is a beautiful thing, because it answers a lot of questions for you. I've had many of those experiences where I'm like, "Well thank you life for showing me that's just not my thing and I can move on now know."Max:Yeah, and also it takes a lot of vaping gut too, to tell yourself, "I suck at something."Stephanie:I'm going to own it, I suck.Max:And I need to find something else that I enjoy, but I knew that I wanted to be in a creative function. But I think ultimately what was missing, I think from all those experiences was the afterthought. So, the strategic side of it and I got my foot in the door actually as a freelance graphic designer working at Adidas. And the way that happened was really through networking. So, when I said that I was really hustling and trying to get gigs on the side, that's literally what I was doing, I was identifying meet and greets that's right. I used meet and greets, which back then was meetups.com at work in my local community.Max:I would raise my hand, any volunteer opportunities for races or local community events. At the time I was living in Boston, and Adidas was a big sponsor for the Boston Marathon. And again, I raised my hand and said can I do any graphic design work? Do you guys need help as a volunteer, it was just saying yes until someone and something was willing and ready to bring me on board. And I started as a volunteer graphic designer and from there that role quickly became a little bit more robust in nature. So, one project led to another, it went from being freelance graphic design to, would you like to support us at a photo shoot? Would you like to do some post production work for us, some casting?Max:And things just fell into place, and it took a very wonderful mentor and a very lovely boss like I said, to really identify that potential in me and tapped me on the virtual shoulder and said, "Hey, I think your place is actually in brand, it's not in creative," which like I shared with you guys I knew that already, I sucked at all four fields. But I hadn't yet gotten that golden offer, that golden ticket to come in full time and he offered me a job. He said we're starting a new division at Reebok.Max:At the time he was moving over from the Adidas side onto the BU classic side I'll be overseeing the division there and we need a brand manager would you like to take a chance on life and take a chance on this opportunity? And needless to say, I said, yes. And things really cascaded and fell into place after that. And just to throw some logos out there like you asked from Reebok, I went to lululemon, from lululemon I then joined a much smaller, but reputable brand in Canada called Lolë. And then from Canada, most recently I was the director of marketing over at LA Athleta, which is a [inaudible] company.Stephanie:Wow. Yup, yup. Awesome logos of course, which is why I was like, "You have to name drop them." That's a really fun story about getting that invite and having someone bet on you before you even knew if you could enter into that world. I want to talk about brand in general and defining a strong brand, because you've worked at some amazing companies now who have done just that and they've been able to develop this following and stay true to brand. And you just see the cohesiveness when you look at what they're doing everywhere, you get it instantly. So, what do you think defines a strong brand today? How do you go about building that?Max:It's a great question and it's definitely evolved. I think when I first started my career in this journey working in performance sports, endurance sports, I think it was very much benefit led marketing. So, it was really about the best shoes takes you on the longest run. Sometimes you got the occasional, this is the shoe that was designed by Michael Jordan. There's a little bit of that celebrity persona aspect of it, but when I really began this journey, it was very product marketing. It was very benefits led, it was a very simplified message.Max:I think there were very little brands that understood and promoted, I think mission driven content and purpose led communication. Nike, I think was one of the first in the industry to package that up and present it in a way that was digestible to the consumer. I think where we're at now today is most brands if not all, I think need to have a purpose led message or at least a mission driven DNA aspect of their brand. I think consumers are demanding more out of brands, I think that now more than ever they're equipped with knowledge and the tools to actually do the research.Max:Which I think before, oftentimes again, the brands really held that power. They could really decide if and when to release messages around sustainability, messages around diversity, equity inclusion everything was very much calculated I think 10, 15 years ago in marketing. Now, if consumers can't find that information on day one on your website or through your social channels, they'll walk away and they'll go to another brand whose mission and purpose is more overtly available on site as well as in their social channels.Stephanie:So, when you're approaching brands that maybe don't already have this, how do you go about it in a way that keeps it authentic? Because, throughout all the things that have been happening in the past year or two, maybe you see brands quickly trying to lean into something and be like, "Oh, we're in that space too, we're doing that well." And then a lot of them end up one week later, two weeks later or whatever it is it's gone and that can actually do more harm probably than not having anything at all. So, how do you approach that, because it feels like a tricky space to play in?Max:It is. And I think it's definitely a hard question that you have to ask yourself and your organization, what are you as a company uniquely qualified to give to the world? Because, I think it is that unique nature that me as a brand marketer can package up and I can create a strategy behind and a communications and really elevate that and present that to the rest of the world. I think the brands that are struggling like you mentioned some were having to pull back.Max:Other brands that aren't having those honest conversations with themselves, I think their desire to want to jump on something that is currently mainstream but not necessarily an element that trickles down back to their DNA and their structure and their organization. It doesn't take long before it's a domino effect. It doesn't take long before you see all of the pieces falling at the same place. But I think really identifying what you as a company are most uniquely qualified to deliver to the world and to your customer, I think that is the hardest, if not the most important conversation that you can have and you can also give to your marketer.Stephanie:Yep. Yep. How do you go about measuring how a brand is doing? So, I'm thinking about what consumers say versus how they really feel, a good quote, maybe not a quote, but a summary from the CMO of UPS, they came on another show of ours and they said that they had really good brand recognition, people trusted them, but a lot of their consumers saw them as an old and stodgy company so they had to rethink their marketing because of that. But I'm like, if you would've just heard the first piece of oh, we have a great brand, recognition and trust, I'm just going to stop there, I'm good. Versus, getting into the details of, and it's a yes and they also think this, how do you go about measuring a brand's performance or how the consumers actually view them?Max:I love that quote too, taking a soundbite and turning it into an actionable insight. I will probably say something's that's a little bit more controversial, but that's in my nature.Stephanie:Yeah, I love that.Max:I love internal employee pulse checks. I think for me, the true measure of whether your work is adding any value or is exciting people is whether or not your employees are naturally promoting that work. Very often it does not happen, you would be shocked how many times even sitting in a marketing function living it day in, day out going through the blood, sweat and tears will team members refrain from posting. I think it's just there's very little work that I think is being put out into the world today where employees take pride on wanting to showcase it and really wanting to advocate for it.Max:So, my way of measuring success is if you can take a head count around the table, and if every member from your team posted, shared it, communicated, was proud to wear it as an emblem, I think you've succeeded in your role first and foremost, if you're just relying on that customer, if you're just relying on that external feedback again, I think you failed as an organization and as a mentor and as a leader internally.Stephanie:Yep. Yeah. I love that. That's really good. I'm thinking about different types of companies that probably definitely have an easier time. I'm thinking the non-profit world, people go there, maybe not always getting paid the highest, but they are there for a mission versus maybe other companies where people are there for the money or it's a trend. How do you think about actually getting that feedback? Are you literally going around the room being like, "Did you share, did you share?" Or how do you do it at scale if it's a team of thousands?Max:It's so great, I love internal surveys. I think anytime I always loved doing postmortems after a campaign or after we deliver an action, because sometimes it doesn't have to be a piece of creative content. It could be a public commitment, that you as an organization decided to make and that structurally made sense. And I've actually found that oftentimes employees are more willing and ready to share public commitments than they are with pieces of content, but anyway to answer your question, I'm a really big advocate of doing postmortems and in those postmortems, I think an internal employee pulse check with a survey I think is most often the best way to conduct that type of review process.Max:I also found that allowing employees to share feedback anonymously, I think helps exponentially and I think people are always more hesitant to put their name behind the feedback, but I realized very quickly in my review process that the moment I allowed people the freedom to actually say what they really thought without having to put their name behind it, I think the amount of feedback that we got was just astronomically higher, I think by nature.Max:I also really love when we are speaking about obtaining external feedback, I think social media has done a great job with that. Depending on which channels your organization is most active in, for me Athletic Apparel socials the epicenter right now, over all the community activities happening. I love doing pulses and customer surveys on Instagram. I think it's such a great way for you to get feedback in real time, which can also be very eye-opening right. Max:So, when you capture your audience's attention, you have a brief second to really engage with them. And if they've already made that first move, I think that to me is a lot more telling for a brand and organization than if you were to conduct customer insights and this extensive six month interview process where you're most likely bringing in individuals that aren't actively engaging with your brand. But on that aspect, I will tip my hat to Instagram I think for introducing that feature a thousand times over again, I've actually used it numerous times, not only for feedback on creative and campaigns that we've brought to market, but also as a way to guide our strategy.Max:So, I love doing polls where we basically ask our community what content would you to see us produce more? And sometimes the answer doesn't have to be very philosophical, it can be very direct, it can be very simple. And the responses that you get can actually dictate the course of almost an entire season. And I definitely have done that before.Stephanie:Yep. So, are you doing that for some of the brands like Athleta, and how did you structure the polls to get actionable feedback?Max:Yes. I think Athleta is a great example, especially during COVID right. It's hard to think back where I was a year and a half ago, but I remember having just moved to San Francisco for the job. I think I was in the office for a total of seven and a half days. The city just shut down and no one knew what to do. The organization didn't know what to do. I think as employees, I think everyone was in a standstill, but again, the community and our audience demanded responses, they demanded actions. And I think our social media team, I think definitely held the grunt of that work, they're at the battlefields, every single day whether it's delivering good news or tapering and bad news.Max:And so, I think there was a lot of immediate and actions that we took and we really utilize social, I think, to dictate the course of how we would, I don't want to use the word market, but really communicate where we were as an organization, because everything was at a standstill for 30 days. And it was really through that engagement and those backend DMs, those poll surveys, and I think we really found power in the voice of our community and we also understood what it really meant as a brand to show up for your community.Max:So, one of the things that quickly became evident as the city started shutting down was that the majority of our members at Athleta were business owners, female owned businesses, which some of that meant that they own their own studios, yoga studios, gyms studios, and those were the first to be impacted by COVID. And so, how do you as a brand support that community in a way that isn't related to product and I think for Athleta, being under the umbrella of Gap Inc we decided to really create a financial resource for a lot of these female owned businesses, where as a member of the Athleta community, you could apply for a grant or a funding that could really for some moms and for some women could really help keep their business afloat for the foreseeable future, which is where we were at the beginning of COVID.Stephanie:I love that. And did you find out more about who needed that help or what help they needed through social media, like you said, through those DMs?Max:I would say a combination of social media and our retail teams. I think especially working in the Apparel industry, we forget that retail is not dead. And if you have a retail structure that is highly connected to your community, they oftentimes know more about your consumer than you do sitting at HQ. And it's really that share-ability from the boots on the ground, I hate using the word bottom up, but I think that's really the mindset.Max:So, let's [inaudible] this top-down mentality and really about what are you hearing? What are customers saying when they're coming to your door? What's the feedback that you're receiving in store? I think that's really pivotal and I think that was really the feedback that was necessary for us to translate that into actionable insights as I call it.Stephanie:It seems there's still going to be so much work around getting those insights and incentivizing the employees to share that, but now consumers are basically coming to any retail shop expecting the same thing that they can get from online. It's like, yeah, of course I should be able to have this. Of course, I should be able to see inventory, talk to you quickly get what I want, but I see there's that catch up to even just going in different stores around Austin right now and being like, "Oh, this still feels like 2019 right now. What are we doing here?" How do you see that evolving?Max:It's also fascinating too, because you bring that up. Your store experience in Austin will probably be much different than a store experience in San Francisco. And even under the context of COVID, I think that's going to feel a lot more amplified as well in today's industry. I think what that touches on is really what I love to refer to as a decentralized model, where I think what we're witnessing in marketing and in omni-channel experiences and retail experiences is these little pockets, these little hubs of community oriented messaging and team structures.Max:So, a retail store is no longer just a retail store, it's actually a space for you to welcome members of your community, I think it's a space for you to engage with local businesses. That was actually an aspect that I love the most about working at lululemon was just how they really understood, I think the power of community and how a retail store could actually be an extension of that local market or that local demographic. And it didn't have to just be a place for business transactions, it didn't have to be a place just for you to go in and buy stretchy yoga pants as everyone likes to say.Max:For some, it could be a resource. I took a trip down to Key West Florida, of course this was before the pandemic happened. And I wanted to know what yoga studio to go to, what coffee shop I should go to, and the first place I went was to a lululemon store and ask their community members, 'Where do you go to work out? Where do you go to get coffee?" And it's just amazing how I think retail environments have become a source of information for a lot of members of the community. And I think the brands that are adapting to that mindset, I think are the ones that will really in the end come out winning and will be stronger I think in today's industry.Stephanie:I love that, such a good example. How does a company do that though? How does the brand pull a piece of the playbook from lululemon and create that community, do it in a way that people actually want to engage with, they trust it where they'll go and ask advice like where's the best coffee shop and buy from it. You essentially nailed every aspect of what every brand probably wants, but what do they do differently to get all of that?Max:I think it comes down to the original question that you asked me, I think a few minutes ago, which is, I think it's just having that honest conversation as an organization as to what are you most uniquely qualified to give to your audience? And I think for lululemon, again, I'm probably not in a place to speak about this because I wasn't there in its inception, but I can only imagine that when the founder sat down and analyzed that exact question, I think they knew that the power rested in community, so they made a conscious choice to really embed that in the organization's structure, as well as their brand DNA.Max:And I think from that brand values the mission statements evolved and it serves as a filter, as you grow and expand, I think for a brand that maybe is not rooted in community and is wanting to maybe shift into that world, I will continuously say that, I think you need to ask yourself are you in a place that you can authentically play in that ecosphere, because if you can't be authentic then I really don't think you should invest the time. I think you should really, really embrace what makes you unique and what it is that you can deliver to a customer in a unique way.Stephanie:Yep. Yep. I love that. So, earlier you were talking about Instagram is where it's at, it's got all these amazing features that can help a brand learn about their audience, answer all the questions they need. What else are you betting on? What other platforms are you bullish on right now?Max:VR, virtual experiences augmented reality. I am so excited for that future. I think if anything, COVID and remote living and brands having to force themselves, how else can we engage with brands that is interested in ecommerce platform and think have really forced us to reconsider other ways to bring customers along the journey and the creative experience. And I think augmented reality has certainly put us in a place I think of a lot of excitement.Max:My favorite to date has really been the Billie Eilish and the Moment Factory partnership, they created an out of this world, no pun intended experience where they really transported her audience and her fan base into this imaginary world. And the question was really what happens to you when you fall asleep? So, it was really this dream like state and it was just, I think, a beautiful representation of what the future of content can look and feel like. And at the same time, I think it really challenges this archaic notion that digital experiences don't create meaningful connection.Max:Which I actually think having VR and having augmented reality has really challenged that way of thinking, because it can absolutely transport you into a different world. It can absolutely create an emotion and it can also create an action. And I think that universe excites me tremendously, and if I could shift my focus and my attention, I think it would really be in a place where I'm playing day in and day out with that type of environment, for sure.Stephanie:Oh, I love that. This is something I've been looking into more from the crypto side and the cities, same, same though. I was learning all about these digital land sales and getting in there early, they're building this entire world and people go and interact there and do essentially commerce in this world, but to think about it from a brand perspective, how can a brand play in VR because Billie Eilish, I get it concert go somewhere to a different land, I love the idea, but if I'm a brand, what opportunities do you see right now?Max:Well, I always think back to yoga of course, because I worked for one of the best yoga brands in the world, but I think again, not wanting to go back to COVID, but I think COVID really shed light on our inability to go outside, and again, be in studio and being in environments that felt very natural to us. And again, I'm speaking in these terms assuming that you're probably the athletic person who does yoga, but if it's not yoga, it could be you wanting to go to a restaurant or a concert or whatever it is.Max:But in the context of yoga I think there were a lot of studios that were actually introducing this notion of virtual reality in which that even though you couldn't physically be present in the yoga studio, you could absolutely be transported there. And I think, again, it was a way to just create that connection and create that meaning and really bring people into one digital world that really felt physical visually.Max:And I think the brands that understand and harness that power, I think they'll start using that as a mechanism potentially to either create content. So, one way that I could think this coming to life, and actually it was one of the first big projects that I worked on at Reebok. At the time Google and YouTube had just started partnering on VR experiences and we did an entire documentary campaign experience, where we brought audiences basically along the ride for four emerging athletes.Max:And it was really a way again, for you to be transported into the physical spaces in which they train day in and day out. And I think for a customer to have that behind the scenes look, it's really one of a kind. If you can imagine this in an era of a Michael Jordan, to have that unfiltered access to an athlete before or after, or even during experience, I think that's a great place to be in, in terms of VR experiences and building that digital world and that digital infrastructure for at least athletic brands, which is where I operate in.Stephanie:Yeah. I can imagine so many different experiences to leverage [inaudible] not just from shopping, that's just the after effect of bringing in customers from all over the world and at the same place, instant way to build community, meet people. I think that's what COVID taught everyone, is we were in our own little bubbles and we'd gotten to this place where the only time you maybe saw people who didn't live near you, was in work meetings. And then all of a sudden you're like, "Oh, but now I need more community."Stephanie:And now it's actually my work friends I need. And so, starting to broaden that, going into a whole different world and being able to have an experience together, you vet your community and then you can also shop while you're there and maybe even change the experience as well, where it's, try that on for me. Oh, I'd like to see a model showing me this outfit who looks like me, this entire thing of shaping where you're at and be able to control it too.Max:I love that. And I think Warby Parker did that.Stephanie:Oh, did they?Max:Yeah. I think before any other brand caught onto that, the idea of essentially creating a virtual experience in which you could try on the products. And I think that notion that you, and I think you actually said something that gave me goosebumps, that idea that you could in real time see the product on someone that looked and felt like you, I think that's really important as well. And I think that's a shift that we're seeing more and more. And I think if anything, I would give credit to VR for building that and putting that at the forefront of conversations and marketing, for sure.Stephanie:Yep. Yeah. We're going to be looking back and be like, why did we just look at, oh, this model is 5'4 and 100 pounds. And me being like, okay, so that's not me. So if I was much taller and bigger, how would it look on me? How would it flow? We're going to look back and be like, "Why did we ever buy things based off of one picture? I want to see how it moves and fits and looks on someone." And I should be able to choose that experience if I'm not going in the store and trying it on every time there should be no return rates from our products.Max:I love it, do you want to work in marketing?Stephanie:Let's do it, I'm down. So many ideas I realized on the show, I'll just give everyone ideas and maybe someone will implement one of them. Every one of a thousand is an okay idea of mine. Super fun. Yeah. I love thinking about that stuff. All right. The last thing I want to touch on was what brands are you watching to keep an eye on the industry? Who's doing a really good job when it comes to branding where you're like, "I keep tabs on them every week to see what they're doing?" Maybe someone you've worked for.Max:Oh my God, that's such a hard question. It's interesting, I think I'm going to go outside of my respected industry. I'm really fascinated by what Spotify and Netflix have done, I think to the industry. I think Netflix has really capitalized on an audience-based as well as on a perpetual habit that I think we as consumers are starting to have more and more of in this digital age, and they've just managed to build this empire that I am so in admiration of, I also love what they're doing as a platform in terms of exposing younger audiences to different types of content with documentaries being at the forefront, I am a huge advocate of documentary.Max:In fact, one of my first experiences was working in post-production for documentaries. And I think I give them so much credit for just having that vision, having that ambition. When I think back from where they were 12 years ago or [inaudible] first heard their name and where they are today being nominated for Oscars and just the amount of insights and data that they have on us as an audience and as a viewership and how they translate that data into building out specific content programs and building out specific platforms on their channel, everyone else is chasing them and I think that was a gift.Max:To me, they're the Kleenex of the, they're probably going to hate hearing that, but they've defined online streaming. The idea and the notion of online streaming did not exist before Netflix came into the picture, and all brands now are chasing them and they want to compete. And I think that's a brand that I go to, I think, as a source of inspiration, which is weird to say, maybe it wasn't what you were hoping to hear.Stephanie:Oh, actually, when you said that I'm like, oh, obviously you're watching Formula 1. You're seeing the brand and the content angle and then you can go to the whole platform play, which also equally is inspiring. We've written entire stories of mission around Netflix and how they basically killed off their entire revenue stream to bet on another big one and inspiring all around. So, I love-Max:I agree. It's thinking big, bold and audacious and just watching the ripple effect happen. And I think they're definitely a brand that I go to inspiration. And another one is Spotify, again, I think the brands that excite me are the brands that understand their customers and they're catering their business decisions based on that understanding. There's no better brand that exposes and showcases that as Spotify, even the types of content and the marketing campaigns that they're putting out there all originally from their customer insights comes from data. And you got to give credit, I think, to a tech company like Spotify, where they're consistently operating in this multi dynamic world.Max:Because, if you can only imagine between licensing music rights and managing talent and branching into podcasts as well as music, it's got to be a living nightmare. Every time they have the opportunity to put a piece of campaign out there, a piece of content it's so powerful and you can see it from a share-ability aspect, from an engagement aspect, people are excited, people are waiting for it. Again, it's so simple their marketing but it's so effective and it's done in such an authentic way. Again, it comes back to that topic that you and I were talking about. It's authentic in nature to who they are as a brand, as well as a business. And I really admire them for that.Stephanie:Yep. Yeah. I love it. Anyone who wants to hear more about Spotify, we had their old CMO on, he's not their CMO now, but Seth, it's a good marketing trends, the podcasts it was really good. I think we did two parts with him and he was epic and you're like, now I know why the company is where it's at now and all of the decisions that were made to get them where they are now. Cool. All right. Well, let's move over to the lightning round. Lightning round is brought to you by Salesforce Commerce Cloud, this is where I ask a question and you have a minute or less to answer. Are you ready?Max:Yeah, I'm prepared.Stephanie:Okay. Get amped up. First one. What's up next on your reading list or your podcast queue?Max:Oh, great. Where the Crawdads Sing.Stephanie:Where the crawd... I have not actually heard of this one, I'll have to look at that.Max:I have it right there on my shelf. Yes, I bought it two years ago, It's collected dust, but I've made a commitment to finish it before the end of August. So, that is on my reading list for sure.Stephanie:Wow. Good reads a million votes, 4.8 stars. That's very good one. Cool. All right. If you were to have a podcast or show, TV show, movie, whatever you want it to be, what would it be about, and who would your first episode or guest be?Max:I think I'd have to do a podcast that is centered around people, places and products and how each of those define the course of your existence and how they really shape who you are as a human. And I feel anyone could speak or relate to any one of those elements and [inaudible].Stephanie:I like that. Who should be the sponsor for that? You already probably have a couple in mind.Max:I don't know, I've actually never been asked as a question. I don't know, maybe something will originate here.Stephanie:Yeah. There you go. Here comes the show, anyone who wants to sponsor it, Max is ready for you. What is the biggest disruption coming to ecommerce over the next year?Max:Hands down, virtual experiences.Stephanie:Love it. We already know your love for VR, so that makes sense. Next one, what is the nicest thing anyone's ever done for you?Max:I've had a lot. I was working at Reebok, I had a really tough day, it was the first time I cried in a bathroom. You know when you just want to hide your tears, you go to-Stephanie:I've been there, corporate life.Max:And I stumbled across someone who worked across from me and she asked me what was wrong. And I said, "Nothing everything will be okay," as we usually do. And the next day when I showed up, she bought me daisies, which she knew were my favorite. And she had a little bouquet of daisies there, and with a little note, and I had only interacted with this person once. And I thought it was just such a genuine kind gesture, and I've carried that moment since.Stephanie:I love that. That shows how such little things can literally impact someone's entire life. And this person listening, I hope they're out there so they can realize well-Max:[inaudible] bad-ass now, so you snagged a good one.Stephanie:I love that. That was great. All right, Maxwell, thank you so much for coming on the show, sharing all your brand knowledge, where can people find out more about you and maybe even hire you?Max:So, they could visit me at maxsummit.com. Yes, that's right. I've basically bought out everything that has my name on it.Stephanie:That's a good brand.Max:It was my little own brand marketing.Stephanie:Love it.Max:Yes, and my website you can visit at maxsummit.com. I'm also on LinkedIn again, Max Summit you can always find me. If you Google Max Summit, I'm probably Max Summit, Instagram, Max Summit LinkedIn, Max Summit Twitter, Max Summit at Yahoo, Max Summit at Gmail.Stephanie:There you go, Myspace, all the things.Max:Yeah. I'm Max Summit everything, but I love connecting with people, I love building stories. Even for virtual connects or coffee, it doesn't have to be business related, I'm open and I'm here.Stephanie:I love it. Thanks so much.Max:Thank you.

Up Next In Commerce
Coffee, Cults, and Commerce; Lessons Learned Breaking Into a $465B Industry

Up Next In Commerce

Play Episode Listen Later Jul 29, 2021 46:18


What's hot today might be out of the zeitgeist tomorrow. Are people still doing goat yoga? Are skinny jeans really the new mom jeans? There are so many trends to keep track of and so many “next big things,” it's impossible to know what's real and what's just a passing fad. For a business, it's important to understand the distinction, and it's even more important to have products that will thrive regardless of the different cycles your industry will run through. Lopa van der Mersch says she has that kind of product with her company, Rasa, which makes a coffee alternative with adaptogen blends. Lopa has a fascinating story, including inadvertently entering into a cult, navigating tricky co-founder relationships, and building up a business to more than $2M in revenue all from her garage.On this episode of Up Next in Commerce, Lopa explains why she believes that her product will be a game-changer regardless of societal trends, and she breaks down how to spot something phony or bad for you, whether it's in a product or even in a partner or personal relationship. Enjoy this episode! Main Takeaways:Finding the Right Match: When partnering with a co-founder, especially one who is a close friend, some things you should consider are their skills and their ability to resolve conflicts. Ask yourself would you hire this person to do this job if they were not your friend? And think back to how you have handled conflicts with each other in the past. If you are comfortable with the answers to those questions, you can feel more confident in that person as a partner.Culture Shock: Growth in any industry is related to what is happening in common culture. When something is trending, a corresponding industry will rise. Today's society is focused on health and wellness more than in the past, so companies that deal with products in that space are on the rise. But to stay solvent even when the trends change, companies need to ensure that they have products that are worth something and add to a person's life regardless of whether it's trendy or not.Let It Come, But Also Go After It: Striking the right balance between organic growth and focusing energy and money into specific channels is difficult. The key is to make sure that you are diversifying your efforts wherever you choose to try to gain attention. Play with the levers of what's working in one area, but continue to invest elsewhere so that when one thing begins to fail, you have other options. For an in-depth look at this episode, check out the full transcript below. Quotes have been edited for clarity and length.---Up Next in Commerce is brought to you by Salesforce Commerce Cloud. Respond quickly to changing customer needs with flexible Ecommerce connected to marketing, sales, and service. Deliver intelligent commerce experiences your customers can trust, across every channel. Together, we're ready for what's next in commerce. Learn more at salesforce.com/commerce---Stephanie:Hey everyone. And welcome back to Up Next In Commerce. This is your host, Stephanie Postles, CEO at Mission.org. Today on the show, we have Lopa van der Mersch who currently serves as the founder and CEO of Rasa. Lopa, welcome.Lopa:Hi, great to be here. Thanks for having me.Stephanie:I am very excited to have you on. So your history as we talked about before the show started is very intriguing and I think our guests would love to kind of start there and hear a bit about your background, childhood, all of the things about Lopa.Lopa:All right. Well, let's see how long we have. So it's all a question of where do I start, right? I mean where do we plug in? But I will say I think a good place to plug is around when I was 16, I first heard the word enlightenment, I don't even remember in what context and I was like, that. I want that, whatever that is. And I started reading spiritual books on Taoism and Buddhism and I went from being this incredibly miserable teenager, like the most, like special. I know like everybody's miserable as a teenager, but I was extra. I'm extra about everything. And then I kind of went through this awakening process as I discovered this other dimension to life and I was just hungry and I was positive and I saw beauty everywhere and it was great.Lopa:I started getting into yoga and I kept on finding myself wanting a deeper and deeper relationship with a teacher. And then I did find a guru, like a real guru from a lineage in India and studied with him for a long time and learned a tremendous amount. Spirituality was a huge focus of my life. I've probably done six months of retreats over the years. And for a while three to four hours of meditation practice a day and I was hardcore. And at some point in there, I started to sort of question the navel gazing nature of it all and was like, what else can I give to the world? And what else can I bring to the world? And through serendipity in many ways, I found a job in the bio char industry.Lopa:And for those who aren't familiar, bio char is short for biological charcoal. It's charcoal that you add to soil to both sequester carbon and improve soil quality. And I helped co-found two businesses there. I worked for Richard Branson's Carbon War Room while I was there. I spoke at TEDx. It was like I was in the right place at the right time in an industry that was really growing specifically for its focus on being a potential solution for climate change. And then after, I don't know, five years of eating, breathing, sleeping, sweating bio char, and then practicing and doing retreats when I could and all of that, I left that context and went on and around the world trip with my now husband and just at the very end of that trip, we inadvertently as always happens, got into a cult. And no one knows you're getting into a cult when you're getting into a cult. Nobody's like-Stephanie:Okay, how do I even know if I'm not in one right now then?Lopa:It's a great question. So there's sort of two distinctions of cults. We are all in a certain cult in terms of modern society, in terms of our involvement with media and the way that it shapes the way that we think. All of that could be considered a cult. And depending on how you look or who you talk to, that could be seen as a benign cult or a destructive cult. Many religions are benign cults. But in this context we were in what could be considered a destructive cult or another framing that they use in cult academia is high demand group. And so one of the ways that you can assess if am I in a cult kind of situation, how much demand is there for your time, for your attention, for your devotion, for your money? And in this context, we were pretty much 100% of our time was focused on this cult. My husband was working at the time and found it incredibly hard to maintain his job and all of his duties in the cult context.Stephanie:How did you inadvertently get into it? Did you meet one person and they're like there's this cool thing, it kind of sounds like this, and it's just like a community of just like besties. And then you get in there and it just turns into more and more and more work, or what does that look like?Lopa:Yeah. Yeah, it's always gradations. So we met somebody and she was talking about her experiences with this woman. And often people don't think of women as having that, but it usually there's some kind of narcissistic component to any cult dynamic. Not necessarily though. And I will also say too, just because I think it's important to understand, you can be in a cult of two and another way to look at that is an abusive relationship. So that would be considered like the smallest size of a cult and then bigger ones are what we normally think of when we think of cults. So if you're in a relationship and you're like am I in a cult of two, look at how much demand is on your time and how much are they trying to limit the world around you?Lopa:So yeah, we met this woman, she was telling me about her experiences and they were amazing and mystical and psychedelic in many ways. And I was like, all right, this sounds like what I want. Yeah. I want that magic. I want that other worldliness. And so we went to go see her and she's a very powerful, very charismatic woman and there's real great spiritual teachings in there too. Nobody joins a cult just because they're like, oh, I want to get abused. That sounds great. There's something that draws them in. And usually it's a trauma bond that keeps people in because there's like, oh, today it's a little bit of love and tomorrow I'm going to humiliate you and today, you're the best thing ever. And tomorrow I'm going to question every aspect of your sense of self.Lopa:So it started as this charismatic, interesting, powerful woman who had a lot of energy. I did have psychedelic experiences around her. Cool. That's fun. Without any drugs and it's the context there. And there are some things that I probably should have been like um, she gravels and hisses and speaks in tongues and stuff.Stephanie:A little off putting.Lopa:Yeah, yeah. But I was like, well, everybody around her kind of did it. And so that normalized it and was like, oh, well maybe I just don't get it. And maybe okay, if I start doing that, then I'll be more spiritual too. And all that kind of stuff. And with almost any cult or context, it gets more and more insane literally. It's like an onion. The outer layers and people who just come to a class here and there, they might be like, she's amazing. What are you even talking about? This is not a cult.Lopa:And then as you get deeper and deeper in and closer into that kind of inner circle, that's where things like some of her like... Sorry, I'll go back and say for the first six months or so, it was like bliss. It was amazing. It was just awesome. And I felt so seen and so loved and all of that. And then after some time is when, and in spiritual contexts, you're trying in some way to break your ego down. And so the eco breaking down a scene in this context of like, well, I need this and so I'm being humbled.Stephanie:Yeah, you need that abuse and ripping apart every piece of need because I [inaudible] and I need to be separate from that.Lopa:Exactly. Exactly. So this is part of the growth and I just have to sustain it and all of that, and it can be tricky to assess if that is real, is it really actually good? And you do need to be cut down in some ways or we all have times in our lives where somebody gives us a reflection that we really don't like but we really fricking need. And that can really hurt to let it in. I think a prime present tense example is people beginning to see the embedded racism in their system for white people and I think that's a reflection that none of us really want to hold, but we have to. It's important to hold and that's a big ego, like we have to let the knife go in on that one, for example.Lopa:But then in these more kind of abusive context, it's like you have to look very closely at what is this person's motive? Do they really feel like it's coming from I am actually trying to help you in some way. And she always said that she was and this was all for us and all for love and all of that. And when it came down to it, some of the things that really kind of set us off towards the end was just realizing how incredibly unhumble she was and how unwilling to receive feedback or any kind of bi-directional. She gives a lot of feedback in our direction. And then we're like, are you kind of sitting on a pedestal and then freaks out. And so those were some of our cues. And sometimes it is, you find just this tiny little cue, and then that's the thread that lets it all kind of break down and then you realize, whoa, wait a second, what are we doing? Where are we? Why are we prioritizing every minute of our lives around this person?Stephanie:Wow. Can you get out? Because I always hear when you're in-Lopa:It's hard.Stephanie:It's hard to get out. So what does it look like you trying to get out of that?Lopa:Yeah. I mean, it's different for every person. For us, it was an outside reflection from somebody who was a relative stranger who brought up. He was like, I'm sure she's a really beautiful person, but I see some red flags and I'm just a little bit concerned and then gave some examples of other teachers who were very humble. And I don't know if he specifically chose these teachers because they're very humble or what, but it was a strange experience. My husband and I were both on the phone with him at the time. When we got off the phone, it literally felt like a bubble popped.Stephanie:Wow.Lopa:We were, wow. Okay, something changed. And we felt kind of naked and exposed. And then we were like oh, we just need to give her some feedback. She's kind of lost her humility and she's like, I am that, I am everything. And so we just need to sort of remind her of her humanity a little bit, right, because we're all humans. And there was a process of, we gave that piece of feedback and then over the next three weeks, there were 3000 emails sent between the group. I went back and looked at my gmail and it was like 3006 or something, crazy. 3006 or something absurd. I'm trying to [inaudible] language out of my vocabulary. And my husband really saw it quickly and was out and for me, it took a little bit more time where I was kind of questioning myself, oh, maybe she is the real deal and I just can't take it and all of that.Lopa:And therapy was a really big part of the healing and the reconciliation and finding my core sense of self again, which got adjusted over the course of this whole time. It was like, somebody questions your motive once and you're like, oh no, that's not where I'm coming from. And then they do it again and you're like, what do you mean? And then they keep doing it and keep doing it. And you move a little bit off of your center over and over because you start to question yourself, well, maybe I am this kind of showy person and you start to believe that. And that's gaslighting and that's how that happens. So for me, it was a process of kind of reexamining all of my beliefs and all of the dogmas that I'd picked up in the course of my life and all of these different things to get back to kind of what feels like a core solid sense of self and a lot of therapy.Stephanie:Wow. That's intense. Okay. So you get out of this cult and then what happens after that?Lopa:Yes. Well that year was a doozy. I now call it my own personal 2020. Now that we've had 2020, I'm like, oh, that was my 2015 because yeah, I left the cult, 3000 emails, I had an emergency back surgery while I was pregnant, I moved across the country a week later, lost a family member, had an emergency cesarean birth that was traumatic, I had a huge falling out with my family. I was fried. And so Rasa actually really came out of necessity. Necessity is the mother of invention. I was fried and I was like, I need something to help me keep going because now I had a baby waking me up, really precious little munchkin. And I tried coffee. I've never been a big coffee drinker because it's a little too much for my system. I tried coffee and was like, whoa, okay, irritability, jitters, panic attacks, sleep is even more messed up. No. This is a hard no.Lopa:And so I looked at all the coffee alternatives out there and tried them all. And I was like, really? This is it? Come on, we can do better, right? And I've been a big herb person, just an enthusiast. I love herbs. I've always had lots of jars of herbs in my kitchen and stuff like that. And I was like, can't we just put a bunch of really good herbs in there? And then I started to really think about here, looking at coffee in this coffee cup that people just don't even really question, this ritual of drinking coffee, it's even built into so many aspects of our culture in terms of don't talk to me until I've had my second cup of coffee kind of stuff.Stephanie:Community stuff like let's meet up for coffee.Lopa:Yes, totally, totally. People talking about how coffee is their personality. And I started being like, wow, this is something that people often actually used to override their body signals. So like their body's like, I'm tired. The answer is not rest or downshift a little bit or maybe I need a little time in nature or anything like that. The answer is often coffee.Stephanie:Yeah.Lopa:Coffee is the tool of a society that does not give two shits about anything except for your productivity in a way. And we buy into that and we do that. And I say this also in the context of not saying that I'm sure a lot of people listening, entrepreneurs, people out there in the world are like, no, you do not blah, blah, blah, my cup of coffee. I understand that. I really get it. It's not that coffee is bad or coffee is the devil. It's about how you're relating to it. Just like how you're relating to anything. Like a glass of wine with dinner is not a bad thing. It's a beverage, but if you have a real dependency on that, and that is something that you really need and you have two or three or four, it's all about right relationship fundamentally. So yeah, I started looking at that and I was like, wow, everybody's just drinking coffee, coffee jacks up your central nervous system. It causes a cortisol flood from your adrenals.Lopa:So it's literally triggering a stress response which is part of why you feel so amazing. And because the cortisol is there to help you be able to beat the tiger or run away from the tiger or whatever. And I was like, wow, that doesn't necessarily put us into our best selves. When I am revved up, I'm not necessarily kind of grounded in my best decision-making, my cognitive executive function is not operating from that wide spacious perspective. And so I was like, all right, what if we, and then there was this other kind of aha about coffee is also one of the few accepted bitter tastes in our culture.Lopa:We don't tend to love bitter in our society, but coffee is super bitter. And so as chocolate is the other one. And I was like, so there's a bunch of amazing herbs out there. Some of them taste kind of like crap, but if you stick them into this like rich, robust cup and with other things that are kind of masking the taste, you can actually get people to drink something that's going to be incredibly healthy for them every single day and is actually going to help them regulate their stress response.Lopa:And so that's where at that point, I started working with a herbalist. I love herbs and there's a bit of a trend out there of people just being like, oh, there's all these trendy things out there, let's just go ahead and throw them into a bag and sell them. And herbalism is a very, very long standing tradition. That's the original medicine, the people's medicine and there's a lot of science in there too. And so I think it's really important. It's very different to have a herbalist formulated product versus trendy things in a bag products. And so I worked with a herbalist and they actually did the formula. And so that was five years ago. We were kind of in beta for roughly two years. And then we hard launched in April of 2018 and now I am founder and CEO of a 20-person business and things are going great.Stephanie:Wow. That's amazing. So when thinking about formulating the product, did you go into it already knowing I want to have for sure these things in it, or did you really just relinquish control and just say, you tell me, here's maybe the benefits that I want to see or I want it to taste maybe a little bit bitter or not at all? How did that relationship go about?Lopa:With that original relationships, so that was my original co-founder, who was a very, very dear friend and now has a royalty on her formula and we bought her out. We didn't bring out the best in each other in a business context. So that's really good, if you're going to start a business with a close friend, you really want to look at them from the angle of would I hire this person to do these things? And have I ever gotten into significant conflict with this person and how did we do? And because as soon as you're dealing with money, it becomes almost like a marriage, it's way intense. And just our friction didn't quite work, but so she had these herbs that she was already working with. Lopa:And I made suggestions, I was like, I think we should add this. And I think none of them ended up in the final formula, but I was like, it needs to taste good. It needs to be really functional. It needs to have an energy component. It doesn't have to match coffee because coffee, I think is an unsustainable energy spike. But it does need to give people some kind of lift and I wanted it to be gluten-free, have no natural flavors, anything like that. So it's just herbs. And she went to town, we now have a herbalist on staff who is a clinical herbalist and he has reformulated that same formulation probably 40 times or something. And some of that is we've done some major reformulations to just continue to improve the taste and continue to improve the functionality. And then sometimes there's like, oh, this herb has a sustainability consideration and so we're going to swap that out and, oh, we're going to change it to a different source.Lopa:And then that source has a different taste. And now we have to adjust everything. But we actually taste every single batch of herbs and reformulate every single time based on the strength of the harvest of the herbs because you're always adjusting for climate and things that are totally out of our control and we want to have a consistent taste.Stephanie:Yeah. I love that. So the one thing I want to talk about too, and understand more is the industry as a whole around adaptogens because I feel like that word now it seems like it's on every product. And sometimes I'm like, well, how do I know what an adaptogen is? Is it real? Is it not? Because it seems like a trendy thing. And how did you think about that when entering into this industry?Lopa:Yes. Oh man, don't get me started. So first, how do you know what an adaptogen is? And is it real? So these are herbs that have been used for thousands of years in traditional context, in [inaudible], in Chinese medicine. And then in the 1940s, a Russian scientist named Nicola Lazaroff, there we go, thank you. He was basically tasked with giving Russian super soldiers and athletes an edge without a crash. And so he went to work studying all sorts of substances, including herbs and fell on these types of herbs, and he was like, oh, wait a second. This does give them the edge. They can go longer, harder, faster, more, and then they don't have a crash after the fact which is what happens with stimulants. And that's the issue with coffee is you get that crash in the afternoon because it's a kind of an unsustainable lift.Lopa:And so he initially started working with eleuthero which was the original adaptogen. And there are over 3000 studies on eleuthero, it's one of the most studied herbs and all through his research. And that term was coined, I believe, in the early 1950s. And so in order to be called an adaptogen, a herb needs to, we call it the four Ns, it needs to have a normalizing effect on the body. So it helps balance, helps you find homeostasis against environmental, physical, emotional, mental factors, all kinds of stress. It needs to be non-toxic in normal therapeutic doses. So it has to be basically safe. It's not going to, basically safe for most people. It needs to be nonspecific in terms of, there are many herbs where this herb is very good for the liver or this herb is very good for the blood.Lopa:These are herbs that work systemically and holistically in the whole body. And then that relates specifically to number four which is neuro-endocrine. It needs to have an impact on your neuroendocrine system which is your nervous system and your endocrine system coming together. And both of those, I want to go a little bit into the science, but so you have two main pathways that your body uses to communicate that you're under stress which is your hypothalamic pituitary adrenal axis and your sympathoadrenal system, hypothalamus pituitary adrenal axis is HPA. And the HPA axis is how your hormones tell your adrenals that there's a stress issue. And then your SAS is neuro-transmitters. And these herbs strengthened those two systems, literally like exercise. So they say that it mimics stress. But it's actually in a good way.Lopa:It's a eustressor. So it's actually like exercise is stressful for our bodies but it's in a good way, because we're getting stronger, we're getting more resilience, all of that, we're getting more flexible. And so adaptogens are literally doing that to your body's stress response system. So they have to have that neuro-endocrine impact as well. And this is also really interesting, just seeing adaptogens trending so much, many companies out there, I think, do not understand that there is a scientific criteria. It's not a marketing term. And there's actually a pretty small class of herbs that are scientifically substantiated as being adaptogens.Stephanie:Yeah, I was going to ask like how many are out there that have that claim against them?Lopa:Yeah. So it depends on who you talk to and who you look at. And we're actually working on coming out with a whole here is the definitive adaptogen guide. Here's what actually has the scientific backing. Here's why we chose these particular herbs based on these scientists and based on what we know and here's the list and here's what gets adaptogen washed. And this is a term that we've coined adaptogen washing where somebody calls something an adaptogens and it's not. So there's about, I think it's 39. And that number is changing based on the science. Sometimes they'll do a few more research studies and be like, oh, actually this one drops off the list or they do a few more research and they're like, okay, this one's definitely on the list. But depending on which scientist you talk to, there's either nine or 12 definitive adaptogens and then roughly 20 to 25 other probable adaptogens or secondary adaptogens.Lopa:And to be generous to the industry, we call anything that is probable, possible, secondary or primary an adaptogen. But many things that we see get mislabeled as adaptogens out there are Chaga is not an adaptogen, lion's mane, all the functional mushrooms, people are like, functional mushrooms are adaptogens. Nope, there's just two. And that is cordyceps and Lingzhi.Stephanie:I love Lingzhi.Lopa:Yeah, turmeric is not an adaptogen. Actually there is one other mushroom that's very little known called [inaudible], I think. But yeah, Chaga is not an adaptogen, lion's mane, turmeric. I've heard Matcha be called an adaptogen, [inaudible]. People just kind of throw it on anything. And this is an interesting case of an industry growing because we're overstressed as a culture. And this was going back to one of your questions about did we know what we wanted to put in that cup? And were we aware of that? We want to put the best stuff ever in a cup and adaptogens are the best stuff ever especially as a superior way to stimulate yourself that's more sustainable. And I believe that they're trending because people need them. That's what's happening right now. And there's a pretty uneducated consumer base.Lopa:And so there's a lot of knowledge to understand. And adaptogens tend to grow in really extreme environments which is why they're expensive. They grow on the tops of mountains, in desert, in these kinds of contexts. And it can be hard to actually get a full harvest out of them in the same way as like you could for other herbs.Stephanie:There's definitely a lot of education needed around this space. And it seems like so many new things are popping up. I mean, I was just at brunch the other day where my friends were talking about Ayurvedic diets and oils to use. And I mean, it was so much, I probably was like oh my gosh, I don't even know how to consume all the things you're telling me because it feels like everything I'm doing, I just never knew about any of this. Well, the same thing with adaptogens and understanding what that is. And there's a whole revolution, I think, of this new kind of nutrition and dieting and way of thinking that is going to take some time to educate the consumers on what that actually is and who's a phony and who's real and what's an actual real product or not.Lopa:Yeah. And what's actually going to have an impact. It wouldn't be such a problem, I think to have adaptogen washing if it didn't like also devalue the herb itself. And to another point, if I gave you something and was like, this has CBD and it doesn't have CBD, you'd be like, what the heck? And some people do call CBD an adaptogen, it's not, and that doesn't make those herbs any less amazing. Just don't mislabel them.Stephanie:Yeah, just use the right words.Lopa:Yeah.Stephanie:So yeah. I completely agree. So when you're starting this company, a lot of founders start out and they're really excited. And then sometimes they're kind of like how's this going? Is this my thing? Get a little distracted, and I want to kind of hear how your journey went with getting really excited about this, knowing you had a solution to something, what did that look like after you had landed on, I want to start this company? Was there any hesitation ever or wondering is this even my thing?Lopa:Yeah. Yeah. I think that's pretty normal. I hope to normalize that for people like, I've definitely had entrepreneurs come to me and be like, I'm not sure if I want to do this anymore and I'm like, that's okay. You'll have those days. It's really hard to create something. And yeah, I mean, my trajectory, let's see, that first two years there was a lot, well, the co-founder conflict really kind of clouded, yeah, my situation for a little bit. And so I was like, well, maybe I should do something else. And maybe I should focus on other things. And I just kind of kept coming back to this and I just kept being like, this is a good idea and I feel like it needs to happen. And I couldn't believe that there wasn't something like this out there. And then, I mean, it's been stressful.Lopa:It is a lot of work and learning how to run a business while running a business is hard. If I were to do this all again, I'd be like, oh, wow, this is going to be a lot easier going forward. I've been the co-founder in a few businesses, but it's very, very different to be actually at the helm. And the buck stops at you kind of thing. And yeah, work-life balance has been tricky. I have two kids now. I actually hard launched Rasa when my second son was four weeks old. Tough planning. It didn't quite go to plan as I'd hoped. And there's definitely a sense of the business would take as much energy as I would possibly give it. My kids would take as much energy as I would possibly give them. And so there's this feeling of, it's never quite enough.Stephanie:The mom guilt. The mom guilt is so real. I feel that [inaudible], yeah, I'm in the house recording. My three kids are usually on the other side of the door and I'll just be like should I be out there with them and having to be like, no, boundaries. Most people, well, not now, but used to go to an office and be away and that's okay. You got work to do. And yeah, work-life balance is definitely a struggle especially working at home now in the same presence as kids and family members and pets and all of that.Lopa:Yeah. We actually originally made the Rasa headquarters out of our garage so that I could be closer to my kids. I just wanted to be able to breastfeed for a bit, put the baby down to a nap, come back. And so we were in my garage until last September. It worked great for that time. And I was like, well, we're running a $2 million business out of my garage. This is solid, it's a small garage. It's not like a big old thing. But it was my garage. We had a storage unit in the back. We had a shipping container in our driveway. We had a shed, it was in all of our basements, pretty much every room had something Rasa-related. And so I was like, all right, we got to get out of here.Stephanie:Yeah. Your neighbors are like, what's this girl doing over there?Lopa:I know. They were like, this zoning. It was not up to code, but we're out now. So forgiveness rather than permission.Stephanie:Yeah, yeah, I agree. So I want to talk a bit about Amazon too because I saw that you were part of the Launchpad program, what do you call it? And I haven't had anyone on the show at least that I know of who's been a part of that. So I want to hear about your experience being on that and spreading the word about Rasa and getting in front of new customers and just being on Amazon in general.Lopa:Yeah. I mean, Amazon in general, Amazon has been a really solid channel for us, which is part of why we went with the Launchpad program. It's been just very consistent. The growth has been pretty steady and predictable. The customers there have been great too. We have some really consistent customer retention on Amazon which I think is not what we really expected. We have a lot of subscribers there. And so we were on the Launchpad program for about a year. We actually are just in the process of pulling out of it. They do take a 5% cut and basically, I think if you have somebody on the team who's really managing it closely and is really taking advantage of every single opportunity that they have, I think it's probably a really good program. We did not have that.Stephanie:What are the opportunities that they provide within that program?Lopa:Yeah, there's a lot of promotional potential. Some of those come with additional revenue cut. Some of those just require additional marketing planning and that sort of thing. And I'll say we have tended to... We actually for about the last year have really under indexed on Amazon. I think we could have autopiloted it. And we were like, oh, well Launchpad will be good and blah, blah, blah. So we may actually go back to the Launchpad program once we have our Amazon growth strategy a little bit more, but a lot of promotional opportunities, get on the front page. You get chances to do extra deals. They have the lightning deals and I don't manage the Amazon super closely. So our Amazon guy could tell you a little bit more, but yeah, a lot of emails came through where I was like, huh, we should probably do that, but we don't really have time. We don't really have the marketing bandwidth.Lopa:And I think now I look back and we're like, well, we want that 5% margin back. We can put that into ad spend. And I think that that's going to be a better use of that capital at this time. And if we had actually been taking advantage of all those emails that came through, you can get a dedicated account manager who will help audit your ad spend and all that stuff. If we were doing that, I think it would have been a great program for us. And it was positive, we've seen growth, but not quite enough to warrant 5% on every bag.Stephanie:Yeah. Yeah. That's quite a hefty margin to take out. For them to do-Lopa:On top of their original 30%, yeah.Stephanie:Ooh, that's a lot. So you pulled back to focus more on ad spend. I mean, what kind of channels were you relying on to get the word out? Because even though it is a big trend around this industry, I still feel like it's pretty niche to get in front of the right people who understand it and are ready to buy around this. I think it might be a little harder of a sell to get in front of someone who has to do the research like me to be like, well, what is an adaptogen? Is a good for me? And how did you go about finding the right people in the platform that'll work for you?Lopa:Yeah, well, we're really going after the coffee market and adaptogens are the way that we're doing that. So adaptogens right now, it's a $25 billion industry, but most of that's in Asia and because they have a cultural context around using these herbs in daily life that we just don't have. And so we are actually bringing a cultural context for these herbs through the coffee ritual and coffees is a $465 billion market. So we like that TAM a lot better. So that said, most of our customers are actually coming to us for a coffee alternative and then they're like, oh, it actually supplies all these benefits as well. And I think that's one of the things that we've been kind of working on and finding our positioning and our messaging in terms of yes, it's a beverage and it's delicious and it's intended to replace entirely or replace partially your coffee ritual.Lopa:But then it also has all these ancillary benefits, not ancillary. I mean, we get incredible customer reviews that say that it's just life changing. And so I think there's a way, and I think that's part of why we get an amazing long tail retention on our customers because we're delivering on more than they expected in terms of the impact. But most of our customers, we've been pretty heavily focused on Facebook. That's been our major scaling channel and that's a really interesting context right now because the iOS 14 change. And I think also with the pandemic ending, the buying patterns ending we hope, the buying patterns are shifting a bit as well. And so people are going back to their third spaces. They're going back out in the world a bit more.Lopa:And CACs are only going up. They're not coming down ever. So we sort of had a little... Facebook's been amazing for us. And I have had this little bug in the back of my head for like two years where I've been like we can't put all our eggs in this basket. We had one ad that, I mean, I think this one particular ad had done a million dollars in revenue for us or something. And it was based on something, it was a relevancy score. So in Facebook, they were categorizing by relevancy and it had a 10 out of 10 relevancy and we were like we could just dump money into it and it would just keep returning money. And it was amazing. And then they dropped the relevancy score as a factor all in their algorithm. And it was like our cash cow has died. It just suddenly, because the way the algorithm was prioritizing, it just didn't deliver in the same way. And we were like, wow, we're at the helm or we're at the whim of something that we have very little control over.Lopa:And so we're starting a little bit of a channel diversification strategy just to have a little bit more health in terms of what we're doing in the business.Stephanie:So many companies start out that way that I can think of and I think it's perfectly okay to rely on one channel. I mean, I've talked to a couple where they're like in chat within Instagram DMs, or Facebook chat, that's where our company's at. And I mean, we kind of went through that at mission too. We were very reliant on media and we became the top on there. That was where our business model was headed until one day they made a few changes and we're like, whoa, that just disrupted our entire business. Why are we relying on someone else's platform? We need to get off here and diversify. What kind of channels are you trying out now? And how did that make you rethink, relying on any platform in general?Lopa:Yeah, I mean, that's the thing. If you're diversified, then you have a little bit of a hedge. And so if something changes, you're like, cool, we're going to just flex the lever a little bit more over here. So we've been very under-indexed on B2B wholesale in general. We've never had a salesperson and we just considered it part of customer care. And if somebody came to us and was like, we'd like to order for our store, we'd be great. And that was kind of it. And so now just knowing that you can really scale a business that way, too. We're going to be investing in that a bit more. So we're in like, I don't know something like 600 retail stores at this point and-Lopa:So yeah, wholesale, actually investing in growth on Amazon, PR is something that we've also done almost none of. So actually working to in-house PR, I have come to kind of think of PR agencies as black holes where money goes to die. So I'm really keen on in-housing it. And influencers is also something that we've been very under-indexed on, just haven't put anything towards and it's all been organic, which is great. And we've had a lot of organic movement in all these things, but there's a difference between letting it come to you versus like, okay, now we're going to really focus on this. And then we have some international opportunities opening up as well.Stephanie:Cool. That's amazing. All right. So I know we're getting short on time and I do want to talk about crowdfunding and I know you mentioned you were very excited about that. So I want to dive into why are you guys crowdfunding? Why do you choose that approach? And you also mentioned innovative marketing ideas around that so. I want to hear all the things.Lopa:Yes. Yes. So DTC has allowed this new level of customer relationships and we have a lot of intimacy all across our communications and people always tell us they feel like they're talking to a friend instead of a company. And we love that and incredible brand love as well. And we feel like the logical next step of that is becoming crowdfunded or community-owned. And we've had lots of investors come and knock on our door and be very interested in what we've done and what we've been able to build, bootstrapped especially for a CPG business. And the thing that just kind of keeps coming up and especially for VCs, VCs are very extractive capital. And we actually talk about it internally. Like VCs are the coffee of money.Lopa:Coffee is an extractive energy source for your body. VCs are an energy extractive source of money for your business. And we do a lot of things differently. In our business, our culture is, I think pretty remarkable. We're doing a lot around sustainability. There's a lot of things where we're prioritizing a triple bottom line instead of a bottom line, just the bottom line. And we get nervous about the idea of getting into a relationship with somebody who's like, well, yeah, you can't treat your employees that way and you can't do this and that.Stephanie:You've got to return the fund to be worth it to me.Lopa:Exactly. Exactly. And we know that our customers love the way that we do things and want us to be more and more that way. So we're very excited about that and they just changed the regulations so that you can raise 5 million via crowdfunding instead of just one per year. And so we're very excited about, we're going to be hopefully one of the first to actually close a $5 million round crowdfunding. And some of it, we've just realized like damn, these businesses can be real capital intensive. And we're trying to do this with capital constraints which means people constraints and bandwidth constraints. And then we're trying to do a very high integrity product with a lot of value in the product and compostable packaging and just fair trade as much as we can all across the business and treating our employees really well.Lopa:And all of these different things that just does cost money, cost more. And then we're like, well, we want to grow as well. We want to invest in growth. So we've been basically break even except for investment in growth for a while. And we were like, if we had more capital to invest in growth, we know that the business is financially sustainable and really solid. And so if we just can get that growth capital and so that's basically why we're doing it. And when you're building a brand that people love, going into some of our marketing strategies around this, when you're building a brand that people really love, and then they're also becoming owners of that brand, I think there's a big question about what's secret, and what's not secret.Lopa:And there's a lot of secrecy in the CPG world and in business in general. And we are seeing that the more transparent we are, the more our customers just eat it up. And they love the behind the scenes about the business. And they love just knowing about why we made a certain change in our packaging and stuff like that. That's where we get the most responses. It's kind of crazy. And so we are shifting towards being more and more open about margins, our run rate and including people in these details allows them to be included in this incredible journey of launching this product. And so we're going to be doing a lot more around this. We're kind of working on building the internal content engine to be able to just be a more and more transparent and share more and more about what it takes to do this and the hard decisions and the hard moments where I'm like, oh my God, my kids and this and the business and all that stuff.Lopa:But our customer reviews are incredible, so incredible. We have to be editing them for the FDA. We've had people say that they had a Rasa baby, it's made them more patient with their partners and their kids and all that. And that's why we got into plant medicine. We knew the power of these things. And so I think crowdfunding is a way of getting people invested in the business and having the business actually be like herbs were originally the medicine for the people and now it's going to be a business about herbs for the people as well. And so it just feels like it's really perfectly aligned.Stephanie:I love that. I mean, I think the idea too around transparency, not only does that give your customers things to look at and engage with you, but I think it also invites help too. If someone sees oh, your margins are around this. Let me come in and help you because I think maybe in the CPG industry, maybe they should be around here. I've got this idea around logistics that might help you enhance that. So I think the more you share, the more other people might come in and be able to actually help and want to lift everyone up in the process.Lopa:Yeah. Absolutely. Absolutely. And I think in the industry, that is really valuable. Sometimes there's always a question of how much feedback you get from where. And sometimes you're like, wow, that's a lot of people that want to help and I don't really know what they're doing.Lopa:But I mean, that said, we listen to every piece of feedback too. And I think going back to the cult conversation a little bit, when you get feedback that you don't like, you have to look at it and say like, okay, if 1% of this is true, what part would be true? And then look at that. And that's one of the nice things too about DTC is that we have been able to actually iterate our products very quickly based on customer feedback. And I think having more transparency also means that we're going to be able to crowdsource product ideas and reformulate things to match people's needs more and stuff like that which we're really excited about.Stephanie:Yeah. Yeah. Super exciting. All right. Let's do a quick lightning round. Lightning round is brought to you by Salesforce commerce cloud. This is where I ask a question and you have a minute or less to answer. Are you ready?Lopa:Yes.Stephanie:All right. What's your favorite Rasa drink to enjoy in the morning?Lopa:Super Happy Sunshine.Stephanie:Okay. Awesome. If you had a podcast, what would it be about and who would your first guest be?Lopa:It would be about cultivating energy intelligence, emotional intelligence but energy intelligence. Yeah. And my first guest is a great question. I have not even thought about that. I mean, if I could just wave a magic wand, I would actually have Brené Brown because we don't think of the way that we hold ourselves in our vulnerability as being actually kinks on our energy. And I think that her work around vulnerability and shame is actually very energy liberating.Stephanie:Yep. Yeah. I love her. What's up next on your reading list or your podcasts list?Lopa:Oh man. I have such a long list. I'm in the middle of The hard thing about hard things by Ben Horowitz. And I'm also reading a book about the ancient Indian martial arts that I practice called [inaudible] and I'm in the middle of like five books right now. Another great one, oh, just Hunt, Gather, Parent.Stephanie:Oh, I'm reading that now.Lopa:It's so good.Stephanie:So good. Yeah.Lopa:Oh my God, so good.Stephanie:It makes you-Lopa:And it's working.Stephanie:[inaudible] parenting in general like oh, why are we basing our parenting advice off? What does she say? The past 100 years or something when there's time-tested things that work for thousands of years that we can tap into and around the stress of the parenting right now is only on essentially the mom or mom and dad where we're doing the same work that used to be 15 people, grandparents, cousins, aunts, and uncles. And I'm like, there's going to be a shift though. I think it's going to start heading in that direction again.Lopa:Yeah, I think so too. And on the podcast, Fred, I'll say, I actually was looking at your list of podcasts and I was like, oh my God, I need to be listening to all of these. So well done. I love business-Stephanie:[inaudible] podcast, hey. I love that. Yeah, check them out. They're good ones. Launching new ones all the time too. And the last one, what is the best piece of advice you've ever gotten? It can be business, personal or from the cult, whatever comes to mind.Lopa:Best piece of advice I've ever gotten. Lopa:What comes up is that purpose is a red herring and that so many of us, I think in this, it may be a little bit less for your audience. But I think that this quest for what am I supposed to do and what is my purpose? And I can only really do something once I have my purpose. The advice was stop wallowing and trying to find your purpose and do something. And you will find your purpose in the process of acting. You will find the things that don't feel aligned and then you'll adjust. And so it's about help someone and help something and you'll find purpose in the process of doing.Stephanie:That's amazing advice. And that's actually perfect for our audience right now. I mean, people trying to start businesses and I mean, you probably went through this too. I know I have of, is this my thing? Am I passionate about this? Do I want to do this for the next 100 years? And I love that. Just start doing it and you will figure it out.Lopa:Yeah.Stephanie:That's perfect. All right, Lopa, well, I've loved having you on. It's been such an engaging conversation. It's really fun to hear about your life and Rasa. Where can people find out more about you and your company?Lopa:We are at wearerasa.com and we actually have a discount code for you guys. If you use the code upnext, you'll get 20% off your order. And we're also on Amazon and we're on Instagram and Facebook at We Are Rasa.Stephanie:Amazing. I'm definitely using that code. I cannot wait to try it. So thank you so much for joining us. We'll have to have you back for round two to hear how the company is going because this is such a pleasure.Lopa:I would love that. Thank you.

Up Next In Commerce
Why Burrow is Not Following the Traditional DTC Playbook

Up Next In Commerce

Play Episode Listen Later Jul 15, 2021 48:43


If you look on Twitter or do a quick Google search, you'll find a ton of chatter about the foolproof DTC playbook. Everyone has ideas about the surefire ways that young DTC brands should be setting themselves up for success. Alex Kubo is here to tell you that those playbooks aren't as written in stone as you might think. Alex is the VP of ecommerce and digital marketing at Burrow, a DTC furniture brand, and on this episode of Up Next in Commerce, he explained how and why the Burrow team threw out the playbook when certain aspects of it fell flat. For example, Alex talks about the lessons they learned about the signals that pricing sends, and why it's critical to put the right price on your product to attract the right customer even if that means pricing higher than the playbook says. Alex also dives into what it means to actually be customer centric and how Burrow stays in constant communication with customers. Plus, we discuss why marketing toward buying events or using a spray and pray strategy across a dozen channels is about as useful as setting your money on fire. Enjoy this episode!Main Takeaways:Sending The Right Signals: How you price your product or service is one of the most significant ways you signal to customers who you are as a brand and what value you bring. If you price too low, you risk being lumped in with brands that don't necessarily fit with the type of products or value you bring to the table.More Than Words: Saying you are customer-centric and actually being customer-centric are two very different things. To be truly customer-centric requires regularly talking to and learning from your customers and then building experiences and products based on those conversations. You can't just assume you know what customers want, you have to do the work to find out.A Horse of a Different Color: There are best practices and guidelines that many companies follow to get themselves off the ground. Sometimes those playbooks work, but in other cases, you have to toss out what everyone says is the right strategy and go in a new direction. Whether that's in your social strategy, your pricing, or how you're getting feedback from customers, don't be afraid to buck tradition and do something different.For an in-depth look at this episode, check out the full transcript below. Quotes have been edited for clarity and length.---Up Next in Commerce is brought to you by Salesforce Commerce Cloud. Respond quickly to changing customer needs with flexible Ecommerce connected to marketing, sales, and service. Deliver intelligent commerce experiences your customers can trust, across every channel. Together, we're ready for what's next in commerce. Learn more at salesforce.com/commerce---Transcript:Stephanie:Welcome to Up Next In Commerce. I'm your host Stephanie Postles, CEO at mission.org. Today on the show, we have Alex Kubo joining us, who currently serves as the VP of E-Commerce and Digital Marketing at Burrow. Alex, welcome.Alex:Thanks, Stephanie. Excited to be here.Stephanie:Yeah, I'm very excited to have you here. It was cool reading a bit about Burrow's background and starting at Y Combinator, and I was thinking it might be fun to start there, back in 2016. What did it look like starting the company, and then we can get into today?Alex:Totally. So, I was fortunate that I actually met the two co-founders of Burrow while were on the same business school program in Philadelphia. And back in the fall of 2015, actually, Kabeer and Stephen, the two co-founders and my classmates were both furnishing their apartments as they moved into Philadelphia for the program, and they had two very distinct but related experiences. Kabeer purchased a sofa from West Elm in Philly, and it wasn't going to arrive for about 12 to 16 weeks, which I think, nowadays, people are pretty used to seeing those timelines, but Originally, it was like, "Whoa, this is not Amazon." And so, Kabeer actually used the cart, the dolly in his apartment building and rolled it to West Elm, and picked up a floor model and brought it home, because the lead time was going to be longer than his first semester, so obviously, that was not going to be a great experience.Alex:Stephen went the classic IKEA route, right, where you don't come in to grad school with a ton of money and need to furnish your space quickly. And so he did that, and then ultimately, it's a waste down the road, right? IKEA furniture, you can't move because of the quality of the materials and that sort of thing.Stephanie:[crosstalk]. Yeah.Alex:Yeah. So, the question ultimately became, why can't you have that higher end quality that you might find at a West Elm, or Pottery Barn, or Crate and Barrel, but the convenience, the modern day conveniences that Amazon has made the default expectation of consumers, so fast, and free shipping, and easy delivery process, and be able to modularize that design so that you can set it up and not have to deal with like the IKEA hex key or any of these really cumbersome assembly processes? And so, that concept was born. And out of that came a series of product innovation that ultimately, Stephen and Kabeer got into Y Combinator with just a pitch deck and no product and used that accelerator to develop the product, to prototype the product, and ship it.Alex:A funny little anecdote is that from the time they incorporated the company to the time they shipped their first product was shorter than the period of time that West Elm quoted Kabeer to ship his first couch.Stephanie:Oh, wow. That's great.Alex:Yeah.Stephanie:And what were you doing when they were going through Y Combinator?Alex:I was actually working on my own concept in the health and fitness space and ended up calling time on it right towards the end of the summer because of a number of challenges that I was having on my end, and joined up with Stephen and Kabeer to help build out the demand side of the business. And I had a relatively intimate knowledge of the business and where they were at because we were in all the same classes working on our own businesses. And I had helped them tangentially with sourcing components during our first year of the program, because I have a background in mechanical engineering and they didn't have any background in physical hardware. And so, there was already the groundwork for relationship. And then I was trying to move my own discipline into more of a consumer facing and ground level marketing and product marketing role, so it actually made a lot of sense.Alex:So, we set it up as a brief relationship to make sure that the working relationship was there, which it turned out very quickly, it was. So, I have been tasked or had been tasked with basically just building demand and ran with it since.Stephanie:So, since then, what does the world look like now compared to when you started and you were building up demand? I mean, I'm sure you guys were trying out Facebook and all the traditional platforms that everyone's like, "Every brand should be on Instagram and Facebook, and if you're not here, where are you?" What did it look like then and now?Alex:So, now it's a much more disciplined and much more properly positioned business than it was in the beginning. Two critical mistakes that were good healthy mistakes to make in the early days were, number one, brand positioning and product positioning. We had this idea in our head that... and sort of the classic Warby Parker pricing story of like, they wanted to price it $45, but their advisors and professors advised them not to do that because it would signal the wrong value to the customer. We had a similar experience where, for some reason in our heads, we had to price our couch under $1,000. And we made that decision because we wanted to be hyper competitive on price and make it the default, obvious solution.Alex:The problem that we failed to acknowledge is that consumers nowadays have very limited time to understand the differences and nuances between products. They're not stupid, they're not lazy, but they do have very limited time. And so, you have to be very clear and explicit with them, and part of that is signaling. And one of the most powerful parts of marketing that I think is most often overlooked is a focus on pricing and what that does from a positioning standpoint.Alex:When a lot of shoppers were seeing our product under $1,000 and the fact that it shipped in boxes, which we were very forward with, because we focus so much on the attributes of the product and less on the experience around it, which is another step in our evolution, that people immediately equated those two things, low price and ships in boxes, with a more expensive version of IKEA. So, then it was us talking to IKEA shoppers, and you're not going to convince an IKEA shopper to spend another 300, $400 on a sofa, right? What you need to do is talk to the West Elm shopper, the Pottery Barn shopper, the Crate and Barrel shopper.Alex:So, we actually, for a number reasons, increased prices in late 2017, about half a year after we launched.Stephanie:How much did you increase them by?Alex:Originally, the sofa was priced at 950. By the way, much different cogs, profile as well, at that point. We increased the price to 1,095 to start. So, it was a pretty meaningful difference on a percentage basis, and especially when you talk about margins.Alex:Interestingly enough, everything you learned in microeconomics about the relationship with the supply and demand curves went out the window, because we increased the price and demand shot through the roof.Stephanie:Wow. Did you get it in front of new people? What else were you doing to get it-Alex:I mean, we were doing a lot of the same things in terms of building full funnel architecture on paid social and paid search and that sort of thing, and again, applying a lot of those early D2C playbook type approaches, which ultimately turned out to not be the best approach for us. But nothing changed substantially from a marketing perspective. We were still reaching a lot of the same people, it's just that we were now signaling to those people that we belonged in the comparison set with a higher quality piece of furniture. That helps also, because a lot of our value props, it's much easier to convince somebody who has shopped at one of these higher end brands and had to wait super long or had to go to a showroom and deal with a frustrating shopping experience with this overbearing sales associate, pay for shipping, and ultimately, have to be home to get a piece of furniture delivered, and either take a day off from work. Again, much different world back then than it was today.Alex:But it's much easier to talk to those kinds of people who've experienced those pain points and tell them, "I'm going to take all of that pain away," than it is to talk to somebody who's never experienced those pain points and doesn't need the higher quality piece of furniture, again, the IKEA shopper, and talk to them about all these future pain points that they've never experienced but that we can help them avoid. That's maybe one of the biggest lessons learned, is that people do not think much about the future. They're often very, very focused on the present. And so, as much as you want to talk about why you should go to the doctor every year, why should you should go to the dentist every six months, it's like, people are not going to react until they have a problem.Alex:So, we've experimented a bunch with what is the leading value prop. So, we talked to consumers, and one of the ones that we talked about very early was this concept of modularity and how, when you move into your next apartment, you can just purchase another seat instead of buying a whole new sofa to accommodate the new space, or rearrange the existing configuration that you have to fit the new space requirements. Problem is, people are not thinking about that. They don't really care. They can't think that far in advance of two to three to four years down the road when moving into the next apartment. And so, we've deprioritized that in terms of communication and lead with other things that are more immediate, like fast and free shipping.Stephanie:Yeah. Got it. So, you're mentioning earlier that the D2C playbook didn't work for you guys, where now, even these days, you can search that and you'll find a bunch of the playbooks and people are still saying like, "This is what you need to do to be successful." What were some other things that you did back then that you completely reversed and you were like, "This doesn't work for us"?Alex:Yeah. So, I think, first, was not acknowledging how complex and lengthy the shopping journey is for a piece of furniture online. Obviously, it's a big investment, it's also mutually exclusive with something else, your home, right? Let alone the high price, you're not going to just buy another couch when you have an existing one in your home, right? You need to think about getting that out or you have to do it right at the right moment with a moving event or something like that.Alex:So, the first thing that we had to realize is that what we can't do is architect our funnel around existing attribution technology or just rely on optimizing towards purchase events in digital channels. What we had to do is to look upstream and find correlations and causation between different upstream, midstream, and bottom stream events to really architect a healthy full funnel. And so, most of our campaigns are not architected towards purchase events, they're architected towards or optimized towards something more upstream.Stephanie:[crosstalk] for a couple examples.Alex:Yeah. I guess one interesting one that we've learned over time is there's a pretty clear correlation between add to cart and purchase, and the cart abandonment rate is relatively steady. We do things over time, obviously, to improve that, but it's not something that fluctuates wildly over time. And so, one of the things we can do is just optimize towards an add to cart versus a purchase.Alex:The other benefit of that is it often can happen in the first session. So, when you see a lot of the privacy restrictions right now and a lot of the issues with cookies going away and that sort of thing, it helps us. We've actually always been architected to bear that burden a little bit better than some of our other D2C peers.Alex:And then the other thing, besides the purchase journey, was also that we were just doing way too many things at once. We had, and we still have today, a very lean team. The difference between now and then is that back then, we thought the best approach was to spray as wide as we possibly could and activate 10 to 15 channels with me managing all of them, by the way, and not doing a good job.Stephanie:It sounds very chaotic and not fun.Alex:Yeah. Not at all, not at all. And only until we really peeled back and just focused on a handful of things and did them really, really well, that's when we actually started churning results, but more importantly, honestly, that's when we started actually learning what was working. Because previously, we were just spending a lot of money, we were generating sales, but we didn't really have a clear idea of where they were coming from, again, because the purchase journey was so complex, right? It wasn't a problem that we could solve by just putting an attribution layer in somewhere. We had to really hyper focus on one or two things and do them really, really well.Alex:The concept of growth in the past has generally been focused on the top line. And what that means, often, for a lot of companies, is to just go into as many different channels and try to tap into as many different demographics as you possibly can and then find out what's working and what's not working. I think the issue is that the broader investment community has wisened up to that, right, and they're holding us more accountable on a unit economics and customer economics level, versus just month over month top line growth, which in reality, it's just a vanity metric, right?Alex:So, it is more favorable to take a more disciplined approach, albeit potentially slower top line growth, to really uncover those median sites that you can actually build a solid foundation on and grow a real, scalable, profitable company on versus just something that's just, scaling wildly at the top one but in reality it's just lighting money on fire.Stephanie:So, for a higher priced product like Burrow and a longer buying cycle, what platforms would you advise other brands to look at and optimize for and which ones would you pull back from?Alex:Yeah. So, I think if you acknowledge that it is, there are a lot of things that people have to learn about the product, a lot of things that people have to get comfortable with and confident in the purchase. You think that a lot of these shorter form mediums, like paid social, paid search, right? It's just a quick second and a half interaction with an ad, they're not going to be as effective for a product like ours, and that's true. What we have indexed up on are things that are more storytelling mediums. So, the earliest insight into this was we partnered with a small podcast in late 2017, and it's sort of one of those micro ones, it's not on a network, and just talks about fantasy football. And we just got introduced to the gentleman that runs it, and did a small test, and the results were incredible.Alex:Part of what we've learned over time from that point, rapidly scaled the podcast program for us is that it's highly dependent on the host, and the reason that it's highly dependent on a host is because the efficacy of that channel comes from the quality of the storytelling. And that is really what benefits our brand, is that if we go and we send a podcast host a product and they have the same amazing experience that our customers have, they can talk about it in a much more authentic way, but also, a much more individual way. We've actually matured to not providing very detailed scripts to a lot of our podcasts hosts and just telling them to talk about what has been most exciting for you, and that really brings out the energy in the advocacy for the brand from the host. So, I'd say it's really about focusing on storytelling mediums. So, I lumped other video, long form video into that as well. A little bit less of authenticity, but also helps communicate a lot of these little value props that add up to the major value proposition.Stephanie:So, the other thing that comes to mind is branded content. I mean, I'm thinking about something like Formula One where now the results are out, everyone knows it worked really well for them. It was very, I would think, pretty organic, didn't feel like it was just a brand push. How are you guys thinking about other kinds of content like this?Alex:I don't know if we're at the stage yet where we can start thinking about that sort of thing. I think that Formula One is a great example of taking two powerhouses and linking them together where the sum is greater than or the whole is greater than the some of the parts. So, we're thinking a little bit less about something like that and creating more on a micro scale, I would say, brand and content.Alex:So, when you talk about something like the influencer arena, I am probably the biggest advocate against using influencers in the context that they are used today. And first of all, just to clarify, a true influencer is not somebody that says, "I'm an influencer" on their Instagram profile description, right? A true influencer is somebody that can speak to a community and elicit a response, and often, within a specific category, right? So, I'm not going to give a beauty "influencer" a furniture product and expect him or her to have an outsized impact on the sales.Stephanie:Stephanie:So, you'd focus on the niche influencer who might only have 1,500 followers or something, which is something I think I talked about early on this show, of going through the comments of Instagrammers and seeing, are the people in there asking, "Where can I buy that? Where did you get that from?" Or are they just like, "That's great. Cool. I love that." What kind of engagement are you getting will show if that person has influential power over their community or not.Alex:Totally, totally. And obviously, it's going to vary by a vertical too. This is sort of an extreme example, right? Again, going back to the very considered purchase, even our ability to measure the impact of that is going to be super limited. So, we've actually leaned into the influencer community for, more so is, partnering with actually photography influencers. One of the bottlenecks and problems with our vertical is that our products are very large and our photo shoots and video shoots require massive studios and massive crews that are very, very expensive. Meanwhile, all of these people out there that can already take great pictures and already have really interesting homes need furniture. And so, we can often partner with them in a much more economically scalable way to get a huge diversity and huge volume of content created that can showcase different styles, different aesthetics, different home types, and different personalities, and just build this library of content instead of having to book homes ourselves and go through the whole production process.Alex:So, we've actually been doing that for a while just purely based on economic reasons. But it's interesting to see that now, I think there's going to be a massive shift towards organic for a number of other reasons. When you talk about a lot of the privacy regulations that are going on right now, over the last 10 years, the control of the voice or the conversation has shifted towards the consumer and towards the user. You see like case examples of this with like GameStop, for example. The retail investor just had a massive impact on the market from such a small player, right? Because the control of the conversation momentum is shifting away from the brands that have the big budgets and towards the customers that have the voice, the authentic following.Stephanie:That's the influencer of the year right there.Alex:Yeah, totally.Stephanie:And Reddit. And that's probably where all the other influencers are, an area that I haven't even thought to go, but we've had guests come on previously where Reddit is how they figured out how to build their business, which I haven't even thought to go there. Alex:Totally, totally. I mean, it makes total sense, right? It's experts that are talking because they're passionate about what they're talking about, right, not because they have a vested interest or they are trying to make money off of it, then that's where you get that authentic content from and the actual truth.Stephanie:So, how do you go about incentivizing that or structuring it so it can come in? Because I'm sure a lot of brands are like, "I want my customers to talk about me and take pictures and do all the things," and then they just sit there and nothing comes in. So, what are you doing behind the scenes to make that happen?Alex:So, it's less about focusing so much effort on trying to elicit that response just by trying to elicit it and more about really focusing on that product innovation and that experience that will naturally have that effect on people, right? You don't want somebody to talk about your product in a positive way because you're paying them to talk about it in a positive way, you want them to really advocate, because that means that not only are they talking on the channel that you want them to talk about it, they're also having side conversations. And when people come over to their homes and they're asking, "Wow, where did you get that beautiful sofa from?" They are talking not just about, "Oh, I got it from Burrow," they're also saying like, "And it happens to have these stain resistant fabrics, and it has all of these great other materials, and it was modular, and it was super easy to get it delivered and get it set up." And that's what you really want to go off of.Alex:So, I would say the biggest focus should be on nailing that product innovation and nailing that customer experience, and that's how you can count on that customer conversation to be generated rather than trying to chase down your customers and get them to talk about it in a less authentic way.Stephanie:Yeah, I agree. I think that the days when people on Amazon are like, "I got paid for this review," or something, those will be gone very soon, because I don't know about you, but every time I go through a threat and I see that, I'm like, "Don't trust you, don't trust you." I just want to see the normal person who's reviewing it at their own goodwill, or not, maybe they're mad, but I want that. I don't want someone saying, "I got a free product for this review." That just seems like those days are gone.Alex:Yeah, totally, totally.Stephanie:So, the other thing I want to talk about is product development. I saw that your co-founder and CEO said, "Every single product we've ever launched has exceeded expectations and projections, and that's a testament to our customer-centric research-driven design process," which I want to dive into that and hear. I'm sure many brands are like, "I want every single product of mine to be a success, and I want to expand my skews." So, how do you guys go about designing and crafting new products?Alex:Well, I think one thing that we should clear up is the concept of customer centricity is used so broadly and inauthentically, I think. A lot of brands will claim customer centricity and they'll think that they're being customer centric because that's who their customer is and they just need to make money off of them, and so they'll say that they're thinking about all their needs. The problem is they're not actually talking to the customers, they're assuming on behalf of the customers that they know what that customer needs. Or they're just testing messaging, which is fine. That's been the traditional approach of, "Okay, if I play up this feature or this benefit versus this feature or this benefit, and this one does better, that's what the customer must want," right? But it almost becomes a little bit of a self-fulfilling prophecy there.Alex:We take it to a much deeper level, not just with our customer community but also our lead community, all of our email subscribers that have yet to join and make an actual purchase with us, and actually going to them and asking them very specific and lengthy questions. I remember the first time we sent out a customer survey about one of the next products that we were going to launch and just wanted to get their input on like, "Is this the right product?" Number one, and B, "What are those little things that really bother you about this product?" And did a ton of just open ended response analysis based on that.Alex:The biggest surprise for me from that was the response rate. For a quiz or rather survey that took probably a solid 10 to 15 minutes of someone's time to go through and really complete in depth, which they did, the response rate was astounding. And that opened our eyes to, "Wow, this needs to become a regular occurrence within our work stream."Stephanie:How quickly were you sending this to them? Was it a week after they got their product and are trying to set it up, or what did that look like?Alex:Well, there's a couple different ones. So, what we have is a couple different touch points that are automated or triggered based on somebody actually making their first purchase with us. So, we had, obviously, a post purchase survey right away, which I think is one of the most underappreciated and can be most impactful survey points that people do, or brands do, rather. We also have an NPS survey, which going back to how do you elicit a response from customers and activate customers, NPS is going to be your biggest indicator of how much of that is happening in the background. And that is actually backed up by an element on the post purchase survey where we ask, "Were you were referred by a friend? Does that friend own Burrow furniture, or do they not, or do not know?" And that can also give us a really solid indication of the impact.Alex:So, beyond the triggered survey points, we also do intermittent studies, and it's almost on a monthly cadence now, of either focuses on new categories in general, or we've already identified the category, we've already identified the specific product and we're trying to nail down colors, color combinations, finishes, specific features, doing conjoint analyses on like, what is most important to this set of consumer? I mean, we've really taken it to a super, super deep level.Stephanie:Have there been any products that you launch based off consumer feedback or maybe early launches where it's like, "Oh, they led us astray with that one"? Because I'd be like, "I want a fluorescent pink couch." And then I'd be like, "Oh, I had a little too much wine that night. Sorry about that."Alex:Yeah. Fortunately, we're pretty good at statistics and we can identify outliers and not get swayed by them too much. There actually have not been. And I think it speaks volumes for this concept of authentic customer centricity where... and you can also cross-compare between the customer set and the subscriber set, right? The subscribers are a great audience because they have not purchased anything from you, or at least the subscribers that are not customers, and there's a reason why, right? Versus the customers, they did find something that you offered already and they've already bought into the brand, and they're responding to you because they're still engaged. And so, that's one set of needs that you need to fulfill.Alex:And then there's the other set of needs, and oftentimes, there's a good amount of overlap, which is great for us, and oftentimes, there's not, and that's when we need to make choices around what does that offering look like and who are we really chasing with that?Stephanie:Yep. The other thing I think you mentioned in the past was around how you start thinking about zoning and mapping out what else a person needs in their room, which means like, "Oh, brilliant, okay, if someone got a couch, a little swivel chair, and obviously, they need pillows." And I want to hear, did that method work, and how have you expanded that since you first started trying it I think maybe a year and a half ago or so?Alex:It did, totally. I mean, you take one concrete example of this is with the advent of coffee tables for us. We first launched the sofa and then we launched our first line of coffee tables, and those were specifically designed dimensionally to work best with the sofa styles that were selling the most volumetrically. So, we knew that there was a high rate of match, right, between them. It wasn't like we were designing for something that we were only selling like 5% of our assortment or something like that.Alex:Where that took another level is in 2019, we launched the corner sectional, and then arrangements and configurations started getting a lot more varied and a lot more... opened up actually, additional demographics as well, with more suburban, satellite city homes with larger room spans. And that opened up a new category, and so what we had to do is to figure out, "Okay, well, if you have a five-seat corner sectional, none of our coffee tables really make sense for that. And so, how do we create a coffee table that works perfectly in that configuration for that customer specifically?" So, that's when you saw in late 2020, we released our Kettle and Signal collections, which are more of a round geometry versus a rectangular geometry. And that happens to work really well with things like a Double Chaise Long King Sofa, where the chaise is wrapped nicely around the round coffee table, or the corner sectional, it creates a really nice conversation pit type feeling.Alex:So, it is very much about understanding how our pieces interact. And then the next level that is, what are the types of rooms that people are using it in? What are the actual dimensions of those rooms? And what logically, could somebody need the most, given that room design and size?Stephanie:It seems like a lot of brands are missing that right now, because oftentimes, I mean, whether it's furniture or a lot of other things, I'm like, "Where is that matching dresser set? Or where is the pillow that goes with that?" And it feels like having to go around and look in different places and trying to find it myself, I'm like, "Why am I doing the work? I just want a kit which is like, 'Here's all the five things that match together.'" But why is that so hard? I don't get why can't brands do that?Alex:I think one of the biggest examples of this is that company brand list that skyrocketed, but they were launching things in such unrelated categories that there was no bond between them. And companies nowadays need to think a lot more about lifetime value than they had to necessarily, in the past. Acquisition cost is growing, and they can no longer just rely on first purchase profitability in order to sustainably scale their business, and they need to think about building a relationship with the customer. And that often comes from creating relationship and being the default brand or site to go back to when they may have that next need and finding that perfect accompanying piece, right? Versus just like you buy cleaning detergent from the company, and you come back and, oh, they're offering soccer balls or something.Stephanie:Pillows.Alex:Yeah, it's like, "Okay, well, that doesn't make sense."Stephanie:Yeah. Which makes me think, I mean, it seems like the world is headed towards a more curated world right now. Maybe back in the day, I would go to a Wayfair or something like that and I'd be like, "Cool, I'm fine with scrolling, scrolling," five years later, still scrolling and looking for what I want. It doesn't seem like consumers want that anymore. So, how do you see the consumer journey and preference adjusting now where maybe a couple years ago, that would be totally fine?Alex:Yeah. I think it's almost a byproduct of the ease of standing up a company nowadays. It is exponentially easier to start a company, a direct to consumer company than it was 20, 30, 40 years ago. So, because of that, the market has just blown up in terms of the number of companies. And so, the paralysis of choice has shifted from like going to an old school Sears or Macy's and just having like a million different options, or as you put it, like a Wayfair, and just tens of millions of options, to now having to build a relationship with a brand and trust that that brand is making the right decisions. And so, that's why we offer a very select assortment of fabric colors, leg finishes, arm styles. In reality, we can house tens of component skews and offer tens of thousands of combinations to the customer, but what's ultimately the most important thing is that we do it in a way that is still a very simple and clean experience for the customer so that they get that sense of they're creating their own product, but not to the extent of being overwhelmed.Alex:I think of myself on old school furniture sites and staring at the screen from two inches away trying to figure out the difference between this gray and that gray, and I'm like... and then you request swatches from them and they come 10 weeks later.Stephanie:Yeah. I've recently been through that experience. It's not great.Alex:Yeah. No, it's not fun.Stephanie:They arrived and I'm like, "What was I trying to buy, again?" [crosstalk]. I mean, it seems like you guys could also have a very localized approach where, like you mentioned earlier, if someone is looking from a very suburban area, like my hometown in Maryland, where my expectations there would have probably been to have a huge wraparound couch, I've got this big living room, versus being in San Francisco or Austin, where now it's like a little bit more limited space, and what can I fit in these small areas? [crosstalk] think about that?Alex:I mean, the first step there that we're taking, it's more from a content driven approach. So, that goes back or loops back to the way that we're treating influencers and leaning into the photography community and the different styles and aesthetics that they have. Because what we are creating are based products. They are beautiful but they don't belong in an architectural [inaudible] editor's home, right? They're not the one-off piece that you design and custom build for 15 grand or something.Alex:And what's beautiful about that is that they stand up to any environment that you're putting them in, whether it's a very eclectic like Austin ranch style home, or the fourth floor walk up apartment in New York, or a more sprawling home in Houston or another geography like that. And leaning in with more of that stylistic approach than necessarily sub-segmenting, "Oh, we're only going to show love seats to this geography, or we're only going to show these massive sprawling corner sectionals to this other geography," because people still have varying needs, a lot of people have multiple rooms. So, we don't want to limit, necessarily, the assortment, but we are trying to diversify constantly the styles and aesthetics that our products are showcased in.Stephanie:Got it. Yeah, that makes sense. So, for the last big point, I wanted to talk about the industry as a whole, like the D2C industry, commerce, what kind of things are you seeing or preparing for behind the scenes for what's to come?Alex:I mean, we could talk about the elephant in the room, which is-Stephanie:Let's talk about it. Yeah, let's do it. I haven't really talked too much about that, because it's been so up in the air, and when's it going to go through? It's more official now, so let's do it.Alex:Oh, yeah, it's official. This is a tough thing, and I think it's a reckoning for a lot of these companies, again, where it's been so easy to start a company and just go on Facebook, and you'll generate some sales, and go to a VC and you'll show 100% month over month growth, and they'll throw a bunch of cash at you. That's changing, and I'm thankful for it as much as I curse the fact that we don't have this GPS anymore, I'm very thankful that we don't, because it's forcing us to mature as marketers. And we're fortunate also that we've had to embrace this appreciation for marketing 101 and really lean into principles and not just trust what the ad platform are telling us, because it's a whole shopping journey.Alex:So, we've built a very healthy, full funnel approach proactively, even without any of this talk about these privacy regulations. That has helped us create something that can stand up in the face of this. There are a lot of companies that have not done that, they've not invested in really understanding marketing 101 and how to build a healthy full funnel without having that very granular level of insight or having automatic triggers in their campaigns and stuff. So, I think that is the most important thing, is like there is a day of reckoning for marketers everywhere in the D2C space to take a step back and really appreciate the principles of marketing and evaluate your program architecture overall and make sure that it's in a healthy state, and not just because your add to cart rates or your conversion rates are really high from this one campaign in this one ad unit, but really, overall, how is your program operating? Where are the weak points and how can you supplement those?Stephanie:Yeah. So, if you were starting over day one today, what kind of things would you look at? What metrics would you look at? What kind of things would you put in place to start building up that healthy funnel?Alex:Yeah. I think we would look at... I'm trying to think if I didn't have all the information that I have today, but I think what you would look at is the abandonment rate through the funnel, right? Of the people who click through to your site, how many of them end up viewing a product? Of those people, how many of them end up adding it? Of those people, how many of them end up actually proceeding to step one of checkout, step two, step three, step four? And find out what that makeup looks like.Alex:And obviously, you're going to spend a lot of time on conversion rate optimization and trying to improve the outputs of each step of that funnel. But that paints a picture of, okay, how broad do you have to invest at the top of that funnel if your ultimate target at the bottom of the funnel is X? And what does that reach look like? And what are the best mediums to do that to actually elicit a response and get people onto your site or into your store or signing up for whatever service you provide? So, that, I think, is what I would take as step one.Alex:The other one is, I would just consider, for the vertical that you're in and the product that you're trying to sell, how much of a story do you need to tell? And that will help inform how much you will need to invest in more storytelling mediums than more immediate click to buy type mediums. Also, how visual is your product? That will tell you how much you have to be content driven versus leaning into things like search or audio formats or anything like that. And that can really help govern your channel choices.Alex:And then the last thing is just, don't fall into the trap of doing too many things at once. There's always something to be said to acknowledging the resources that you have and trying to build a architecture that is best for that set of resources, not just the one that happens to be doing really well for the other portfolio company that your VC backer is constantly in your ear about, you have to focus on what is going to work for your company, your vertical, your customers specifically.Stephanie:Yep, yeah, I love all that. Is there or are there any tools right now that you're very excited about that are either new or just time tested, you're like, "We're going to keep using these forever because they do wonders for our marketing efforts"?Alex:I think a lot of it is less about tools and more about information sources. So, we've partnered with a number of different companies over time to do things like customer enrichment and really understand our customers to a deeper level, again, going back to that concept of customer centricity, not just talking to them directly, but also learning much, much more about them. And I think one of the biggest traps that a lot of companies fall into is they think of their customer as an average customer, and the problem is they're failing to acknowledge that customers are not one monotonous group, they are a system of clusters and cohorts. And what you really have to do is understand what is unique and important about each of these clusters and then create a messaging architecture, channel architecture, product offering that really speaks to each of those clusters individually.Alex:So, from a tools perspective, it's more about these data enrichment, customer data enrichment type platforms, and then using those to create these clusters and cohorts and really understand those customers. Again, for us, an attribution platform, not super helpful because of the complexity and both mix of offline and online activity that it takes to get to the purchase point. Much more about really understanding the customer and then applying a marketing 101 approach to it.Stephanie:Cool. Yeah, that's great. All right. Well, let's shift over to the lightning round. The lightning round is brought to you by our friends at Salesforce Commerce Cloud. This is where I ask you a question and you have a minute or less to answer.Alex:Oh, boy.Stephanie:Ready, Alex?Alex:Sure.Stephanie:Oh, boy. What's one thing you don't understand today that you wish you did?Alex:Shoot. Where do I start? I think I would like to understand more about the global supply chain. I think over the last six months to a year maybe, we've seen, very intimately, the impacts of a broken or strained supply chain, and I think that there's a huge opportunity for D2C companies to innovate on the supply chain side. We focus so much on how do we innovate on the customer side that we focus so much less on the supply side of the business. So, I think that is where... and it will become increasingly important for marketers and supply ops to be speaking and working very much hand in hand to grow a company together. So, I do wish I had more of that background.Stephanie:Yeah, that's great. And you guys just raised around, and I think that money, a part of it, was to focus on international supply chain effort, right? Figuring that out better.Alex:Yes, totally.Stephanie:So, you're already right in the right spot, the right time. You'll have to let everyone else know the insight. You have to come back and tell us what you learn next year.Alex:Yes, definitely.Stephanie:What's up next on your reading list or podcast list?Alex:There's actually a couple books I think that I want to reread. I'm one of those weird people that really likes to read technical books, and so there's a couple of conversations we're having right now about pricing in this book called Power Pricing that I love to read. There's also one by a gentleman named Douglas Holt called Cultural Strategy that I think is one of the most foundational and important books, especially for the world today. And again, how the customer controls the conversation, and understanding how to position your company and your messaging around cultural movements and ride momentum versus trying to create that momentum yourself as you have in the past. The last one is Shoe Dog, actually.Stephanie:Yes, such a good book.Alex:Amazing book. This would now be, I think, my third time reading it, but it is a way to, I think... A lot of people have been talking about languishing right now and the fact that we've been in this environment for so long and we're yearning for that personal interaction, and so tired of being in the sedentary and fixed on a digital screen environment. And I think Shoe Dog can help reignite a lot of that passion, right? Because it's like, "Wow, this multi-billion dollar company started at such a microscopic level." And it really helps you understand the power and the capability you have as an individual to create something like that and can help really reignite that passion.Stephanie:Yeah, that's one of my favorite books. Actually, we have a podcast called The Story that tells the unknown backstory of people who change the world, and we highlighted him in one of the episodes because we were like, "The story is too good not to tell, and tell, and tell until everyone hears it, and gets motivated and starts their thing today."Alex:Yeah, totally.Stephanie:That's awesome. I feel like they need a movie out or something. Do they have one?Alex:I'm sure there will be. I'm sure there will be.Stephanie:There has to be one. Too good of a story not to. What's one thing you're secretly curious about? [crosstalk].Alex:TikTok, I think.Stephanie:Are you all on there?Alex:We are not. From a demographic perspective, in the past, I would say a year and a half, it hasn't made sense. The program is continuing to grow, the demographic adoption is continuing to expand, and so I am interested in what it looks like going forward. I think it is also a challenging medium for a lot of brands that are really attached to high production quality content, because what scales the best on that platform is very lo-fi content, very organic and authentic content. And it creates this shift for a lot of companies in the way that they think about creative. So, I'm curious in that we are actively learning about our potential approach to that channel, but also curious about how does that platform and program evolve over time. I've not heard great things about the ad platform that they've built so far, which is partially why we've been hesitant to really go after the channel, but that will evolve. They will crack that code. And what that looks like, I don't know, but I'm certainly curious.Stephanie:Yeah. We've definitely heard 50-50 on TikTok, some brands saying it works wonders, but they're the ones creating their own content, maybe not an ad partner programs. I also think from a consumer standpoint, how it's going to evolve, because at least me personally, I think I got signed out and I couldn't remember my password-Alex:Oh, no.Stephanie:... and I just never signed back in. I'm like, "I'm not sure I really like it then, or maybe I know that just scrolling is not good for me."Alex:Yeah. That was me with Clubhouse, actually.Stephanie:Oh, same.Alex:I loved Clubhouse for the first seven days and was on it constantly and I have not been back on it for [crosstalk].Stephanie:Yeah. I think it got crowded. I mean, now it's just so busy, so many people talking about so many things, it didn't feel curated. I started feeling like that to me too where it was 50-50 of like, "I like these videos, and next nine, I don't like." I think there has to be curation to keep at least us involved, it sounds like.Alex:Yeah, totally. I mean, honestly, that's what happened with the podcast world too, right? It became everybody launched their own podcast, and then there's so much content. The biggest problem with podcasts now is discovery. The only way you learn about what to listen to is through your friends.Stephanie:Yeah.Alex:And so, that concept of discovery is such a challenge for podcasts right now, and I think that's what Clubhouse is going through at 1,000 times faster through the learning cycle.Stephanie:Yeah. I think the next couple of years will be interesting, because I mean, they've been talking about discovery issues back to even when I worked at Google, figuring out Google podcasts, and that was an issue back in 2017. So, why hasn't this been solved yet? It should be so much easier.Alex:Yeah.Stephanie:All right. Well, Alex, it's been awesome having you on the show, such a fun conversation. Where can people find out more about you and Burrow?Alex:Burrow.com would be the easiest place.Stephanie:What about you? Are you on LinkedIn? What if people want to talk to you?Alex:I am. LinkedIn. Alex Kubo. I'm not sure if you can actually search me and find me, but I'm sure you could.Stephanie:I'll find you. Don't worry. All right. Thanks so much, Alex.Alex:Thank you so much, Stephanie.

Up Next In Commerce
What It Takes to Break Through in China

Up Next In Commerce

Play Episode Listen Later Jul 6, 2021 41:19


From starting a hedge fund to owning the DTC beauty market in China is a career path you don't hear too often. But that's the winding road that Julian Reis has traveled and along the way he's picked up some critical intel about the ecommerce world and Chinese trends that he shared with me on this episode of Up Next in Commerce.There are a bevy of factors to take into account when entering the Chinese market. From the vast differences in the way consumers shop in China to the sheer volume of consumers that can make a huge boom in sales in a matter of moments, there is a lot to contend with. And how does a brand even get in front of a consumer without traditional ads or email marketing? And what about social media? Or regulations? Julian explains how to take all that information into account and build an ecommerce strategy that lets you win abroad. Plus, he dives into how his company, SuperOrdinary is working with top skincare brands to enter the Chinese market, and some of the experiences that can be expected when embarking on this new path. What a fascinating discussion that was so different than any interviews I have had so far, enjoy!Main Takeaways:It's All Chinese To Me: Brands might want to expand to the Chinese market and believe that there is a huge opportunity there, but rushing into the market without doing the proper research could be a huge mistake. Despite the fact that a lot of information is censored in Chinese, consumers there still find ways to access the content that is important to them. Brands need to get more social awareness, learn about what Chinese consumers are interested in and let their actions reveal whether or not you have a product-market fit before trying to make a splash in that market.Platforms vs. Pages: There has been a bifurcation of ecommerce between platforms and webpages. The debate about where to invest more is coming down to how you see your customers acting. SuperOrdinary's theory of the case is that platforms are the way of the future because at the end of the day, customers spend more time on Amazon and Tmall than on a company's website. Therefore, more focus should be on creating content that drives engagement on those platforms. Boom and Bust: In China, the volume of consumers is so much higher and there is so much more emphasis on influencers and celebrities, that if something goes viral, a brand could do millions of sales in a matter of seconds. Being prepared for that kind of boom is very different from working in the U.S., where you prepare for steady growth over a longer period of time.For an in-depth look at this episode, check out the full transcript below. Quotes have been edited for clarity and length.---Up Next in Commerce is brought to you by Salesforce Commerce Cloud. Respond quickly to changing customer needs with flexible Ecommerce connected to marketing, sales, and service. Deliver intelligent commerce experiences your customers can trust, across every channel. Together, we're ready for what's next in commerce. Learn more at salesforce.com/commerce---Transcript:Stephanie:Hey, everyone, and welcome back to Up Next In Commerce. This is your host, Stephanie Postles, CEO at Mission.org. Today on the show we have Julian Reis, the CEO and Founder of SuperOrdinary. Julian, welcome.Julian:Thank you, Stephanie. Lovely to meet you.Stephanie:I'm happy you're here. I'm glad you're not in Hong Kong. I was a little bit worried at first. Like, it's got to be 2:00 AM for this guy, talking on the show. I mean, I would have also appreciated that, but that's okay. Before we dive in to SuperOrdinary, I want to hear about your background because you have a very fascinating background, and I want to hear what led you to the beauty industry.Julian:Great. Thank you for having me. Well, first of all my background, I'm half Australia, half Chinese Portuguese. I was born in Australia, and at the tender age of five I moved to Singapore, where I followed my parents. My dad was working for Pizza Hut. And my twin brother, who's identical, we grew up in Singapore and we kind of were brought into this world to experience all these different cultures, and really thank my parents for giving us such an international upbringing. We all went to these international schools in Singapore, and then Hong Kong, and really got a flavor for all the different Southeast Asian countries growing up. I went to study in the UK to confuse myself even more, and studied economics at University of Nottingham. And Justin, my brother, was in London at the London School of Economics. And we kind of had these parallel paths where we didn't know what we wanted to do after university. And I was always intrigued by the financial markets when I was at university. I always thought that ... This was at the time when we still had analog Internet, dial-ups. I was always curious to see how people were thinking about this global economy.Julian:I applied to probably 150 jobs after university, and got very disheartened that I couldn't move to Tokyo, which I had this dream to always live in Japan. And I found myself finding a job eventually in New York, at J.P. Morgan. I was one of 3,000 applicants to the markets training program, which was a rotation through JP Morgan training program. And I still don't know how I got it, but I was so thankful. I went to New York without even an interview, and basically phoned from downstairs and told the graduate recruitment officer that, "Hey, I'm downstairs. You might as well see me." And suddenly, I got the job. I feel very, very lucky for that.Julian:Went from there to, as a trader, I was trading derivatives in fixed income, which is straight derivatives. And that really started to shape my career, about thinking about the macro markets and how you need to think about the world. And after three years, I moved back to Asia and found myself working at Deutsche Bank and building my career as a proprietary trader.Julian:And then I realized that I would love to try and build my own business. And in finance, you either work at the lease investment banks as a trader ... Because the idea of a hedge fund was still very new. And when I was 27, I decided to go alone and start my own hedge fund. And tried to rustle up as much money from my friends and family, and realized I didn't have that many friends and family. And started my first hedge fund, which was called Pagoda Capital, which was one of the first macro funds in Singapore. I got acquired by Tudor Capital a year later and became CEO of their Asian business, building out their macro strategies in Singapore and Australia.Stephanie:How did they want to acquire you after a year? What were you doing? You must have been doing something amazing.Julian:You know, it was kind of interesting at the time because we were one of the only funds in Asia doing what we were doing. And there clearly was ... And this actually dovetails into what we're doing now because we saw this opportunity to build a business around the Asian markets, and many of these big, large, successful brands or hedge funds in US wanted to get exposure to this market. And the way they did that was find like-minded individuals who were trading, and eventually we came together and built this business. And Paul Tudor Jones is still, to this day, one of the guys I idolize the most in the world. And that gave me my introduction to the financial markets.Stephanie:Very cool. Okay, so your hedge fund gets acquired. You're working there for a bit. And then what?Julian:And then what? I moved to the UK again, working at a new hedge fund which I founded. And I realized that the common thread to all of this was that I really enjoyed building businesses. And I really felt like from zero to one when you're building a business, it's all about hiring the right people and building successful partnerships. And after a couple of years of working in the hedge fund industry, we entered 2008, which was obviously the financial crisis. And what became really apparent and important to me was that this was not sustainable, and that it was really exciting to see what other opportunities there were for me in my life. And at the time, was a very difficult time because to change out of a career or something that you'd been trained in to move to a completely different industry was very scary. And I thought long and hard about making that decision.Julian:And I met this lady who was starting a Groupon startup, and I said, "Listen, if you decide to do something in beauty, come back to me because I think there's a really big opportunity." And I started to see that the Asian population or the communities were really interested in foreign brands. And I was a founding investor of a company called Luxola, which was the ecommerce 1.0, distributing brands in Southeast Asia. And after two years, was acquired by LVMH to become Sephora's digital presence in Southeast Asia. So, really got an understanding about learning, about building and investing in the beauty side.Julian:And then I thought, well, why not try my hand at building my own brand? So, moved to the US to start a brand called Skin Laundry, which is a skincare brand focused on disrupting services. And really proud of what Skin Laundry has become today. It's now in five countries around the world, in the Middle East, London, Hong Kong and all throughout the US.Stephanie:Did you sell that?Julian:No, I didn't. The brand is still operational. I still remain one of the largest shareholders in the business. But really brought a management team in to really accelerate the brand. I think it's a very unique concept, and continues to be a loved brand by the customers. And I think by working and building a brand on that side, really started to, when I was back in Hong Kong and I noticed in China many of the brands that we were exposed to whilst we were in the US were not available in China. And that's where SuperOrdinary was born.Julian:I moved to Shanghai three and a half, almost four years ago now. And kind of just wanted to study how brands are being bought and sold in China. And then the light bulb went off and said to me, "This is an incredible opportunity. All these digital native brands that we see in the aisle of Sephora and Ulta and Mecca, why aren't they available?" So, I started the company and started hiring my first-year employees in a country that I had very little experience in. And I didn't speak the local language. I could only speak pidgin Mandarin. And I said, "Well, this seems like a big enough challenge. Let's go."Stephanie:That's a niche, [inaudible] opportunity. All these brands should be in China but they weren't. I mean, what are some of the top reasons why brands maybe don't even think about bringing their products to China? Because from the outside, it does feel scary, and regulations. And does the customer there even want what we love here? Seems like very different things that they love versus maybe what I might like. What are some of the reasons that you hear brands are like, "I've never thought about that before"?Julian:Well, I think the first thing which you kind of touched upon is the regulation. First of all, animal testing is obviously something that many of the brands, or most of the brands in our portfolio, goes against the DNA of what they believe in terms of cruelty-free. Luckily on May the 1st, animal testing regulations now be announced to have gone away, which is incredible because it just opens up this huge, untapped, physical market domestically.Julian:I think because of that restriction, it was very difficult for brands to enter China, and so everyone hears of these stories about Chinese tourists coming overseas and bringing back suitcases of products in the suitcases, and reselling them locally. And I think what happened was that the government obviously realized that this was happening and said, "Rather than smuggling products into the country, let's create a channel for these products to enter the country on a legitimate basis, and let's make sure that they're real products, authenticated, they're registered, and then they can be sold."Julian:But in order to do this, this channel which we call the cross-border channel, only limits the amount of products that you can sell to an individual consumer in China on a given month or a given year. There's a quota in terms of absolute R&D value. Whilst it's an exciting channel and it continues to grow, represents close to 20% of the ecommerce market, obviously there are restrictions for that. We started our business as a cross-border business which allows us to work with brands anywhere from Farmacy to The Ordinary, to Drunk Elephant, Supergoop!, and we really have an incredible partner portfolio. And to be able to build their presence in China by creating a profile for them on social media in all the different channels, on Tmall, and really build a brand from zero and continue to grow them there across multiple channels. That's how we started.Julian:Now, we currently have globally close to 300 employees in the company now, most of which are based in China. And I think what we do as a business is really provide that one-stop-shop service where we really build your brand. Where we call ourselves not a distributor. I would almost call ourselves the general manager of your brand in China, because we do everything that you would do as a brand owner by operating your brand in a foreign market.Stephanie:Yeah. What are some of the tests that you do to figure out what the market here even wants this? Because that seems like a big thing. If a brand comes to you and they're like, "I'm selling this," and you're like, "That might not even go well here." What are some things that you think about if a brand should even try to enter China.Julian:Yeah. I think, I mean that's the million dollar question. And I think what we do, we've gotten a lot better at it because I think the consumer there is very discerning, even though a lot of the information about that brand is not readily available on Chinese social media. There are ways to get it, and people do find out about it. What we typically do for any brand that wants to work with us is really have initially a conversation to really understand what the point of difference of the brand is. And really just see if there's a product market fit. We do a lot of desktop research around the brand, not only in its home market but in China to see how big that opportunity is. If someone comes to us and says, "Oh, we want to launch blonde hair dye in Shanghai and we think it's a big market because it's big in the UK," we have to question is there a demand for people to dye their hair blonde.Julian:And I think that's what we do, and we've gotten better at, is we test a lot of the products within our team. We have experts in each of the categories that we manage who really are our first port of call in terms of trying to see if there's an understanding or a demand for this product. Remember, all these brands have zero social awareness, and as the market's got more and more expensive to launch a brand, it's really important for us to make sure that if we get behind it, we're going to be able to spend the marketing dollars to get the brand to where it needs to be for it to make sense financially.Julian:After two weeks of very deep due diligence on the brand, we'll go back to the brand founder and say, "Listen, we think your hero product in America is this, but you know what? Actually in China, we think it's A, B and C." That helps us have this conversation and once we get to that point where we think that there's an alignment, we then start working on financial terms on how we would work together.Stephanie:What's interesting is that your background in the hedge fund world seems like it would be so helpful when coming and analyzing brands, and looking for opportunity.Julian:That's right.Stephanie:And looking at competitors and stuff. I mean, it seems like a perfect fit of how you came about even into this world, which is really fascinating.Julian:I think the hedge fund world really gave me an appreciation of data, and really thinking about data in a different way than I would normally do. For us to, whether it's analyzing the influences that we work with, or analyzing the livestreaming broadcast that we'll do tonight with Austin Li, or analyzing LTV and CAC on the brands that we manage, it's really become you're heavily reliant on it because if you don't rely on it, then you start to not make better decisions.Julian:And what we've done at SuperOrdinary is using that data that we give our brands, our partners, visibility into the consumer in China. And that gives us informed decisions on what products to make next. And I think that's really exciting for our brand partners, to know that this product, this moisturizer, may be too viscous on the skin. Or, this tint doesn't blend well with this lipstick shade. It's too bright. All of this information helps guide their product development. And for us to be successful, they have to be successful in their product development. So, data has become a really big part of our business model.Stephanie:Is there a different way they have to go about collecting the data there? Versus in the US, maybe you would do surveys, you would just directly ask, you would do your email marketing stuff. How would you go about collecting that data in a way that keeps you safe?Julian:Well, I think everything you learnt about business in the US market, you leave at the door when you walk through Shanghai Airport. And I think that's where you have to really come in with eyes wide open to say, "How is the consumer interacting?" First of all, there's no websites in China, so you're working through these platforms. And we have a market in the US where you have a very large amount of websites in the US market, whereas in China you have zero websites. But you have all these platforms. The world's bifurcated between platforms and D2C websites.Julian:And our view at SuperOrdinary is that platform is where the markets head to. The websites are where you discover your brands, you learn more about the content, you go to Instagram, you go to Sephora. But at the end of the day, where do you gravitate to? Well, where you're buying your products, on Amazon, on Tmall, on Lazada. And this is where I think we really try to create this vision of where SuperOrdinary is headed. And it's very important that our brands believe in this strategy too, because this is the direction we think beauty is headed.Julian:In China, I think to your question collecting data, the data that we get is readily available. You can see what people's revenues are by looking at Tmall data. But I think what's interesting is that we have a lot of other platforms, like the equivalent of Reddit and Quora that allow us to see what people are asking about brands. They're looking up ingredients. They're looking up what squalane means. They're asking what hyaluronic acid does to your skin. And that kind of data there is really important.Stephanie:I mean, how would a brand even think about getting in front ... I know you're talking about platforms and different ways to think about it. So any brands here are used to paid media and email marketing and Instagram and all that, so I know you have to just completely turn off all those ideas and start from scratch. How should a brand think about entering a new market? Even trying to get their product there is one thing, but then trying to get the word out, especially if they aren't working with a firm like those. How would they even go about that?Julian:Well, I think that historically, when a brand has entered the market it had a number of choices. One is to go through a multi-brand website that sells products and posts it into China. The problem with that is that your product may or may not get to the end consumer, so there's a lot of risk. That channel is obviously a very small one.Julian:Two is to go in it alone. Go to China, hire a team, spend 10 million dollars. Really go nuts. And after five years, you'll have lots of learnings. Pretty much what I've done, and figure out oh my gosh, there must have been a better way to do this. I'm not only spending a lot of money, but I'm losing time.Julian:Really, the way we approach our playbook ... And it is a playbook, because it is after many years of learnings, is making sure that you focus on the brand and what it stands for, making sure that the messaging behind the brand is consistent. You don't want 16 different platforms saying 16 different things about your brand. And also, the other thing is there's no such thing as seeding. You can't just send out 100 packages and expect to receive 100 posts. So, it opens a pay-per-play environment. And that's because the cultures are very different, too. Understanding the culture is very important to know where is your consumer spending most of the time? I think it would shock most people that 88% of the beauty market is Gen Z and Gen Y, Millennials. And more than 50% are purchasing products on their mobile phone. And they're looking to spend more and more on skincare and color.Julian:I think understanding that just helps you frame how do you, again, those consumers. Where are they spending their time? They're spending their time on TikTok, or Douyin in China. They're spending their time on Little Red Book to discover ... And so we at SuperOrdinary have a very large team now that speaks to over 40,000 influencers or KOLs, directly or through agencies. And I think because SuperOrdinary has a very exciting portfolio of brands, we're able to authenticate the types of brands we work with. So, we're able to work with the very best livestreamers in China. We're probably one of the most active in the livestreaming area. And that creates a lot of awareness around the brand.Julian:Building a brand from zero to one is the hardest part. It's the most expensive part of the curve. And then year two, year three should be easier. Getting it right is very important, so providing a very concise go-to-market strategy, making sure that the messaging, whilst it's in local language and it feels local to the consumer, is not different to what it is in the US. We don't want to be talking about a brand and not be in line with the brand guidelines, but making sure that the emojis, the hashtags, the cute names around the products really make sense to the local consumer. There's a lot of hard work that goes in before we even launch a brand. It's not just putting it on Tmall and then putting a price, which is traditionally what a lot of the local TPs have done. We really feel like you have to take a much stronger brand view about building that channel.Stephanie:Yeah. I mean, totally agree. What are some of the biggest surprises, maybe, that brands have? When you're going through and you're working with them and maybe you say, "Okay, but we need to do it this way," or, "This is what they're expecting," or, "Influencers are the way here. It's not just a nice to have like it is here. It's like, this is the way to go." What are some of the surprising things that brands maybe aren't expecting when you work with them?Julian:I think volume. Volumes can get big very, very, quickly. It's not uncommon that you will enter a livestreaming event and will do 3 million in sales in 20 seconds. The market is that much bigger. But at the same time, in the US we're used to growth, very steady, 10, 20% every year. And that's achievable. And in China, something could happen where a very big celebrity will go to London and find your product and talk about it, and then boom. It's all gone in China. You cannot find it. And it's just because the absolute size of the market is that much bigger than the US, and that when the community is all on their phones buying and following these influencers, it's very much an influencer-led market and celebrity-led market. I think that shocks a lot of brands. Why doesn't it have some steady growth?Julian:I think they also realize, the shock, the difference is that it's how text-heavy the interaction with media is. While here in the West we're very visual, in the East it's very much about information. Before you even get to the ingredients, there will probably be seven pages of text telling you about the product, the storyline. And then at the end, there will be some more information about the product itself. It's really important to realize that's how they shop. I think that's another one.Julian:I think yeah, I think also the market there moves very quickly. It's very saturated as well, because everyone sees China as almost like the Holy Grail during the COVID environment. I can't tell you the number of times people have asked me, "Oh yeah, this is a must have." Also, I think on the downside is just measuring people's expectations lower. Just because it's a big market, doesn't mean your first year you're going to do 10 million in sales. It's really about it takes time to build a brand. Five years, minimum, in the global market, so why should it be any different in China? My advice is really be patient with your brand. If you give it the love and tender, loving care over the next five years to make sure that it's there in five years. You don't want something doing this and doing this.Stephanie:Yeah. I mean, that's what I was kind of thinking when you said okay, you could do 3 million in sales in a matter of seconds. How could a brand think about setting up maybe a longer-term strategy there? Because when I'm putting on my US-centric view, I'm like okay, you've got SEO stuff, you're getting to the top and you start ranking, and then people see you more because you've proved that you're best long term, and Amazon do the same thing. And there, it feels like if it's so based on maybe influencers and celebrities, because you can have these blips of when you can get in front of people. How do you maintain a brand there long term, where it's not just crazy sales and then to until you have your next celebrity or influencer talking about you again? How do you think about that?Julian:I do think that's a billion dollar question. Really believe.Stephanie:I do those in my head, billion dollar questions.Julian:Because I feel like China has gotten to a cycle or a rhythm of doing shopping festival after shopping festival, whether it's 11.11, 12.12, 618, Secretary Day. These events become so gravitational for the consumer because they know they're going to get the best offers on those days. Naturally brands, if you don't participate in them, you miss the traffic which helps get you more and more awareness.Julian:I think channel dispersion is important because you don't want to be so focused on one channel versus the other. But I think with the opening up of the market with the removal of animal testing it's going to allow us to become a much more measured approach. And what I mean by that is just imagine if you could only sell your brand through Target. And you live and die by Target's traffic. Of course you're going to play along the rules that Target might have given you to go and say, "Oh, here you go and sell that."Julian:If you can imagine that you can leave Target now and open up in all these different retailers in the US, now you have a lot more control about your brand. Just like that in China, I think we're going to have this opportunity to build brands in a much more succinct manner, and open the doors that we think best represent the brand and not have to scattergun it through all these different social channels.Julian:And also, it's fair to say that the consumer now will get to touch the brand and the product for the first time in these physical stores. And it's not just Sephora. There's seven to 10 other competitors in China which have got insane new retail experience, so I think the market there is 10 to 15 years ahead of the US in many ways. And that's another shock to most brands, is like, "Oh my God. This really, truly exists?"Stephanie:Yeah. What are some of these experiences that are so far ahead that maybe we should be looking into?Julian:Yeah. I think the consumer, when they go to a retail store in China, traditionally you go to a Sephora which is really much about it's glossy black, it's got music, you've got these beauty assistants that will come in and they would really sell you the product. China has also gone the other way, where they've removed all the beauty assistants and you go in there and it almost feels like a ghost town. But you get to try all these product and sample sizes. There are examples of that. And there's a shop called Harmay, H-A-R-M-A-Y, you can Google it, have a look. It looks like a museum. And they're 10,000 square feet, and it's very Instagram-able. That's a word. But it's one of these things that I think has really changed the way that people are interacting, because people want to drive traffic towards the door, there has to be a reason. Especially when you can buy everything online.Julian:I think that's really exciting. And I think I always get asked the question of, why is livestreaming working in China versus US?Stephanie:Yeah. That's a big one. Whenever people have come on here and talked about ... We had one guest who taught Harvard, and they brought a livestreamer from China over to show how many Harvard t-shirts they could sell, or hats or something. And it was insane. But then also it was like, I don't know if that would work here. I don't know. I just doesn't feel like a similar market around how it was happening. I don't know, it just didn't feel very familiar.Julian:Yeah. I think culturally, in the US and the West we don't like to be sold to. And that's why Instagram is very much a place where you build relationships with the other person. I think that's fundamentally where the big difference is. And remember, livestreaming in China is a business. These livestreamers are starting work at 6:00 PM and clocking off at 2:00 AM, and they do that 365 days a year because it's a business. And they have tens of people underneath them that are helping them bring in product to talk about. I think when you think about this is your starting block, and when you think about in the West, I don't think people will approach livestreaming in the same manner.Julian:I think at the end of the day, the winner in livestreaming in my view is that it will be the platform. I would make a bet that Amazon would probably be the leader eventually, because they're the ones that are going to be able to fulfill and deliver multiple brands and multiple products to the consumer in a very fast fashion. However, it's exciting to watch all these new platforms come about into the space.Stephanie:Yeah. Are there any other trends that you see happening in China right now that you're like, this could work in the US? Or, this should definitely be brought back because people would love that here?Julian:I think China's done a really incredible job of cross-collaborations with really interesting partners, like very nonsensical to the West. I don't know. In the West, you'd see a clothing brand pair up with a skincare brand. But in China, they'll go KFC will do something with a perfume brand. Or, a bubble tea will work with Fenty Beauty. Really, they like to think out of the box in the market, and I think that's really exciting.Julian:I do like the idea of sampling. I think sampling is something that the US has always been involved with, these boxes that get delivered to the customer and these subscription boxes, whether it's Birchbox or BoxyCharm and all these different ones. In China, I see that there's this interest to go and try sample size products at stores. I think that could eventually translate over here, and I think that would be well received.Stephanie:Yeah. I mean, I think about Costco. I wonder how much business they've lost because people like samples.Julian:They do, yeah.Stephanie:I mean, yeah. It seems like there is the stores that are okay with letting you try everything. And I know COVID mixed that up a bit and made it harder to do that, but I wonder if it will lean heavier into that because they think that's such a great way to sell. But it seems like some brands are kind of stingier, like I don't want to give this away for free. And it'd be interesting to have a case study of like well, when you get a sample, here's the ROI and the LTV just based off that one, little, teeny sample that you did give away consistently. Not just once a week when you send someone in to be an ambassador.Julian:Yeah. No, I think that's really exciting. I do love the idea that I think the US is incredible at creating these ideas. [inaudible] has done a great job and really given the consumer a more accessible way to try products. But we have to always ask ourselves the question, what's going to drive the end plus one customer to go to the next multi-brand beauty store? And I don't know about you, but how many times do I get ... I'm buying my groceries online because I don't to go and queue up. I mean, this is the trend and it's accelerating faster and faster.Stephanie:Yeah. Yeah, I agree. The one thing I'm thinking about now too is that it feels like in some ways, the US and Chinese buyers are the same, and in other ways very different. Thinking about the sale aspect where it's like, that's big in China. And actually, it's kind of like going away here. Why are we doing these Black Friday events? There's no point. And that's once difference.Stephanie:And the other one I'm thinking about is all these new D2C companies popping up where you see consumers here kind of falling in love with the brand, which is very different than maybe even five years ago. And maybe you didn't always know who the brand was behind the product. Are the buyers in China similar, or are they not really open to new brands? Or do they not really want to hear about the story? What are the differences there?Julian:I think for example when we started SuperOrdinary, we saw this opportunity to bring clean beauty into China. Which at the time, there was no social listing around clean beauty. If you checked out clean beauty packaging, clean ingredients, there was really nothing there. And that was very important. I think the US, where they're ahead of China in this respect, is the brand story, the mission behind it. What does the brand stand for? What's the why? I think those types of ideas are becoming more and more important in China. We're starting to see brands really care about the environment, the packaging, what they do. The say/do ratio, we call it. Julian:But I think one of the learnings we had, and it's why I think SuperOrdinary, we moved to the US to really build out the Amazon business. Because we saw the opportunity of what we were doing in China and reapplying that to beauty on Amazon. Everyone knows the story that there are rogue sellers on Amazon. There's plenty of opportunity. And over one third of all beauty purchases are now on Amazon. And it's like this dirty, little secret we all know. We're all purchasing our toilet paper, our mineral water on Amazon, so why don't we buy our skincare?Julian:We set up a team. We have a team just under 25 people here in the US focusing on building brands, the story, making sure their D2C websites look exactly like they do on Amazon. And it's just been really exciting, because in five years' time from now, I think if you ask yourself the question, "I want to buy a product today and I want it on my doorstep in 30 minutes, who's the player that's going to be able to do that?" And it's not your own D2C website. It's really the part that can actually have the tentacles everywhere that's going to be able to do that.Stephanie:Yeah. Yeah. That's going to be huge. All right, well with a couple of minutes left let's shift over to the lightning round. Lightning round is brought to you by Salesforce Commerce Cloud. It's where I ask a question, and you have a minute or less to answer.Julian:Oh, wow.Stephanie:Are you ready, Julian?Julian:Let's go.Stephanie:All right. If you had a podcast, what would it be about and who would your first guest be?Julian:I would invite Anthony Bourdain. I just think he's the coolest guy, and I really enjoyed his international aspect on traveling and eating. I love eating.Stephanie:Yeah? He'd be your perfect guy?Julian:Yeah.Stephanie:So, a show all about eating and food, then. I like that.Julian:Yeah, exactly. Definitely nothing to do with ecommerce.Stephanie:Yeah. That's good. Well, when you want to stay on top of new trends that are popping up, how do you stay on top of that? Where do you go? What are you looking at? Yeah, how do you know what's hot?Julian:I'm lucky enough to have three boys, who are 16, 14 and 12.Stephanie:Oh, so they know.Julian:Who keep me on my toes, yeah. I actually ask them, and they find everything on Twitch. I usually ask them, and then they frown at me like, "Dad, what are you doing in makeup?"Stephanie:You can ask makeup stuff on Twitch? Wow. That might be a new-Julian:Yeah, it is. It's true.Stephanie:What do they ask?Julian:Well, they just find out ... They know everything from men's grooming, and they get targeted. And it's so funny, because the young one, he said, "Dad, what's manscaping?" I'm like, "Where did you learn that from?"Stephanie:We'll talk about that later.Julian:I'm learning about new projects and new things all the time.Stephanie:Oh my gosh. That's awesome. That could be a whole, new trend there. Go on Twitch. Ask the people. They'll let you know what all the trends are.Julian:That's right.Stephanie:What was an idea that you thought was brilliant but ended up failing?Julian:Oh, I've got so many of those. I'm trying to think of the one that's the least embarrassing.Stephanie:You have embarrassing?Julian:During COVID, I was like, wow. I was thinking about everyone is staying at home. Everyone is on these Zoom class, why doesn't people create comfortable clothes? Maybe I should start a pajama company. And I quickly had a handbrake on that. So, I didn't do that. But I've also done other things. What else did I do? I invested in a pool cleaning company back in the day, and that was my first, real investment. And I had a very big learning from that because I gave them all the money upfront. And the second day, he never showed up for work. I'm like, "Huh. That was a bad trade."Stephanie:Never saw that dude again? Oh my gosh.Stephanie:All right, what's up next on your reading list?Julian:On my reading list. I guess I'm a creature of habit. I think one of the books I wish I read 20 years ago, it was available, was Ray Dalio's Principles.Stephanie:Yes. So good.Julian:I think he gives you this honest look at yourself. It's very introspective. And tells you how to build teams. I recommend everyone in the world to read that book over and over and over again.Stephanie:Yeah. He's such an interesting person. All his philosophies, and I think yeah, he came and spoke at Google when I was there. And just how he thinks about rating his employees, have you read about this?Julian:Oh yeah, of course.Stephanie:You get a rating.Julian:I know.Stephanie:And if you're this level, you actually just probably shouldn't speak up until you get to this level, but everyone gets access to everything.Julian:I know. The scorecard is like a baseball card. I mean, but it gives you a very different perspective about radical transparency. And also, teaching you how to take constructive criticism in a positive way, knowing that collectively the information in the room will allow you to make better decisions.Stephanie:Yeah. Yeah. Love that book. Well, awesome. Well, Julian, I've loved having you on the show. If people are trying to get into China and they're looking for help, where can people find out more about you and SuperOrdinary?Julian:Yeah. We have a website, SuperOrdinary.co. Not .com. Thank you, whoever took that website away from us. We'll find you. Or, reach me on JulianReis, R-E-I-S, @SuperOrdinary.co. Really, thank you so much, Stephanie. You're wonderful. It's so nice to speak to you.Stephanie:Thanks so much. It's been awesome.

Up Next In Commerce
Don't Flush The Fundamentals

Up Next In Commerce

Play Episode Listen Later Jun 29, 2021 34:19


The best way to learn something is by doing, which is a lesson that Thomas Lotrecchiano's father taught him early on. Thomas and his father started Omigo together in 2018 as an alternate route to Thomas going to school for an MBA, and in the years since, that lesson keeps cropping up. Omigo is a DTC bidet company, and like many industry disruptors, its biggest challenge is educating the consumer base and converting skeptics into loyal customers. On this episode of Up Next in Commerce, Thomas explains how they have done exactly that by blending humor and educational content, building an infrastructure that allows them to ride the changing tides of demand, and by betting big on TV moving forward. Plus, Thomas shares some of the lessons he has learned from his father, who is an ecommerce gamechanger in his own right, having grown a small online business from a modest five employees to 250 in the early days of the industry.. Enjoy this episode! Main Takeaways:How Long Will It Take?: Getting consumers to adopt a new product, especially an intimate one, requires a great deal of education, patience, and listening. Just because your product works flawlessly and it has certain innate benefits doesn't mean that it will immediately be a hit. You have to invest in educating the consumer base and then listening to and incorporating their feedback into your products and messaging.Don't Overlook the Obvious: It's easy to fall in love with your product and spend time and money selling its unique features, but what actually makes people convert is if you can show them how to use it, how to install it, and lastly the value that can be derived from it. Those are the conversion areas that you should be laser-focused on, and highlighting any of the superfluous features can come later.Basic Building Blocks: There are three fundamental elements that DTC businesses need to start with before getting their company off the ground. They are: customer service, fulfillment, and a functioning, lead-generating website that has the ability to scale. Without these building blocks, your company is not ready to scale.For an in-depth look at this episode, check out the full transcript below. Quotes have been edited for clarity and length.---Up Next in Commerce is brought to you by Salesforce Commerce Cloud. Respond quickly to changing customer needs with flexible Ecommerce connected to marketing, sales, and service. Deliver intelligent commerce experiences your customers can trust, across every channel. Together, we're ready for what's next in commerce. Learn more at salesforce.com/commerce---Transcript:Stephanie:Hey, everyone, and welcome back to Up Next in Commerce. This is your host, Stephanie Postles, co-founder and CEO at Mission.org. Today on the show, we have Thomas Lotrecchiano, the co-founder of Omigo. How's it going, Thomas?Thomas:It is great. You nailed the last name. Perfect.Stephanie:Yes. I'm so happy. I was looking at that like, "Oh, can I do this one?" So many tricky names on this show, but I'm like a 50/50 shot at getting them right, so it's all right. So I'd love to hear a bit about Omigo. I saw it's a bidet company, which was very exciting to me, surprisingly, because I've been to Japan before, and I remember entering the airport and going into one of the stalls, and it closed and music started playing. They had this beautiful toilet. I couldn't hear anything. I was in my own little spaceship. And the toilet was obviously a great bidet, and so I'm very excited about the world of bidets, but I want to hear a bit about how you guys even got into this.Thomas:I love hearing about people's first bidet stories, and they're always so different. A lot of people talk about Japan. Some people talk about [inaudible] or having to use their hand, or bum guns in Southeast Asia, or the traditional ones in Italy, and not having any clue how to use them. Bidets, bidets. So it started when my dad rented a new apartment in Raleigh, North Carolina, and they had an electric bidet seat there, and it was just like the ones that we're selling now. Very similar. So it was his first bidet experience, besides the ancient extra fixtures you see in European bathrooms that you might want to wash your feet in.Thomas:And he didn't use it for a month. Wouldn't touch it. My mom loved it immediately. And so, after some time, he warmed up and he sat down, used it. Basically, I like to imagine an epiphany where he sat down and some angelic music played and lights lit up around him and his life was changed forever. He wouldn't stop talking about it. I had been exposed to bidets in Southeast Asia. A little bit different than what we're selling now. But that's how both of us kind of got our start with a bidet, but the company came from when my dad just would not stop talking about these Japanese toilet seats every family gathering, whenever I was with him, I lived in the same city as him, and it just wouldn't wouldn't end.Stephanie:Yeah. Yep. Once you get that experience, I feel like it's hard to go back. I know when I worked at the main campus at Google, they were everywhere, in every bathroom. And to me, that's such a foreign concept, but there's so many different people there, that was just part of the norm. And I would always have friends come and visit me and family come on campus, and after just me being like, "Go try it. Don't be scared. You're going to love it," it's like it was a conversation for the entire week afterwards. So it was very life-changing. I mean, what's interesting, too, about your guys' company is that you co-founded it with your dad. Which I think is a very fun story and I want to hear a bit about that, because I see he has a big background in ecommerce, as well, and had a company that went from 5 to 250 employees, which you were working at as a teenager. So I'd love to hear a bit of the background there and what it's like working with your dad.Thomas:Yeah, absolutely. Super accomplished guy. Really happy to be working with him now. So just kind of how he and I got started, I'll fast forward to. There was a time where I was choosing a career path after I had done two years of service in AmeriCorps, which is a nonprofit, national organization: NCCC. And we had known we'd always wanted to work together. We're very similar people and we get along. We have a lot of the same thought processes. And so, it came a time where this bidet epiphany had happened, and he said, "Hey, I know that you're thinking about going to school for an MBA. Instead of getting an MBA, we're going to start this business together. You're going to learn more. You're going to actually get paid instead of paying. And it's going to start a new career for you." And I was game-Stephanie:Smart dad.Thomas:Right? Very smart dad. I trusted him, I believed what he was saying, and I knew from all of those years' experience, like you mentioned, that I was going to learn a ton. And so, the business that you referred to that he took from five to... I forget how many hundreds of employees, was called Canvas On Demand. And so, it is a digital or physical image-to-canvas art company, and when he started it, you only really found that in Walgreens. And so, he took it to the ecommerce space, which was... In 2005, selling stuff online was weird. It wasn't huge yet. You were still going to the store, picking things up. But I want to reel back just a little bit more. He started Art.com. He purchased the Art.com domain-Stephanie:Domain?Thomas:And started selling... Yeah, selling posters in 2001 with a different company. And that kind of set him on this online trajectory. Then, he launched into this Canvas On Demand company, which yes, I worked at as a teenager every summer, every holiday, I was probably the eighth employee, technically. From the beginning, I've been working with my dad, and I've definitely watched him run his companies and I've admired what he's done from afar and up close for years now, so it's great to work with him.Stephanie:Yeah. Very cool. So what does the separation of roles look like for what your dad does and when he's like, "And this is for you to run on your own"?Thomas:Yeah, so I would say that my dad is the big picture guy. He is really good at thinking outside the box, pushing the brand, and making sure that everything is in the right place, and then my job is running the day-to-day. So running the store, managing all of our agencies and merchants, and working on [inaudible]. And I'm really in the day-to-day of Omigo.Stephanie:Cool. And how challenging has it been to bring this product to the US, sell people on the benefits? How do you even approach that marketing? Because I feel like unless you've really tried it, it's pretty hard to convince someone who's never even thought about it to be sold on a product like that. So how do you think about introducing people to this kind of new product? At least in the US still feels kind of new.Thomas:Yeah, it's shocking. I still have to convince my friends to try it. I run a bidet brand and it's still work to get people that know and trust me to sit down and wash their butts. Washing your butt is such a foreign concept here and it is maddening, because, like you said, once you try it, it's almost impossible to go back. You have to get some sort of bidet in your home. And we knew it was going to be a challenge, but we know that that fact I just stated, once you try it, you'll never go back, and it's such a better way, cleaner way to go to the bathroom, that it's just a matter of time before it catches on in the United States.Stephanie:But it's been a long time. That's my thing. These have been around for [inaudible]. How much more time do we need? What kind of [inaudible] are you going to get yourself out there? What kind of marketing are you going to use? Are you going to pull a Poo-Pourri and really go hard with the unicorn type of stuff? Or how are you guys thinking about educating and selling this idea?Thomas:Yeah. Well, you need multiple people in the space to start disrupting and pushing this kind of taboo idea in people's faces, and what we've done is we took an educational approach. No one knows what Japanese bidet toilet seats are, and so we have this awesome product that does all these great things, makes you feel amazing, super easy to install, and that's the tactic that we went with was letting people know that it's not intimidating. So we use plain language to describe the installation. We let you know exactly how it functions. And then, along the way, we're using a little bit of humor and that expressive "how it makes you feel" experience, and try to get that across in our visual and audio cues.Stephanie:Yeah. And what kind of formats have you seen do best? Where you're like, "Oh, this one video that centered around humor did better than a pure educational one." What are you seeing connect with people, especially in the marketing campaigns that you're running?Thomas:Yeah. So humor has been a big one for us. We have one called "Bidet, Mate," and it's an Australian man and he talks about if you stepped in a lot of dingo dung, you wouldn't wipe it off, you'd wash it. So use a little bit of humor there, but he's also explaining exactly how this great product works, so it breaks down that wall of, "This is gross. I'm not talking about poop. But poop is funny, so let's make jokes about it." And then it says, "Okay, we're here. We're talking about it. Now, look at this awesome thing. Toilet paper is disgusting. You're reaching down and you're wiping yourself, so why don't you wash instead?" And so, [crosstalk] a good one. And an accent.Stephanie:Any accents you can get into marketing I feel like will probably have a good ROI. I don't know. Don't measure me on that, but it seems like it would. All right, so you're using humor. I sometimes feel like humor can go both ways though. You've got one side that can work really well, like I was saying, like Poo-Pourri and then the Harmon Brothers do a bunch of ad campaigns all around humor and a lot of them have done really well. But then, it also seems like it can be like a short blip of people are excited about the Squatty Potty, and then it's like, "Is anyone still using that thing? What happened to it?" So how are you approaching that balance between funny but then also, "This is something that you're going to keep for a long time"?Thomas:Yeah. So humor's a great attention-grabber. So I make you laugh. It's a little bit funny. You're interested in the product, and then we also have educational, but kind of... So I'll say I am in a video with my dad on YouTube and it is called, "Our Founder Spot and Why We Founded Omigo," and it tells you basically this story, and then, it lets us explain the product without being funny. And we think it's approachable and educational and real, coming from real people, not actors, and that seems to do extremely well combined with that humor. So I agree. It could definitely be flash in the pan and we've done funny stuff that hasn't worked, but on that front end, getting people's attention, humor does seem to work really well for bidets, specifically.Stephanie:Yeah, and I think that authenticity is definitely key, especially around a product that people don't really understand. And yeah, I'm even thinking, how do you guys lean into maybe user-generated content? Which to me, if you see someone using it that is like you, you're like instantly, "I'll probably give it a try, because you're like me and if you like it, I probably would, too." But for something like this, are your customers even willing to talk about it and get the word out there and help spread the message?Thomas:Yeah, so we have seen a steady increase in our post-purchase survey for friends and family, word of mouth. And that's exactly where it comes from: people that you trust talking about such an intimate topic. So UGC isn't always something that I'm going to be showing on my website, because it's true, I'm not going to be able to get the everyday consumer to send me a video while they're on their bidet, talking about how awesome it is. But when we do use that approach, it's been in the influencer space. A lot of people look at influencers as people they trust, guides in their lives, people they aspire to live like. Whether you agree or disagree with how people portray themselves on Instagram or social media, it's still a place for aspirational content and to look at people and see what they're doing. And we've seen some very good traction there, utilizing that influencer content elsewhere on our marketing channels.Stephanie:Mm-hmm (affirmative). What platforms are you working with alongside these influencers?Thomas:Yeah, so they post on Instagram and then we use whitelisting on Facebook and Instagram.Stephanie:Got it. Okay. And then, what are the results for that when it comes to conversions, and what does that funnel look like versus maybe just a typical ad out in the world or on YouTube, maybe running it against your video with your dad, like a very authentic company story. How do those two perform side-by-side?Thomas:Yeah. So we typically don't run those side-by-side or A/B test them. We kind of keep them separate. The best thing about whitelisting... Are you familiar with the concept?Stephanie:Yeah. Go into the detail, because I'm not...Thomas:Yeah, sure. So whitelisting content is working with an influencer where you get them to create some awesome content around your brand. You guide them and let them do their own thing, but then you technically have access to their account, and from there-Stephanie:Oh, got it. Yeah.Thomas:Yeah, you can use their audience and create a lookalike from it on Facebook and Instagram, and then re-target them with that content from the actual influencer. So that's where a lot of the power comes from is building those audiences on Facebook and showing them these people that look and think and talk like them, and then getting them to look at this product and say, "Oh, I've never heard of it. These people are using it. Hmm." It's kind of like that "this is everywhere" approach. You're going to get hit with a funny ad, you'll see my dad and I, and then you'll see an influencer with it. So breaking down those walls and making it normal is a big thing in the customer acquisition.Stephanie:Yep. Yeah. Completely agree. So how do you even garner... I'm thinking about like, you have this product, and do customers give you feedback and do you let that influence the product? Or are you more kind of like tunnel vision? "We know it's good. We've been to Japan. We know what it needs to be like." How do you think about that product development cycle?Thomas:Yeah. The product is what the product is right now. We know that we have a great bidet seat, and we know that we have great bidet attachments, and we have faith in these products to perform extremely well. They're super high quality. A lot of people love them. When you're working with a product that 98% of Americans don't have in their homes, you're going to get a lot of feedback about that product in particular. We are always listening, though. It's not to say we turn a deaf ear to what people are coming back and mentioning about the product, because there are things you can change down the road. So it takes a long time to develop. Years and years. So being able to hear what people are saying, seeing patterns in their responses, will definitely be guiding our product development. But for me, listening to our customers at the beginning was more about why they decided to try the product, what they like about it, and what they were skeptical about, and then taking that feedback and putting it back into our messaging. So that was super important to me.Stephanie:Yeah. That's a really good way to view feedback, from all angles. What are some of the most surprising pieces of feedback, either before the sale or after, that you've received where you're like, "Oh, that's very interesting"? Where you actually maybe implemented it into your copy, your language, the way you educate people? What was something surprising, or more than one thing, that actually helped influence how you talked about it or sold it?Thomas:Yeah, so one thing that we hear a lot, and I love to hear it, is: "Why didn't I do this sooner?" And it's that sentiment where it's like, "Ugh, I've been living my entire life wiping with dry paper, and these bidets have been around. What was I doing before?" And so, we take that sentiment into our marketing now. And then, on the pre-purchase side, it really came down to listening the frustration points of what we weren't showing and telling people on our website.Thomas:So there are little complications with your seat size and shape and your plumbing fixtures, and it's a complicated world down there by the toilet. And I was looking at it from a world of head down in bidets and toilets, and I knew too much about toilets than I ever needed to, and to be able to hear a customer pick your head up and say, "Oh, well, I obviously need to show this information. Why wasn't I doing that before? It doesn't matter. Put it on there now." That always has been a winning tactic for us.Stephanie:Yeah. I mean, it also seems like a good way, even around customer acquisition, building a piece of content of just, "How do I even hook this thing up?" I mean, even if they've bought it from a different brand or they're even considering it, I mean, that'd be my first question is, "Can I even do this myself? Do I need someone to come and install it for me? And what kind of things should I think about before buying something brand-new?" So it seems like a good content angle, too, to attract customers that maybe you wouldn't have otherwise.Thomas:Yeah. We put installation in a lot of our videos, and it's simple language, it's DIY, self-install, no special tools, no plumber required. Right? And that's kind of all you need to know. "Oh. I can handle it," is basically the message.Stephanie:Yep. Yeah. That's great. So earlier, you mentioned working with agencies was a piece of your world, and that's a topic that... We've had many founders on here where some are excited about it, some are like, "It didn't go well." How do you view working with agencies? What things did you choose to maybe hire out? What did you keep in-house? And how do you keep a good working relationship there?Thomas:Yeah, so the agency battle is: it seems incessant, until you find an amazing partner. And we've really settled into a couple of great partnerships, and those are the ones that we work harder at because we like the people internally and the work that they do. We get along with them. We have similar values when it comes to business, and so we put in extra time and effort say, "Hey, we don't really like this right now. We would like to change it this way," or, "We would like to see more of this." And the ones that take your feedback and change are the ones that you're going to stay with, and those are the people that we continue to work with.Thomas:So it's not easy finding a good agency, and we've had agency turnover multiple times with Omigo so far, but settling into a great relationship is extremely fruitful; and it's still going to be work, but that's the approach that we've taken. And to answer what we have kept in-house versus kind of farmed out, we keep customer service and product development in-house. Super important to keep that close to home, understand that feedback loop of what are people saying, how can we answer their questions more efficiently, and making sure that when it comes to a plumbing product, they have a great experience talking to someone and getting their questions answered. So keeping that close to home is super important.Stephanie:Yeah, it definitely seems like a high-touch customer service experience that, once you get past that point, it can be an instant sale as long as you have a good lead in and know everything and their questions are all answered from the start much easier, and you have to kind of keep that in-house. I can see why. So getting back to you working with your dad, and he's done a bunch of cool things before, what are some of the lessons and insights he brought into the company that you're like, "Wow, that really helped get it off the ground," or, "These insights here or his experience here really helped kind of get it going"? What kind of things did he bring to this company today that helped you guys lead it to where it is?Thomas:Yeah, so after he sold and exited Canvas On Demand, he started to consult with other ecommerce brands. So he is the friendliest person I know probably, and loves being around people, talking with them, listening to them, helping them, so it was a natural fit for him to take this... How many years was it? Seven or eight years at Canvas On Demand, where ecommerce was changing. It was in such a growth stage. Everything was different year after year, and so he had to adapt constantly. And I think that really shaped his way of thinking about ecommerce and allowed him to go past this legacy concept of ecommerce, that you might get stuck if you started in 2001, and really grow with that channel.Thomas:So he took that into his consulting career, and so, for the six years in between his sale and Omigo, he was consulting with ecommerce brands of all sizes: $5 million a year to $120-150 million a year and everywhere in between. So what we took from his experience into Omigo was what he calls his "ecommerce playbook," and it was the fundamentals of where you need to start with a direct-to-consumer business. And the basics of that were: great customer service, like I mentioned, solid fulfillment,Thomas:And the fundamentals of a website, so that being: something simple and functional, having a great hero and landing page, having solid email capture, having all of your email flows built and all of your knowledge base in place and everything ready to scale, because something could happen overnight like it did with Omigo, and you have to be ready to go from 10 orders a day to 150. So he brought this ecommerce playbook and this really rich knowledge base and a lot of connections to the start of Omigo.Stephanie:Nice. And so, how many orders are you guys at today? You just talked about going from like 10 a day to a hundred. What does it look like today, and what did that process look like scaling to where you are now?Thomas:Yeah, it fluctuates. So it's been a funny year-and-a-half for Omigo, because at the beginning of the pandemic, the toilet paper shortage hit.Stephanie:Oh, yeah. I forgot about that.Thomas:Right? Forgot about that.Stephanie:Yeah.Thomas:What a crazy time.Stephanie:I like to forget about dumb things like that. We didn't actually have a toilet paper shortage, we just had a logistics problem. But okay. Carry on.Thomas:We had a hoarding problem and a logistics problem. Either way, it was great for the bidet industry. It was an odd time to prosper, when you had a lot of people going through hardships and a lot of unknown in the future, but we couldn't look at that in the moment because people needed a solution to the toilet paper shortage. And bidets are the best answer, so, "Hello. We're Omigo. We've been here. Welcome." And during that time, it was Black Friday every day for a week. And then, that lasted about a month and a half. We sold out. Sales tapered back down in the summer, picked back up during holiday paper shortage, and then kind of continued into the new year. And we're seeing kind of a mini decline right now, and a steadying out of how many purchases we get. So still trying to figure it out. We haven't cracked the code 100% and we're working at it constantly, but definitely going with the flow as far as when orders are coming in and when they're not.Stephanie:So what are some lessons or things that you're adjusting going forward now that you've kind of seen these fluctuations of demand and Black Friday every day for a week, and then tapering down again? What kind of things are you maybe adjusting going forward to kind of future-proof the back end as well to make sure that you can keep up with it when it's there and then still have your suppliers and manufacturers when it's not Black Friday levels? How are you guys thinking about that now?Thomas:Yeah. Well, after we sold out, we realized this could happen again, especially during the pandemic. It was super unsure times. So we really shored up our supply chain. We ordered a lot of product, and we have a lot of product, and we are continually ordering it. Because we know it's a matter of time until bidets are ubiquitous. I mean, I am confident in that. It may take five more years. It may take 20 more years, but there's going to be one day where bidets are everywhere. And our products, they're shelf stable. It's not like they're going to be going bad, so having that on hand, being ready for a boom, is one way that we're future-proofing ourselves.Thomas:And another way is just keeping everything tight on our website. We are constantly A/B testing and trying out new copy or new design to optimize how customers are coming in, learning about our product, and finally purchasing. So keeping everything tight on the website keeps us future-proof. And being direct to consumer, we have a great relationship with our distribution centers, so always knowing that we're going to have a distribution relationship where, "Hey, yeah, we're at X amount of orders today, but that could double in the next three weeks and we need to make sure that you're ready." So having the infrastructure there, as well.Stephanie:So where are you most excited to take Omigo over the next maybe three to five years? What are you guys working towards? What are you most excited about right now?Thomas:Yeah, I'm really excited about television.Stephanie:Yeah?Thomas:I think that it's funny, because you think TV five years ago, you're like, "Oh, TV is dying. It's all going to be streaming." And yeah, it is a lot of streaming, but it's still a traditional marketing platform. There are still ads on every streaming platform and cable is still a booming industry. It is a gigantic industry. A lot of people have cable, Dish, and the like, and I think that for a young direct-to-consumer brand, getting in front of that many eyeballs is really exciting for us. So it's not a new channel; it's just new to us.Thomas:We are going to be launching soon. Yeah, we're going to be launching soon and are excited about the results. We have some people that we know that are doing well on TV and we think that we're going to do well, also.Stephanie:Cool. And is it specifically focusing on cable? Which I do feel like a lot of people are kind of sleeping on that, but I also wonder if maybe it's a generational thing, where it depends on who your target audience is that you're trying to get in front of; where maybe people closer to our age, they might not have cable. They're probably Netflix, Hulu, everywhere else, YouTube. But then, when I about maybe my parents, for sure they still have cable, and they're probably not going to get rid of it for a long time. So which areas... Or are you exploring all of that?Thomas:Yeah, we'll definitely explore all of it. Streaming is great. We have those low-price bidet attachments at Omigo that start at $89. So great entry-level, great price for anyone that wants a bidet. And then, our top-of-the-line bidet is at $649, and we do see the demographic there swing older. And that's a demographic that is humongous in this country. A lot of them are still watching cable, like you said, so they don't know about these luxury bidet toilet seats. And if they see it on TV, I think that kind of awareness is just going to do good things for every bidet company out there.Stephanie:Cool. Yeah, we'll have to circle back once you guys are live and [crosstalk] see you out there in the world on one of the channels.Thomas:You will.Stephanie:That'd be fun to hear the results and how it's going.Thomas:Yeah, so excited.Stephanie:All right. Well, let's shift over to the lightning round. Lightning round is brought to you by Salesforce Commerce Cloud. This is where I ask a question and you have a minute or less to answer. Are you ready, Thomas?Thomas:Yes.Stephanie:Cool. What ecommerce tool or piece of technology are you most excited about right now that you guys are maybe experimenting with?Thomas:So we've been on SMS for awhile, but SMS has just been a great platform for us. Being able to get into people's pockets and the open rate and click-through rate has been awesome. So SMS is a killer. It's not going anywhere and we're super excited about it.Stephanie:Awesome. What's up next on your reading list or your podcast queue?Thomas:Let's see. Guiltily been learning more about crypto lately on my podcast queue, so trying to educate myself on not just kind of what's booming and busting, but the inner workings and how to actually invest longterm into that world. So definitely a little bit of crypto podcasts in there.Stephanie:Nice. Yeah. There's some good ones out there. Personal favorites.Thomas:I'll have to ask. Yeah.Stephanie:I'll just send some episodes your way that are good ones. When you want to get creative, what do you do to get into that headspace?Thomas:I turn off everything around me, because I'm a very distractible person, and I really put myself into the place of who this creative project is for. Put on a little different hat for email, put on a different hat for Facebook, and if I'm stuck, I leave. Wherever I am. I go outside and move my body. I'm a very active person, so being able to get some blood flow gets my creative juices going, too.Stephanie:Yep. Yeah, same. Cool. All right. And the last one, what one thing will have the biggest impact on ecommerce in the next year?Thomas:The next year: the continued at-home life. People are not going to go back to the office full-time. A lot of people are going to keep spending time at home. People are buying houses. So this at-home goods and everything that you can use around the house is going to be huge, because people are still shopping online. People are still getting everything shipped to their door. We're not going to go back to retail yet. I think that's going to be in the next year. A big one.Stephanie:Cool. All right, Thomas, thanks so much for coming on the show and talking about bidets and the fun world. Where can people find out more about you and Omigo?Thomas:Yep, so if you want to find out about me, you can find me on LinkedIn: Thomas Lotrecchiano. And if you want to find out about Omigo, you can go to Myomigo.com. That's M-Y-O-M-I-G-O dot com. We have all of your butt washing needs. Stop wiping, people. Wash your butt.Stephanie:Do it the right way. Come on. All right. Thanks so much, Thomas.Thomas:Thank you, Stephanie. It's been a lot of fun.

Terreur sur le Pod
TSLP Ép. 38. Le Beau-Père (The Stepfather) 1987

Terreur sur le Pod

Play Episode Listen Later Jun 19, 2021 100:08


Cette semaine, nous te présentons un film dont les origines remontent aux années 70 et qui est inspiré d'une histoire réelle. The Stepfather raconte l'histoire d'un homme s'incrustant dans une nouvelle famille après avoir éliminé les membres de sa précédente famille. Terry O'Quinn (Lost) est impressionnant dans le rôle du beau-père Jerry. Il joue très bien cet homme malade, qui évacue son stress en sifflant et qui finit par se perdre dans ses multiples identités. Merci à notre invitées spéciale Héloïse avec laquelle nous avons eu beaucoup de plaisir. Nous avons bien apprécié son image de psychologue burrito. Au menu Une maman atteinte de la "cécité de l'amour", un beau-père se défoulant dans son sous-sol tel un Martin Matte essayant d'installer une tablette, un beau-frère aux beaux yeux et "mort à l'arrivée", une gifle livrée avec force... et violence et un "coup de téléphone" brutal. Ayoye mon nez! Bonne écoute!  Tu peux nous écouter sur la plupart des plateformes de baladodiffusions et sur YouTube https://bit.ly/30HxCIE Aussi, tu peux échanger avec nous sur: https://www.instagram.com/terreursurlepodpodcast/ https://www.facebook.com/Terreur-sur-le-Pod-111446400732063 https://www.instagram.com/lafreniere.serge/ @surlepod sur Twitter The Stepfather Creds RC:  Aries Beats - Synthwave Dreams 2020 - 80s Retro Pop [No Copyright Sound] [ FREE USE MUSIC ] License: https://creativecommons.org/licenses/... Download: https://soundcloud.com/aries4rce/synt... Il a dit qu'il était un bon garçon, mais il a menti (Il a compté des grosses menteries) Au début, il retire ses caleçons pis dans l'miroir on voit son zizi (Zizi zizi tout petit kiki) Peut-être que Jerry a bien eu Susan, mais il n'a pas dupé Stephanie (Oh non Stéphanie n'est pas conne) Et pour connaitre le dénouement du film, TSLP ou FrissTV Casa Bossa Nova by Kevin MacLeod https://incompetech.com/ Promoted by MrSnooze https://youtu.be/ioi_-5sAuXQ Creative Commons — CC BY 3.0 I https://goo.gl/Yibru5 Karl Casey @ White Bat Audio

Online Coaching
015: Why and how content is the key to a coach's success – Interview with Jeanet Bathoorn

Online Coaching

Play Episode Listen Later Jan 27, 2021 40:14


This week's guest, Jeanet Bathoorn, is a bestselling author of 6 books, international speaker and trainer and a no-nonsense business coach. She is a certified NLP Master Coach and a Certified Sacred Money Archetype Coach.She started the Freedom Entrepreneur Movement a couple of years ago after having dealt with a total lack of freedom in her business and private. In 2020 she started her own podcast show in which she recorded 100 episodes in 100 days.She is a multiple six-figure entrepreneur since 2005 and has coached thousands of entrepreneurs finding their own unique path to freedom. She also runs several mastermind groups.We talked about…>> Changing plans from freedom entrepreneur running cruises to focus on the dutch market again>> Launching a podcast with 100 episodes in 100 days>> The importance of having fun with your content>> Writing your first book shifting to author>> Keeping things simple to avoid confusing your clientsEpisode Links and Mentions:English Website: http://jeanetbathoorn.com/Assessment: https://jeanetbathoorn.com/money-archetype-assessment/Ebook: https://jeanetbathoorn.com/ebook-7-steps-to-become-a-freedom-entrepreneur/LinkedIn Link: Jeanet: https://www.linkedin.com/in/jeanetbathoorn/LinkedIn Link: Stephanie: https://www.linkedin.com/in/stephaniefiteni/Did you Enjoy this Episode?Subscribe to this Podcast Here Prefer to Read? Here's the Transcript:Stephanie:Hello, Jeanet, how are you? Hi, Stephanie. I'm fine. Thanks for having me. Thank you very much for joining us today. I'm really happy to have you on, would you like to start by introducing yourself and letting us know what you do? And we do it for? Okay. So my name is Janet - I work for the Dutch market, so all my content, everything is in Dutch. I call myself the freedom entrepreneur and I guide/mentor self-employed entrepreneurs to break through their own limiting beliefs, like the beliefs that they created in themselves. And I do that by running mastermind groups. And by putting out a lot of content, I know we're going to talk about content, but I put out a lot of content. Yeah, excellent. Yes, we're in the right place to talk about content. So, what does that content look like?Jeanet:So I am, I'm in the habit of writing books. I love to write books. And in fact, this year I will publish two books. My first book is about running a mastermind group. So what do you need to run a mastermind group? And what does it take to run a group? And the next book I wrote that my publisher asked me to write it. That will be published in November. And it's about online business models because of the whole COVID-19 situation.Stephanie:Oh, wow. Yes, definitely the right topic and especially the right topic for you. . Excellent. So that would be book number 10 in all, because you've already written eight books, right?Jeanet:Yeah. That's that if it's like books that I wrote his book number eight, but I wrote also like chapters for other books, so that, that would bring it to like books and co-writing books.Stephanie:Wow. was it all in dutch? For the Dutch...