Rocky Mountain Ruby 2014

Unpacking Technical Decisions

Unpacking Technical Decisions

by Sarah Mei

In the video "Unpacking Technical Decisions," Sarah Mei discusses the complexities involved in making technical decisions within software development, emphasizing that these choices often intertwine with both code and people dynamics. This talk aims to provide a structured approach to tackle high-stakes technical decision-making, which is critical for teams navigating a landscape filled with an abundance of technologies and frameworks.

Key points discussed include:

- The Intersection of People and Code: Mei highlights the notion that programming itself is straightforward, but being a programmer involves navigating complex interpersonal dynamics. This duality identifies the importance of understanding both technical and human factors in software development.

- Framework Selection Challenges: Developers often face the pressing question of which JavaScript framework to use. The proliferation of options such as Ember, Angular, and Backbone makes this decision daunting, as it can have long-term implications on a project.

- Decision-Making Process: Mei suggests that technical decisions often stem from a combination of social factors, personal experiences, and established practices. To illustrate this, she describes the varied backgrounds of attendees at the Fluent Conference, all seeking to answer the same question: which JavaScript framework is best?

- Evaluative Techniques: The speaker presents a four-quadrant system to aid in decision-making, which includes:

- Interface: The code's usability and functionality.

- Activity: The level of engagement and updates from the project maintainers.

- Popularity: The community's acceptance and usage of the technology.

- Accessibility: How well the project aligns with developers' backgrounds and coding styles.
- Educational Insights: Mei emphasizes the role of learning through repetition and how deep insights can be derived from community practices. By analyzing the steps developers typically take when evaluating frameworks, one can refine their decision-making capabilities.

Concluding her talk, Mei encourages attendees to recognize that technical decisions require a thoughtful approach combining all gathered data and social context. While choices regarding technology may be infrequent, understanding frameworks and making informed decisions based on accessibility and popularity can significantly enhance project outcomes.

00:00:26.880 I'm one of the many Sarahs involved in this year's conference. I was actually here at the very first incarnation of this event back in 2010, when it was still called Mountain Ruby, without the 'Rocky.' No matter what it's called, I'm really happy to be back. It's always a good time, and I always love coming back to the extremely bright stage lights. It's very exciting! Even with all the presentations I do, I don't actually get to be on stage very often, so that's pretty cool. I know you're all feeling pretty relaxed, but that's the end of that right now. We're done with relaxation; it's time for code.
00:01:05.680 This is a technical talk, and there is some code in it—more on that later. There are also some people in it. For the last couple of years, I've been really interested in the intersection between people and code. It's funny to me that we think of these as separate subjects. For example, a conference always has hard talks about code and soft talks about people. The naming is ironic because soft talks deal with the hardest topics we face in software development. I loved how James Edward Gray the Second put it in his talk at GoGaRuCo in 2013: he said, 'Programming is easy; it's being a programmer that's hard.' He didn't mean that it's easy to learn how to program; there's a lot of syntactical and logical thinking and understanding needed. But once you figure out how to tell the computer what to do, you realize you must also figure out how to tell the people what to do.
00:01:39.119 For me, and for many of us, I suspect, figuring out the people is much harder than figuring out the computers. Now, if you're one of those lucky folks who understand people very well and are just trying to grasp the computer side of things, then you're starting out with a huge advantage—don't let anyone tell you otherwise, because that's the hard part of software. A lot of conflict arises, in my opinion, between the 'hard' and 'soft' topics due to the idea that code and the people who write it are two completely separate subjects that can be analyzed independently, but they cannot be.
00:02:44.959 This talk deals with one of the most explicit overlaps of the concepts of people and code, which is technical decision making. How do we make decisions about code? This talk is based on an experience I had earlier this year at the Fluent Conference in San Francisco. Fluent is O'Reilly's big front-end conference, covering HTML, CSS, JavaScript, and more. It's a pretty big event, with about three to four thousand people over three days and four tracks running simultaneously. This is an official picture from the Fluent Conference this year. As JavaScript conferences go, it's fairly conservative, as you might expect. You can tell it's an O'Reilly conference because they sprung for the fancy name tags, which is what you get for your $2500 ticket.
00:03:30.000 However, it's a fascinating conference, and it's really interesting to talk to the people there because it feels like a more realistic cross-section of individuals who use JavaScript compared to most smaller conferences that I attend. The smaller ones often attract the fanatics, while many attendees at Fluent work at large organizations, and this is their one conference for the year. While I was there, I spent a lot of time talking to people in the hallways, asking them why they were attending. As you might expect, I found that the attendees typically fell into three categories. These are the only bullet points in my slides, by the way—sorry, I couldn't find a way to get rid of them.
00:04:18.959 The first group consisted of back-end developers who came from a variety of languages such as PHP, Ruby, Python, and Java. They were there to learn more about front-end development. The second group was made up of visual and UX designers looking to learn front-end development from the other side. Lastly, the largest group, not surprisingly, was front-end developers who were there to learn about the newest technologies and take that knowledge back to their companies. Despite having very different past experiences and skill sets, what surprised me was that when I asked them specifically why they were there, they all answered essentially the same thing.
00:05:24.240 I wrote down some quotes to see if any sound familiar. One person said, 'My group has started an Ember project, so I'm going to every Ember JS talk on the schedule,' which for a multi-track event like Fluent was actually possible. Another stated, 'My web app has an old jQuery code base that I need to figure out what to do with because jQuery clearly isn't the cool kid anymore. I want to learn about Angular; I think I can raise my rates,' which is probably true. Lastly, someone said, 'We have an ancient Backbone.js setup that desperately needs a rewrite, but we're not sure what to do.' And I'm pretty sure by 'ancient,' they meant about six months old. Regardless, despite the different backgrounds, all these developers were there to answer the same question: 'What JavaScript framework should I be using?'
00:06:01.440 This question is one of the most significant open questions in web development today. And it's open, not just because of Ember, but due to the sheer number of options available. This is a great problem for us to have, but unfortunately, it can also be very challenging to determine the right answer for a particular project. You might argue that there are some frontrunners right now, but it's still very early in the game. In fact, since I made this slide about six months ago, several frameworks have dropped off the radar while new ones keep emerging. The landscape changes very rapidly.
00:06:37.360 Each technical community—from Ruby developers to back-end and front-end developers, to PHP programmers—faces some question like this that they're working through. For instance, another question in the Ruby community is, 'What data store should I be using?' Here we have a similar issue with lots of different data stores to choose from, often with unclear value propositions for each option. When you have a specific project in mind, it can be tough to decide which is the right data store. The internet is full of resources on this topic, but asking it about which JavaScript framework or data store to use can be like pulling up to a parking spot and wondering, 'Okay, it's noon on a Tuesday—can I park here?'
00:07:15.999 Because you often get a lot of seemingly contradictory and confusing information. This was evident at the Fluent Conference. One talk in one room would discuss how amazing Ember is, while next door, another session would argue that Angular is the way to go, and then in the next slot, there would be someone arguing that React is going to save us all. Your job is to synthesize all that information into a decision—no pressure, right? But this is quite important because the cost of being wrong in such decisions can be very high. It’s not just about whether you’re parking legally or might be chased off by a meter maid; if you select a JavaScript framework that doesn't suit your project, it depends on how far down that path you go before realizing you need to turn around.
00:08:34.960 How long is that going to take? These decisions are big and scary, and we don't often make them. So, when we do, it quickly becomes overwhelming. It would be great if we could find some way to get better at making these technical decisions. One obvious way to become better at something is through repetition. There's a very persistent meme in our programming culture stating that it takes 10,000 hours to develop truly good skills at something like playing a musical instrument or programming. While there are many good explanations online indicating that this is not really true, the meme persists because it does have a kernel of truth: repetition is one of the most powerful ways for our brains to learn.
00:09:39.280 The key factor, however, isn't just time spent but how you spend that time. You can spend 10,000 hours on something, but if you're not doing it the right way, those hours are wasted. To genuinely learn through repetition, you must perform the action, analyze the outcome, and then repeat the action, slightly changing something to see if it alters the outcome. Even after you believe you’ve perfected a skill, you must keep experimenting and trying new approaches because that's where real learning occurs. It would be fantastic if we could repeat high-stakes, large decisions often enough to improve our skills in making them, but it's unsatisfying to think, 'Okay, I’ll just wait 15 years and then be better at it.'
00:10:56.800 If that's our only avenue for learning, then we are essentially stuck. However, there are ways you can apply learning theory to circumvent this limitation on time. You can draw insights from other types of decision making and adapt them to this context. As a side note, I did a version of this talk in London a couple of months ago, and when I got to this slide, I noticed that nobody in the audience understood what 'an end run' meant or even which sport it referenced. I thought about explaining it, but I decided to move on instead.
00:11:43.440 The type of decision making I’m referring to is the fact that decisions occur at many different levels and frequencies. Language and framework choices are likely the most infrequent decisions we make, but we also frequently decide whether to use random code we find on GitHub or create our own solution. Additionally, we often make everyday decisions, like how to name a variable or where a specific test should go. Even at this smallest and most frequent level, the processes we employ to make these decisions remain rather opaque. If you ask a programmer why they named a variable in a certain way or why they placed a function where they did, many times they can only respond with something like, 'Well, it just seemed like the right place for it, don't you think?'
00:12:37.760 Sometimes, you might hear answers like 'experience,' 'intuition,' or 'gut feeling.' We often use these terms because we can't quite pinpoint what led us to make a certain decision. For instance, when I ask a programmer why they prefer Ember over Angular, the response is often something like, 'It just feels more natural.' Interestingly, the Angular supporters often say similar things when asked that question. I wanted to investigate what contributes to that 'natural' feeling—what factors influence our feelings about ease? What data do we gather when we make these judgments, and how do we analyze it? Gaining insights into these questions is crucial since these are the high-risk decisions we seldom face and cannot repeat as often as we would like.
00:13:47.200 To start, I asked a number of my colleagues to introspect and reflect on their decision-making process when considering using a gem. What do they do, and what do they think about? Interestingly, everyone starts in the same place: they begin by reviewing the README file. I noticed that the README is an age-old guide, almost like a meme. When people come to a README, they seek out bullet points that outline features, functionality, usage, and installation details. Essentially, they're searching for information about the gem's interface: what it does and how to use it.
00:14:43.040 To make this more concrete, let's examine the evaluation of two gems that perform very similar tasks. For example, if you're trying to choose a gem to make HTTP requests, you want to send a request to another server or an API over which you have no control and retrieve some data. Essentially, you want to use the TCP/IP tubes. If you're working in Ruby, there are two basic options: you'll likely come across HTTPParty, which I'm sure I'm mispronouncing, and Faraday.
00:15:01.519 Assuming you don’t choose Faraday just because you don’t want to pronounce the first option incorrectly—though I can't say I haven't done that—the first thing you likely do is look at the README for each project, typically proceeding to the usage sections. Here's what you'll find. You don’t even need to read all the code on this slide; I'll point out the interesting parts. HTTPParty has static methods that can be called directly or you can include it into your object to gain HTTP call methods within that object. That's reasonable. Faraday, however, takes a distinctly different approach by giving you a connection object that you're required to use for making calls.
00:15:49.760 Both interfaces will work and accomplish the same things, but how do you pick between them? This is not enough on its own; just having a bullet list of features in a framework's README is insufficient to make a decision about which framework to use. So what else do we consider? Here’s a somewhat exhaustive list I compiled while interviewing a group of individuals. I also said there are no more bullet points, but these don’t really count anyway—as a side note.
00:16:55.520 The approach people typically take includes reviewing the README on GitHub, examining the number of commits and their recency to determine project activity; looking at the reported issues, their resolving timelines, and their comments to assess maintainer involvement. They also consider the number and timeliness of tutorials and blog posts, popularity relative to other gems on platforms like Ruby Toolbox, the frequency of releases, and how many Stack Overflow questions exist, along with answered ones. Ultimately, they ask various people: potentially useful contacts, possibly even those deemed useless. Additionally, they explore documentation, books, and screencasts, and sometimes they even sift through the code or the tests. Sometimes, they might even just shove it into the gem file and see what happens. They might build a small sample app to test how it works. It’s a long list.
00:18:07.760 As a note, this isn’t completely exhaustive, as there were several other items that people mentioned that I opted not to include. But I want to point out a couple of interesting features of this list. First, different individuals rank these factors differently. For instance, I frequently check GitHub to verify that a gem offers a reasonable interface, and the next thing I typically do is ask my coworkers if they have utilized the gem. Yet, one person I spoke with used to work at a company where displaying any ignorance was frowned upon politically. As a result, he would examine the README first and then immediately start looking at the documentation next.
00:19:10.919 So, while different people approach these evaluations differently depending on their backgrounds and current workplace cultures, it’s evident that nobody utilizes all these techniques for any given evaluation. This is merely a union of various strategies people adopt. Generally, however, the riskier a decision is, the more of these strategies people tend to employ. Additionally, the methods that are used may evolve as the community that generates them changes. For example, prior to Rails' emergence, a lot of discussions about Ruby libraries occurred on the official Ruby mailing list, but nowadays, there aren’t any mailing lists in this context, whereas the Python community still relies heavily on mailing lists.
00:20:16.799 The point being that the methods we use to collect and apply this data—even if it is a swift evaluation—are quite intricate. Furthermore, if you examine this list, you'll notice that most of it pertains not to the code itself, but to social data; it's about the maintainers and users associated with a project. I want to categorize this information to provide clearer insights. There's certainly some technical data involved—the code details we all start with, what we’ll call the 'interface'—which is crucial.
00:21:22.800 Next, we can describe the project activity—how frequently it’s updated, the likelihood of getting help from maintainers, the chances of bug fix adoptions, and similar issues—as another layer. This can be quantified and mechanized. Ultimately, that leaves us with some of the more obscure areas; how popular a gem is among developers, how easy it is to find support when issues arise, and whether you can hire someone who’s already used the gem. In the end, we can gather up a few outliers, such as actually reviewing the code or tests, which don’t easily fit into the categories we've defined thus far.
00:22:43.200 So we have our categories: interface, activity, and popularity—these are straightforward, standard sources of data, all of which can be methodically gathered. But what remains to be defined? Some fuzzier concepts surround how familiar you find the code when using it—how much does this code align with your own coding style? How much does the maintainer share your testing methodology? Let’s categorize this as the 'accessibility' of the gem. Therefore, we now have our four categories of data to consider when making small scale decisions.
00:23:45.440 Once I reached this point in my analysis, I started thinking about how to further group these categories interestingly. So, we can draw a dividing line here. The two categories on top—accessibility and interface—relate to you. The interface indicates whether the code works as you’ll need it for your project. In contrast, accessibility assesses whether your team is comfortable with the metaphors and language employed in the project’s code. In the lower half, we find two categories concerning outside perspectives: popularity and activity, which measure external factors, such as community support and continued updates.
00:24:36.320 Additionally, if we draw another line, we can observe similar connections. Accessibility and popularity both relate to the people surrounding a project; accessibility concerns whether your team can effectively utilize the project, while popularity measures how many other developers are using it. On the other side, interface and activity provide insights regarding the project itself, which is evident when assessing the code. The interface, as stated, relates to whether the framework satisfies your requirements; activity is inherently linked to the likelihood of bug fixes or improvements during the project's lifecycle, ensuring reliability.
00:25:38.720 And there we have it: my four-quadrant system for making technical decisions. I was sharing this talk with a friend who commented that it was ingenious because consultants are expected to have a system to sell. I thought that if I’m doing this, I should think of a name for it—something catchy and self-inflating! And thus, I present to you "The May System." If this makes you want to throw copious amounts of money at me, do let me know! But for now, I think I’ll continue with my regular activities, if that’s okay with all of you.
00:26:39.680 Thus far, we’ve established a system, and we've identified some quadrants, but that’s not particularly useful just yet. What we’ve done so far is mainly capture the practices that people follow and categorize them accordingly. The real power lies in applying these categories to higher-risk problems—a topic from which we can derive deeper insights. Let's explore how we can apply these categories generated from low-risk problems to those high-risk dilemmas that we often face.
00:27:50.880 Starting with the concept of the interface, it defines what is available within a framework’s README. For example, consider what the Angular and Ember READMEs contain: the lists of features and functionalities that represent the foundational blog posts on how to select a framework. The same holds for activity; generally, you can glean this by examining the project on GitHub, keeping an eye on the release schedule and the accompanying documentation.
00:28:28.640 Popularity operates similarly. You can measure it through analysis of Stack Overflow content, percentage of Hacker News discussions, or the number of recent blog entries. Accessibility diverges slightly since, in the current JavaScript framework landscape, multiple frameworks boast sufficient interfaces, activities, and popularity to merit consideration for production use. Therefore, it becomes critical to navigate how we differentiate between these frameworks.
00:29:38.960 To illustrate this point, let’s delve into the accessibility judgments we make at both small and large scales. Returning to our previous HTTP library example, both libraries can handle HTTP calls effectively. Yet they feel distinctly different to use, conveying various preferences: HTTPParty allows you to enhance your existing objects with call functionalities, while Faraday requires you to maintain that calling function in separate objects. If you come from a procedural programming background, you might favor HTTPParty’s method, whereas if you’re more grounded in object-oriented programming, the structure of Faraday may resonate more.
00:30:42.640 Accessibility, in this context, emphasizes whether you identify with the coding methodology used. This concept is even more relevant at the framework level, where the type of framework heavily influences the coding style you will adopt. Next, let’s examine larger developments, particularly focusing on Angular and its evolution within the JavaScript community. If we look at the history of how Java and JavaScript have coexisted—often in tension—initially, Java web frameworks were quite challenging for JavaScript developers. The peak of this period exemplified with technologies like Java Server Faces, which created packaged front-end widgets that relied on outdated jQuery versions.
00:31:50.559 The overarching Java community sought to minimize their interaction with JavaScript. Notable approaches included the Google Web Toolkit, which compiled Java down to JavaScript, and more modern alternatives such as the Dart programming language. However, the introduction of AngularJS has changed the paradigm. By building it with a dependency injection structure incredibly similar to those found in standard Java frameworks, Angular was designed to feel familiar to Java developers who mainly work within that environment. This accessibility is a significant advancement, as Java developers can now adopt real JavaScript without having to shift entirely to a new paradigm.
00:32:59.840 Conversely, JavaScript frameworks can seem rather bewildering for those who aren’t from a Java background. The complexity introduced by dependency injection in Angular may initially feel disorienting, making adoption quite risky. Nevertheless, once you're accustomed to JavaScript frameworks and find ones that align with your prior experiences, it makes the transition much smoother and less risky. In comparison, Ember.js has flourished thanks to its construction by Ruby on Rails developers, integrating a router at the heart of every application.
00:34:03.840 Having come from this RESTful era, if you've developed using frameworks like Rails or Django, Ember.js will feel intuitive and accessible. Yet if your experience is rooted primarily in Java or .NET, which had less emphasis on REST, Ember might feel unnecessarily restrictive in some respects. Likewise, Backbone.js emerged as a foundational technology in the context of single-page applications several years ago. Many developers approached it from a perspective that regarded JavaScript as a means to enhance server-rendered pages by enabling interactivity on the client side. For those individuals, Backbone might feel like a logical fit.
00:35:17.760 However, if your understanding of web applications is that they’re comprised primarily of JavaScript running in a browser—leading to data fetching and rendering—Backbone might come across as counterintuitive. Therefore, determining the accessibility judgment for a framework is influenced by the types of projects you've completed, as well as the technologies you’ve engaged with. This insight emphasizes that accessibility judgments concerning complex frameworks arise from multiple sources.
00:35:58.720 Lastly, accessibility is often the hardest aspect to evaluate clearly. Unlike how Angular may not specifically state 'By Java developers, for Java developers' in its README, framework creators typically presume that they are catering to a broad audience. Nevertheless, what they genuinely offer is heavily reliant on their own internal thought processes encoded into the framework. The extent to which these thought processes track with yours defines your level of comfort in using a framework. As we assess our decisions, especially those concerning frameworks, we must engage with these accessibility considerations.
00:37:06.800 As we conduct evaluations and learn to embrace accessibility in our decision-making processes, we can enhance how choices are made. The key takeaway here is that while language and framework decisions may not frequently be assessed, understanding these considerations allows us to develop more informed choices by looking through a wider lens. I want to conclude with a reference I encountered on Hacker News regarding the Nimrod programming language. One commenter lamented the language's lack of popularity, attributing it to people not evaluating things logically.
00:38:19.200 I share his frustration, as decisions made by others might seem mysterious if one’s perspective is limited. The truth is, decision-making incorporates more extensive reasoning than he realizes. Always remember that you cannot frequently repeat the decision-making process regarding language or framework selection. However, one constructive way to expand your viewpoint when tackling significant technical decisions is to utilize these categories. As a wise individual once said, 'A change in perspective is worth 80 IQ points.' Embracing diverse viewpoints may yield insights equivalent to years of experience—thank you for your time.
00:39:06.240 I should mention that I'm in the process of writing a book with Sandy Metz that applies her object-oriented frameworks specifically to Rails.
00:39:34.400 I don't know if we have time for questions, but I can't see anyone currently.
00:39:42.480 The question was whether I’d call this the matrix; that sounds like a great title, a perfect pun. As for the inquiry regarding how my decision-making has shifted since defining these quadrants, I've noticed that it assists in making group decisions. When discussions arise about the pros and cons of a particular option, visually representing the four quadrants is beneficial.
00:39:54.880 Writing down the advantages and disadvantages within these quadrants helps facilitate clarity in meetings, avoiding that situation where people talk for an hour and remain uncertain about the outcome. Also, it provokes thought about the trends among programmers who gravitate toward certain parts of the matrix. While I cannot speak to specific trends in who leans towards which quadrant, I have observed that individuals from specific communities may prefer certain styles, for example, Ruby developers who appreciated novelty.
00:40:32.640 Finally, regarding how to find consensus among a team with differing opinions, one technique is writing down the pros and cons of each option. Additionally, consider trying out the technologies for a short trial period at your team’s convenience. This way, everyone can experience the actual coding process before finalizing their opinions.
00:41:12.800 In response to the question about how to identify those frameworks that seem great initially but turn out to be undesirable later, it's generally true that the further along the adoption curve you are, the fewer surprises you might uncover. Conducting thorough workouts with frameworks before deciding to adopt them provides insight into compatibility and alignment with the specific needs of your projects—thank you very much.