00:00:00.000
Hello everyone, welcome to my talk named 'The Selfish Programmer.' In this presentation, I want to explore what you can learn by writing software for yourself, as opposed to working on a team or as part of a larger organization.
00:00:10.200
My research shows that the three most important traits of a successful solo programmer are being antisocial, egotistical, and irresponsible. We're going to talk about all three traits. You may know me by this old picture that doesn’t really look like me or by my username 'searls' on GitHub and Twitter, which I pronounce as 'Sade Zoo' when I'm here in Japan because it's easier.
00:00:26.789
I work for a company called Test Double, where we have software developer teams that join other organizations to help them get things done, as well as to search for general ways to improve. I'm here today because I've been struggling with learning Japanese for years, and I found it really challenging. A couple of years ago, I discovered an application called WaniKani, which helps teach kanji and vocabulary memorization.
00:00:57.930
Its interface is like a flashcard game where you see Japanese characters and have to provide the reading, such as 'tsunami' for 津波, and it marks you right or wrong based on your responses. Additionally, it gives you the English meaning. This app's ability to teach me kanji was excellent; however, I found it lacked when I was trying to express concepts in Japanese that originated in English.
00:01:15.479
So, I built a companion app to WaniKani, which I called 'Kamisama.' This app works in reverse; it provides an English prompt, and using a Japanese keyboard, you have to provide the correct answer. It also has a feedback mechanism similar to WaniKani to help reinforce the learning process.
00:01:36.360
Building this app taught me a lot about selfish programming, which I believe can be beneficial for programmers. I would like to discuss why it can be beneficial to be a little bit antisocial. First, let's talk about why the selfish programmer is unambitious.
00:01:54.030
It’s easier to stay motivated when our goals are incremental and achievable. When goals are too ambitious, we run the risk of exhausting ourselves without making real progress, which might eventually lead to quitting. In contrast, at work, our applications are large and involve many components, where we can rely on others to cover various areas. The problem with large systems is that our brains can’t contain them all, and switching between contexts can be time-consuming.
00:02:26.100
For that reason, many developers specialize in just one part of a system at any given time. I get nostalgic when I remember starting to use Ruby in 2005. Back then, Ruby was known for enabling individuals to create small, useful applications quickly. Ultimately, Ruby allowed me to keep my entire application in my head, so I was much faster.
00:03:10.320
Fast forward 14 years, I attempted to create a new solo Ruby app. After several days of effort, I completed only a small part of the app that turned out to be useless on its own, which discouraged me and made me think about how much longer it would take to finish the complete application. Over these 14 years, I feel I had unlearned how to create small, useful things.
00:03:44.370
As a result, I established a personal rule: if I cannot release a project by Sunday night, I won’t even start it. This one-weekend rule is liberating because it forces me to shrink the scope of my app, and I find that it fits within my brain, allowing me to work more quickly.
00:04:19.110
For my initial project, I thought of a simple and small feature: a gem that tells me whether my WaniKani flashcard reviews are ready or not. It’s just a command-line interface that runs and tells me when to come back to check on my reviews.
00:04:58.140
The code is straightforward; it uses Net::HTTP and JSON. With a given API key, it fetches a response and checks for errors. If there are reviews available, it informs me immediately, effectively making it super easy to test and retain in my mind.
00:05:35.820
What’s crucial is that this initial project gave me the experience of working with WaniKani's API, which helped with the larger application I eventually wanted to build. My next project involved creating an English to Japanese flashcard game, but it turned out to be too complicated since it involved a user interface and various game rules.
00:06:20.580
Thus, I decided to focus only on the game logic, wrapping it in a simple command-line interface for practice. Over weeks, I would get the logic right by practicing with correct and incorrect answers, adapting for synonyms and implementing timers.
00:07:01.550
To my surprise, I ended up with real code that could build a review queue for me, score my answers, and track progress effectively. That weekend project was a resounding success and became the foundation for the current web application. Such incremental accomplishments keep me motivated and moving forward.
00:07:37.440
So the selfish programmer is unambitious, shrinking their goals until they are easy to accomplish. The next point to mention, stage two, is how the selfish programmer is ungrateful about open-source dependencies.
00:08:08.330
When unmanaged, dependencies can create an unmaintainable mess. I like to think of applications as triangles: original application code at the top, with various gems and dependencies below. In a corporate setting, the marginal cost of adding one more gem is low, but in solo projects, each additional gem increases the maintenance burden.
00:08:43.660
Instead of arbitrarily limiting myself, I categorize dependencies based on how much I trust their maintainers. For example, I trust the Rails core team to curate their dependencies closely, which allows me to include Rails in my projects.
00:09:14.300
Conversely, I consider the smaller gems carefully before adopting them, especially if I don’t trust their maintainers. While at work, I have been conditioned to never reinvent the wheel, in solo projects I might choose to write code even if another gem could do the same thing.
00:09:50.860
Sometimes I find gems that are too cumbersome to learn. If a gem overwhelming me leads to quitting a solo project, I’d rather take the time to create my solution than give up. For instance, I’ve never been responsible for building authentication features at work, but for Kamisama, I needed to figure it out. I faced my fear of using existing solutions like the Devise gem, and I started with a basic password field.
00:10:30.220
As a result, my solution utilized bcrypt and Rails’ 'has_secure_password' feature, which worked perfectly. This foundational implementation lasted five months before I expanded to include more complex features.
00:11:13.430
Eventually, I added features like changing passwords, verification emails, and so forth. Even though those custom functions were likely more complex than using Devise, my pride comes from having created them myself, resulting in a deeper understanding of my application’s workings.
00:11:50.210
Kamisama provided me the opportunity to practice a skill where I lacked confidence previously. So now I can engage comfortably in conversations about authentication because I developed this understanding myself.
00:12:28.480
Nonetheless, solo programmers must consider the ease of adding dependencies and the long-term issues that may arise from using them without careful thought. Therefore, they must critically weigh the trade-offs of each dependency they add.
00:13:06.940
Moving on to stage three, the selfish programmer's code is often ungenerous and doesn’t focus on making code reusable. In a work environment, I've learned to share code to benefit the team, but this can inadvertently slow progress as code reuse leads to higher maintenance costs.
00:13:42.270
That's why I prefer to keep my code isolated, focusing on implementing it close to the feature it serves, instead of storing my logic in shared locations. By soundproofing my code, I avoid the complications that come with extensive reuse.
00:14:18.840
I treat my models as simple value types, focusing on functionality and keeping model responsibilities clear. For example, if a controller performs two distinct tasks, I make sure to separate those functionalities to maintain cleaner and prioritized code.
00:14:51.100
Soundproofing my code allows me to change it aggressively since it is only invoked in one context, while I ensure the more generalized utility code remains lean, as it will be called in multiple places. Additionally, I avoid adding custom logic to Rails subclasses, treating them primarily as configuration and keeping the package size minimal.
00:15:31.240
This approach has served me well. For example, I initially built Kamisama as a sentence search engine without any need for further changes when I adapted it, which underscores how keeping code simple can eases modifications.
00:16:08.110
This careful separation of code ensures that some areas are viewed as valuable assets within workplaces, leading teams to believe that maximizing reuse enhances speed. Still, this can create dependency nightmares, which is why the selfish programmer embraces writing just enough code for flexibility.
00:16:45.680
Now, let’s discuss the virtues of being egotistical. At stage one, the selfish programmer is delusional, often believing that their code is ready to ship even when it’s still rough around the edges.
00:17:21.110
In my case, pushing messy but functional code allows me to observe performance and behavior over time, which helps me refine the product based on actual use. This iterative refinement enables me to be confident that changes presented in the end result meet my expectations.
00:18:00.160
Initially, I was running too many queries for my application’s API response. However, when addressing response times, I transitioned to using PostgreSQL views to aggregate data effectively, improving the application’s overall performance.
00:18:37.620
To sum up, I encourage shipping code quickly, observing the output, and refining as necessary before returning to optimize. The pressure to produce perfect code can hinder actual project progression.
00:19:10.370
The second stage of egotism is narcissism, where the selfish programmer considers only personal benefit when evaluating activities. In collaborative environments, tests enhance communication by clarifying intents and ensuring everything functions correctly across different sections of an application.
00:19:49.880
However, these testing benefits don’t always extend to solo projects. When working alone, you manage the direction entirely, and it’s easier to assess specific tasks without employing comprehensive tests.
00:20:30.730
For my project Kamisama, I adopted AI testing, which simply looks at recent code changes and only runs relevant tests. This method enhances efficiency, cutting the testing time significantly.
00:21:03.120
Truthfully, my AI testing means I often executed tests manually without writing formal code-based tests because it just didn't seem like a smart return on investment.
00:21:43.650
Thus, while traditionally automated testing pays off on teams, with solo projects, you need to assess the cost-benefit relationship since you’re only investing your time when managing tasks.
00:22:25.850
In programming, a balance must be struck between preventing issues upfront or minimizing repair time later on. My career primarily focused on maximizing the prevention of problems, yet now I find value in learning about monitoring and debugging.
00:23:07.300
So, although automated testing can seem indispensable, solo programmers like myself must be judicious about their time investments. This brings us to the third stage, where the selfish programmer is domineering and used to asserting their personal vision.
00:23:41.700
When you’re solo, you advocate for your own priorities without needing to navigate multiple stakeholders' needs. The complexity of managing various demands contrasts starkly when you’re simply focusing on a personal project. Hence, I opted to launch Kamisama for free, making me my only customer.
00:24:12.250
With that came the freedom to make decisions based solely on personal preference without external pressure. However, as development progressed, I began to run out of ideas and turned to community boards for inspiration.
00:24:51.900
This enabled me to solicit ideas for improvement. While responding to feature requests, some were good, others weren’t worth prioritizing due to personal disinterest. A notable example was a suggestion for color-coding. A colorblind user expressed difficulties with subtle distinctions.
00:25:31.890
Initially, I hesitated to act as it didn’t affect me; however, once I reviewed their feedback in context, I realized a simple solution could significantly enhance accessibility. So, I implemented straightforward validations for the kanji inputs.
00:26:07.850
This modified validation had multiple benefits, and a feature inspired by a user’s experience enriched my application positively. It became more apparent that selfish programming can yield benefits for others even when it begins from a personal need.
00:26:43.030
At work, we may forget to voice our perspectives, yet a successful selfish programmer takes control over their priorities while remaining flexible to community feedback.
00:27:16.920
Now shifting to stage one in the next world, the selfish programmer actively detaches from operational responsibilities, enabling their application to run with minimum involvement.
00:27:55.970
Many apps come with operational burdens ranging from security to performance monitoring. Originally, 'DevOps' implicated developers being responsible for operational tasks; however, it has morphed into something demanding full-time positions resembling traditional systems admins.
00:28:32.770
As a proponent of 'no ops,' my ambition is to focus solely on coding without routine operational work. My strategy included reducing dependencies and leveraging services like Heroku, which eliminate much of the operational overhead.
00:29:11.310
Heroku allows me to produce a simple configuration defining how my server functions and automating necessary tasks like migrations directly during pushes. This exemplifies effective service management.
00:29:46.240
Offering remarkable value, platforms like Heroku can outperform significant investments in custom infrastructure by streamlining the developer experience for minimal cost.
00:30:22.670
However, there are growing pains, as companies tend to resist adopting standardized operational solutions, clinging to their unique processes despite the efficiency of outsource operations. Why not collaborate with those specializing in specific operational needs?
00:30:59.280
The selfish programmer discards operational burdens to focus purely on writing code. As such, the second stage here reveals the fickleness of the selfish programmer, reflecting how personal whims and creativity can alter opinions and preferences frequently.
00:31:35.390
In shared coding environments, consistency standardizes practices, enhancing readability and manageability. Solo coding allows for greater freedom; each change can lead to inconsistency across projects, which complicates maintenance.
00:32:11.270
Tools like RuboCop help enforce rules consistently, yet each implementation may generate large, non-standardized configurations. To combat this, at Test Double, we created 'Standard'—a package that encapsulates best practices, providing consistency while minimizing decision fatigue.
00:32:49.000
Standard addresses syntax and formatting decisively, allowing one community style to prevail while maintaining quality across teams. Utilizing such tools can help maintain focus and consistency in programming.
00:33:27.470
Finally, the last stage of our exploration involves unhelpfulness. The selfish programmer aspires to solve problems once rather than revisiting the same issues repeatedly.
00:34:04.870
In organizational settings, support staff commonly mediate queries, relaying repeats and workarounds for complex issues to developers who are shielded from user feedback. Yet, the solo programmer is constantly exposed to user responses.
00:34:43.290
When I encountered a troubling bug stemming from browser behaviors, I learned quickly through user feedback and direct engagement how essential it is to refine the client code proactively.
00:35:23.650
To mitigate potential repetitive tasks, I developed a gem named 'To Do or Die,' designed to remind me of messages I needed to address or tasks to delete.
00:36:01.320
This preventative tool boosting accountability resulted in significantly fewer recurring bugs. In summary, the selfish programmer's focus on preventing issues is evident: they understand that if no one is seeking help, it implies they’ve succeeded.
00:36:39.150
This leads us back to the exploration of selfish programmers as being antisocial, egotistical, and irresponsible. If you have any comments or questions, feel free to tweet or send a DM. I’ll also be available throughout the day for discussions.
00:37:13.740
You can check out Kamisama at kamisama.com. Additionally, feel free to grab a copy of the background artwork linked here. If your teams need developers who won’t mind speaking largely in English, I’d love to discuss opportunities at Test Double.
00:37:40.990
Thank you once again for joining me today, and I hope this talk encourages you to adopt a more selfish approach in your solo coding endeavors.
00:38:23.250
Unfortunately, we do not have time for questions.
00:38:32.110
If anyone has questions, please approach the microphone to ask.
00:39:08.450
Thank you for the presentation! I appreciate your motivating story about developing your application. I am not a programmer myself; I work in instructional design. Do you think your experiences could benefit programming training?
00:39:41.920
Thank you for your question! I believe the best method for beginners to learn programming is to pursue something they genuinely want to create and to go through the necessary work to make it happen.
00:40:23.260
[Further questions about programming differences in solo vs. workplace projects]. Certainly, maintaining a library differs greatly from running a live service application. My experiences taught me a lot about expectations and capabilities when it comes to running applications.
00:40:51.380
[End of Q&A session]. Thank you for attending this session and for sharing your valuable questions!