Old Programmers Can Learn New Tricks
Changing careers can be both thrilling and challenging. You benefit by gaining useful experiences and skills to take into your next venture, but you are, despite previous work experience, a novice in your new field. I have experienced this shift multiple times: from a civil engineer to a teacher, from a teacher to a self-taught software developer, and finally from a solo developer to a software engineer at a startup. That last transition was the most surprising, even though I was still writing code, I discovered how much there is to learn about coding as part of a team. Overcoming the initial learning curve involved more than just learning new tools; some of it required changing how I thought about the code itself, helped along by high-quality pairing sessions.
Throughout my ten years as a middle school teacher on Chicago’s South Side, I was always looking for ways to automate my work or try out new technologies for learning. I picked up programming as a hobby and occasionally automated things. I set up a pen-pal program with IBM employees for my students. To work around my school’s restriction on student email I wrote an app in Filemaker Pro that could connect students with their pen pals. Later, as part of a behavior incentive plan that also taught money management skills, I built an app to emulate a checking account in ASP on an IIS server. The ideas for applications were endless, but my time was not. I had become a pretty good teacher, but I started thinking I might be more useful coding full time.
As I taught myself to build more robust apps over the next ten years, I became adept at programming in .NET and later PHP. Wearing all the hats, I designed, built, deployed, and supported quite a few apps that were all related to teaching though none that directly faced students. The last of these was a side project that grew into the beginnings of a startup. The project allowed teachers and administrators to document student behavior issues and trigger workflows to correct the behavior. I actually wrote much of the app while sitting in a school responding to constant feedback from the principal and teachers who invited me to be a member of their behavior modification team.
The pilot was a huge success. Before I knew it I had 30 Chicago public schools very happily using my software. When I tried to make this a full-time venture and go after the whole district, however, I ran into some headwinds. A district of 600 schools was not going to trust such a sensitive service to a company that consisted of a self-taught programmer and his computer. The manager of data security asked about testing, version control, load balancers, and financial stability. My answers came up short; I really didn’t have the technical or business capacity to scale my project. This was the downside of working in isolation for all those years. It was time to move on.
eSpark Learning makes software for iPads and Chromebooks that delivers a highly organized curriculum of great resources to students based on their individual needs. From hundreds of thousands of apps, videos, and websites, they curate the best and align them to educational standards. They use an agile development process, as most startups do. Everyone in the company, from sales to support to engineering, is involved in the visioning and learning process, drawing on their experience as former students and, in many cases, former teachers. From my first day at eSpark I felt at home. I have since been involved in design problems like keeping kids engaged in reading an article on the web and automating teachers’ tasks, like setting goals for students.
I came to the company with a healthy amount of skepticism toward the Ed Tech industry. After 20 years of watching expensive computers and software sit idle, things have improved. But walking into a classroom today is still not very different than it was 20 years ago. The good intentions of school administrators and Ed Tech companies seem to have transformed the edges more than the core of what students and teachers do. So I was delighted to find that eSpark was very interested in this core. I felt that my new team knew what they were doing. There was a great respect for teachers and pedagogy. As we form new ideas and approaches to learning, we are constantly checking in with the teachers who implement our products. Their opinions and ideas together with data from students drive each iteration of the design. I felt I was a very constructive player in this process. But pretty early on other challenges arose.
I knew coming into the job that I would need to learn a new stack and adopt a new set of tools. But I was surprised at how difficult it was to fully fit into a modern software engineering team. As a self-taught programmer who worked alone, I never had to write code so that others could understand it. Furthermore, the code base for any given project was small enough that I could get away with manual testing and weekly releases. Now, on a team that manages hundreds of thousands of lines of code and nightly releases, I had to adjust to a different coding standard that was constantly vetted with reviews and tests.
Our CTO, Luke Shepard, said it was a rational decision to hire me. He appreciated my experience as a teacher and as someone who has launched software into schools successfully. And he assured me that the rest could be taught. And sure enough, within a few months I was a productive member of the team having learned many tools: git, Rails, Angular, React, RSpec, and Jasmine. The concepts of test-driven development, sprint planning, code reviews, composability, readability, and constant refactoring settled in over time. I readily embraced the help that was offered by my young colleagues; hubris was rarely an issue for me. I was a junior engineer eager to learn. Even so, there was an occasional pattern of tension.
The tension came from my resistance to refactor my code under certain circumstances. In some instances I was trying to prioritize code performance over more composable, readable code. For example, I was trying to transform nested arrays and increment various counters all in one loop. My reviewer advocated that I loop through the array several times so that it was more readable and did not have hidden side effects. In another instance I was trying to add features to rarely used internal tools to help out our support team. My code could definitely use a refactor, but I argued that I didn’t have time and this wasn’t a critical area of code. In my mind, the technical debt, or intentionally leaving poorly written code for a later cleanup, was worth it to solve a problem for the support team.
The rest of the team was united in the notion that well written code is nearly always worth pursuing and that frivolous technical debt is a bad habit. While the term elegant code was used a lot in these conversations to describe the goal, my teammates were not looking for perfectly crafted code. They were simply saying that readability, composability, and testability trump the small performance gains that I was defending. Well written code also trumps adding a nice feature that we don’t have time for. Putting in extra effort at the time of writing pays dividends down the road. It helps us avoid bugs. It helps us fix problems and add new features more quickly. It helps make the code more maintainable for the next person. The fact that I sometimes struggled to write sound code was something I had to address.
Fortunately, in addition to valuing well written code, we also have a strong culture of learning. Pairing has been a great way to deal with friction. If I don’t understand or agree with the reason a refactor is being requested, I don’t hesitate to ask to pair on it and dig into specifics. This time is most effective when my mentor takes the time to understand my reasoning and provide a clear rationale for their proposed approach. It doesn’t always sink in the first time, but the investment is well worth it as I become a more independent and trusted colleague.
In the pursuit of a healthy engineering culture, career changers and programmers who do not come from a modern software environment can become valuable assets. While high quality mentoring will go a long way to ensure success of any new hire, the following suggestions are particularly important for those in transition:
High Quality Mentoring/Pairing of Career or Culture Changers
- Establish a culture of learning — providing time and encouragement
- Make pairing an expectation whenever friction or questions occur
- Acknowledge the difficulty in transitioning from old habits to new
- Seek to understand the rationale behind old habits
- Provide a very clear explanation of the benefits of new habits
- Repeat as necessary