Learning the Unknown

08-12-19 Daniel Flynn

How can a developer adapt quickly to new environments? Daniel shares his process for learning the unknown from his experiences during a recent project with the Described and Captioned Media Program.

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?

Foundations

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.

Syntax

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?

Modularity

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.

Dependency Management

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.

On occasion, you’ll learn that the environment does not have any method for you to easily pull in third-party tools. Ruby, Java, and JavaScript have set a high bar with their dependency management tools. You might not have something of equal value. Languages like BrightScript have no dependency management tools, and you’ll have to use Git submodules or copy-paste to include community-driven modules.

Data Persistence

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.

Services

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.

For example, in JavaScript, you should learn the difference between using a Promise or a callback. In Go, you should learn how to open a connection and also understand the importance of when to defer closing the request. Or for an even more “exotic” take, you’ll need to learn how languages such as BrightScript require XML interfaces and callbacks to make an HTTP request.

Best Practices

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.

Tooling

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