Hello from a brand new Junior Engineer at NoRedInk! I started working at NoRedInk in January and it’s both my first job as a Software Engineer and my first time using Elm. Thinking about learning Elm? Here’s what it was like to learn Elm from scratch!
The Beginning
A brief background on my programming experience: in 2016, I attended a coding bootcamp that taught Ruby on Rails and JavaScript and stayed on for a year as a TA. I’d done some programming in Matlab during college, but little else before attending the bootcamp. After receiving an offer from NoRedInk, I spent three computer-free months road tripping across the United States. This all means that I had a) very little experience working with purely functional and statically-typed languages, b) programming skills coated in a three-month layer of road trip dust, and c) equally matched levels of excitement and terror over learning Elm well enough to contribute to NRI’s codebase.
My initial terror towards starting a new job and learning a new language quickly abated. I spent 100% of my first week pairing with more experienced engineers on the team, which was both educational and fun (the NRI team is an amusing bunch). Nonetheless, my confusion abounded, stemming mainly from the size of the codebase (Help! where does everything live?) and my unfamiliarity with Elm. While some parts of Elm made intuitive sense, other aspects of the language felt perplexing and mysterious.
Battling Confusion
Elm was the first language to introduce me to type signatures. I was told that their purpose was to provide helpful compiler errors in lieu of unhelpful runtime errors but, as an inexperienced user, they mostly provided me with confusion. During my first day writing code at NoRedInk, I encountered the Html.map
function while looking at a reusable view and was rather perplexed. Its type signature looks like this:
map : (a -> msg) -> Html a -> Html msg
I wasn’t quite sure what Html.map
’s type signature meant by (a -> msg)
, nor did I understand what a
or msg
were supposed to be. Beyond making sense of its type signature, I had little understanding of why we needed to use Html.map
in the first place.
While I wish I could report that I went home that day with a firm grasp on Html.map
(and all things Elm-related really), the reality was that it took a while longer for the pieces to come together. Html.map
lies at the intersection of several concepts that were new to me and I was missing too many pieces of context to understand how it worked. Before I could understand Html.map
, I needed to have a grasp on type signatures, Elm architecture, and the general idea of passing around functions as arguments. However, as a brand-new Elm user, I was not yet aware that I was missing these pieces of context and felt frustrated when I didn’t immediately understand what was going on.
Luckily, I had a team of experienced Elm developers at my disposal who could point me towards a number of useful resources and learning strategies. Here are some resources and strategies that I found particularly helpful:
The Elm Tutorial: The Elm Tutorial is a great resource for beginners. Walking through the tutorial from beginning to end gave me a good high level overview of Elm architecture and provided me with pieces of context I didn’t even know I was missing. After finishing the tutorial, I felt significantly less confused about how Elm deals with user interactions and understood why a view function returns an Html msg
. Working through the tutorial was also a good way to handle Elm code in a simplified context, rather than trying to understand what was going on in NoRedInk’s complex codebase.
The Elm Package Docs: Whenever I’m confused about a function or am wondering whether a function that I need exists, I consult the Elm Package docs. While they are a stellar resource, the Elm Package docs can also feel overwhelming. They contain a lot of information, and it can feel difficult to know where to start. For beginners interested in creating a basic web app, referencing the Core and HTML packages provides a good starting point. I also find it helpful to think about what type signature will solve the problem at hand and search for that type signature when looking for functions. For example, if I’m looking for a function that takes in an Int
and returns a String
, I can grep for Int -> String
in a specific package. Like learning a new language, learning to navigate documentation takes time, and as I’ve worked more with Elm, I’ve become more confident in using the docs to look up what I need.
Drawing connections: Another strategy that has helped me is drawing connections between unfamiliar concepts and concepts that I understand well. In the case of Html.map
, it was helpful to look at List.map
. Just like JavaScript’s map
function, Elm’s List.map
requires a function and a list. It uses the function to transform each element in the list into a new element:
map : (a -> b) -> List a -> List b
A member of my team pointed out that Html.map
works similarly. Instead of transforming elements of list, it transforms a msg
. Drawing a connection to a concept that I did understand well helped Html.map
click.
The Elm Community: As an employee at NoRedInk, I have the unique advantage of working with experienced members of the Elm community on a daily basis. If I have a question, I need look no further than the desk next to me to seek help. Being unafraid to ask “stupid” questions has also been extremely valuable to my learning process. Sometimes, there is no better way to resolve confusion than admitting that you don’t know something and asking a human being who does!
Even if you lack the convenience of having experienced Elm developers one desk over, there are still several ways to connect with the Elm community, including the Elm Subreddit, Elm’s Slack, and Elm meetup groups. In my experience, the Elm community is very friendly and wants to help you learn, whatever your background and current level of knowledge. Meander into the Elm grove and say hello!
Making Peace with Confusion
My ultimate piece of advice is to dive right in and try to build something if you’re thinking of learning Elm. There are plenty of resources out there to help you, and there is no better way to start learning a language than to… start learning it!
I’ve grown to love parts of the language that I initially found confusing and frustrating. Type signatures and compiler errors are my new best friends (along with my great new coworkers, of course). Type signatures force me to think a few moves in ahead and be more conscious of the code that I’m writing. Compiler errors tell me exactly what I’m doing wrong without forcing me to embark on the grand debugger chase-down of 2017. I’d almost call debugging my code… fun?
Sometimes, the amount of context needed to understand a seemingly simple snippet of code can feel overwhelming. It’s okay to need more context! Learning a new language isn’t about understanding everything immediately; it’s about building foundations and circling back to complex topics later. It can be frustrating not to understand concepts at first glance, but as I’ve picked up more languages, I’ve accepted confusion as a natural part of the process. I am still new to Elm and have a lot to learn, but my fear of learning the language has greatly diminished. It’s all fun from here on out! I’m excited to be working at NoRedInk and look forward to sharing more about the joy and confusion that accompany learning a new language. Interested in joining us? We’re hiring!
Brooke Angel
Engineer at NoRedInk