Our jobs as developers have always necessitated that we be experts in programmatic thinking but stay flexible in how we implement our work. Whether it is the language, framework, or programming paradigm we work with, it will inevitably change. This is not news to a lot of developers but instead is a truth we hold with equal parts fear and delight. How do we stay flexible as opportunities come up and adapt quickly to foreign environments?
At Sparkbox, we are fortunate to have cultivated and maintained client relationships that have allowed us to stretch ourselves with new projects—projects that differ significantly from our “normal work.” After our original project with them, the Described and Captioned Media Program (DCMP) asked us to develop both a Roku and a tvOS application for their streaming service. Both of these projects required native applications that lie outside of Sparkbox’s usual expertise. So how did we adjust to building native applications from a background of building web applications? How can we learn an entire application environment we have little to no experience in?
Before you step into learning a new language or framework, you need to understand the paradigm of the language and environment you’re entering: is it functional, procedural, or object-oriented? Understanding this will provide a set of expectations for this foreign environment.
For example, if you are working in an environment using functional programming paradigms, you’ll need to understand what a pure function is and how to manage immutable data. These paradigms each have their individual vernacular and terms that will help inform any decision you’ll need to make.
If you are trying to figure out which programming paradigm the environment you are moving to follows, here are a few keywords for each that you can watch for. Look for references to these terms in almost all of your Google search results, as they are a part of each paradigm community’s ubiquitous language.
Procedural: subroutines, collections, procedures
Functional: immutable, first class function, composition, side effects
Object-Oriented: class, OO, polymorphism, inheritance, objects
These terms may be mixed and matched between paradigms. For example, object-oriented programming still references functions and may talk about pure functions, but it will have a significantly heavier emphasis on classes.
Having a firm grasp on the foundation behind the language or framework will allow us to feel confident in designing how the application will be built, managed, and documented.
With the foundational knowledge of what programming paradigm you are working in, next it’s critical to understand the “building blocks” that comprise the environment.
For languages, look for walkthroughs or documentation that teach the following topics:
Instantiating and modifying variables
Available native data types such as Array, String, Int, or Bool
Creating functions and groups of functions, such as a “Package” or “Class”
Flow control, including conditional statements and loops
Concurrency and asynchronous actions
For frameworks, find the answers to these questions:
What high-level methods and APIs are being provided?
How does this framework decorate or add on to the foundational language?
In almost every application, you will need to have separate modules regardless of what programming paradigm you are working in. Maintaining an entire application in a single file will not only slow active development time but cause single points of success for your project that can’t scale. Understanding how to make new files and reference their functionality will enable you to clearly find splitting points in the code and separate out operations for their single responsibility.
Along with understanding modules that you write, it is equally important to understand how to leverage the community backing the environment you are using. While reinventing the wheel can help you thoroughly grasp complex topics such as authentication, it usually isn’t beneficial to spend project time on this or to open yourself up to unknown defects due to your lack of knowledge of the environment.
Whether caching a web views response or saving JWT tokens as cookies, if you need to persist data, you need to understand the limitations of the environment. Some environments, like browsers, come with data storage through many facets: cookies, local storage, web storage, and the browser’s internal cache. Understanding how your environment can store data will allow you to make decisions around how to store data temporarily, for a specific period of time, or indefinitely.
Understanding the limits of data persistence is especially important if you are using any type of public API key or you want to persist user sessions. If your environment does not meet the requirements you need, you’ll want to understand what type of external requests and services you can use.
When you run into work or operations that your environment cannot or should not be doing, you can lean on external services to provide that information. Interfacing with service APIs provides a lot of benefits, but you must understand how to make requests, how they are managed, and how to properly consume them.
In most environments, HTTP requests are asynchronous in that the application can continue working without having to wait around for a response. This normally will result in what is called an event loop, which manages this asynchronous complexity. While it is not necessary to know the complete internals of how your environment handles these types of asynchronous statements, it will be beneficial to understand how to write them.
Now that you’ve got a handle on a lot of the core concepts of the environment, you’ll want to do some quick research on best practices. Generally, programmers are opinionated people. While some of these opinions are just navel-gazing, a lot of opinions are from experiences in shipping applications and seeing what works and what doesn’t. You stand on the shoulders of giants when referencing refactoring principles, design patterns, or performance improvements, and you should heed their advice.
Trust the community you are walking into. It may be significantly different than what you are used to, but they have experienced a lot of the pitfalls and gained environmental knowledge. Reading up on what they’ve normalized on will save you time and effort.
The last piece of our learning framework is tooling. Remembering syntax, best practices, documentation, and other environment-specific information will inevitably be hard. However, with good tooling comes automated reminders and fixes. Do research on linters, compilers, and on whether or not your preferred text editor has tools for “live” error checking. Although it does come with a bit of initial investment, the tools will almost always reduce the mean time to failure with automated testing, compilation, builds, and more.
Iterate Using the Weekend Rule
If you follow these steps, you will gain a lot of conceptual knowledge on how to design and develop an application outside of your expertise; however, this is almost never enough to confidently develop inside a foreign environment.
In order to obtain experiential knowledge, you need to go through the exercise of creating a small application. Come up with a simple, abstract application idea that touches on a majority of these concepts and try to follow the “weekend rule” of constraining your entire development time to what you could finish in a weekend.
Here are a couple of starter ideas that you can take and apply as you want!
Use the Pokemon API to create a paginated listing of Pokemon with the ability to create “Favorite Pokemon”
Create an “English to Emoji” translator using an API with a cache to prevent duplicate translations