zed.dev
Course Description
Take your Elm abilities to the next level! Learn the best techniques for authentication, scaling, styling, module structure, Single Page Apps, performance optimization, and much more. This course uses the latest 0.19 version of Elm.
This course and others like it are available as part of our Frontend Masters video subscription.
Preview
CloseCourse Details
Published: October 18, 2018
Learning Paths
Learn Straight from the Experts Who Shape the Modern Web
Your Path to Senior Developer and Beyond
- 200+ In-depth courses
- 18 Learning Paths
- Industry Leading Experts
- Live Interactive Workshops
Table of Contents
Introduction
Section Duration: 5 minutes
- Richard Feldman begins the course by explaining that the workshop was created to help people who want to transition from using Elm as a hobby, to using it at work or at scale. The primary goals and an outline of the course are discussed, as well as the workshop's structure.
Opaque Types
Section Duration: 36 minutes
- Richard introduces how choosing whether or not to expose a custom type's variants from a module affects the guarantees you can enforce about that type.
- Opaque types are types whose implementation details are hidden from other modules. Richard gives examples of opaque types in core Elm libraries, only some of which are custom types under the hood.
- Richard shows how elm-validate uses a custom type called Valid to guarantee that forms have been run through a validation function before being submitted.
- Richard demonstrates through direct application why it's important to make it impossible for code to compile unless an edge case has been handled.
- Richard uses the example of Author custom type in the course repo to demonstrate a case where opaque types are not useful.
- Students are instructed to make Cred an opaque type, then fix the resulting compiler errors.
- Richard live-codes the solutions to the Opaque Types exercise.
Extensible Data
Section Duration: 36 minutes
- Elm's compiler performs type inference through a process called constraint unification. Richard walks through how it works.
- Closed records define the exact shape of a record, whereas open records specify a minimum set of fields that must be present. Richard shows how these work with constraint unification.
- Richard explains why open records are necessary in Elm. Although not designed for it, they are also used for naming arguments, and data modeling.
- Richard demonstrates how a more extensible data shapes could be created with custom types than with an open record.
- A clarification question is asked about the example that was last shown, Richard gives a word of caution about open records, and this section of the course is briefly reviewed.
- Students are instructed to return and convert data using extensible data principles.
- Richard live-codes the solution to the Extensible Data exercise.
Creating Constraints
Section Duration: 33 minutes
- Using the Mars Climate Orbiter disaster as an application, Richard demonstrates how to use custom types to add measurement units to numbers, and contrasts this method with a refactored solution using phantom types.
- The tesk9/accessible-html library is introduced. Richard shows how the library uses type constraints to guarantee that semantically non-interactive HTML elements like paragraphs can never be given event handlers.
- Richard shows how the Never type can be used to describe Tasks that are guaranteed never to fail.
- Richard summarizes the tradeoffs between accepting Attribute Msg, Attribute msg, and Attribute Never. Phantom types and non-phantom types are discussed, as well as how to use Never as a constraint to require that something is still unbound, and how that will unify with two different type variables.
- Students are instructed to convert a Task to a Cmd using Task.attempt or Task.perform.
- Richard live-codes the solution to the Creating Constraints exercise.
Scaling
Section Duration: 43 minutes
- Richard discusses the fundamental challenge of scaling: what happens when the codebase gets too big to fit in our heads?
- Narrowing types are introduced as the key to scaling. Richard discusses the implications this can have on debugging. - couldn't find this cut...
- Using the current codebase, Richard demonstrates how adding arguments can enforce business rules. He gives the example of adding a mandatory Cred (credentials) argument to certain Msg variants, to enforce that those variants can only be used when the user is logged in.
- Richard discusses the benefits of organizing modules around a single type, and the cost of splitting modules based in file length rather than based on types.
- Students are instructed to refactor three different files to accept narrower types than the entire Model.
- Richard live-codes the solution to the Scaling exercise.
Reuse
Section Duration: 43 minutes
- Richard walks through examples of the most important tool for reuse in Elm: the helper function. It works for view logic, update logic, and everything in between.
- Sometimes reuse is not best practice. Three different flavors of status are discussed. Richard shows some examples of similar code where reuse would result in excessive configuration.
- When a view function returns an Html msg, it is reusable across pages and projects. Richard discusses two possibilities: either an unbounded type, or receiving a message.
- Richard discusses the most powerful with the most overhead reuse method. When a view function needs several different message variants, returning Html msg can require excessive configuration. In these cases, Html.map and Cmd.map can replace the configuration with a one-time translation operation.
- Students are instructed to refactor their code such that the concepts of reuse are utilized effectively.
- Richard live-codes the solution to the Reuse exercise.
Sources of Truth
Section Duration: 30 minutes
- When we have multiple sources of truth for the same information, our application can end up in states that ought to be impossible. Richard gives an example of how this can affect the tabs in the sample application.
- Richard explains why, given the option of rendering a value that is derived from another in view and throwing it away, this is a much better alternative than recording it in the model.
- Authentication is a case where the source of truth is on the server, but the client must cache the authentication token to get acceptable performance. Richard walks through what can happen if this cached information becomes invalid.
- When interoperating with JavaScript, Elm or JavaScript be the source of truth. Richard argues ultimately for letting JavaScript own the state because of the consequences of competing for state. This section of the course is also reviewed.
- Students are tasked with creating a single source of truth within the tab functionality in the application.
- Richard live-codes the solution to the Caching exercise.
Decoding
Section Duration: 33 minutes
- Richard shows how the Decode Pipeline types interact with the types of the Decoder primitives using Decode.map3.
- Richard compares the Decode.succeed function to Decode.map3, and explains the use cases.
- Richard explains that Decode.andThen works similarly to Decode.map, with the exception that it can additionally change successes to failures.
- Richard shows how Decode.andThen can be used with a result to "decoderize" an operation.
- Richard uses the example application as a reference while explaining intermediate representations as for the idea of using internals only for the purpose of creating a decoder, not exposing it to the outside world as an intermediate step, then using Decode.map to convert to the one that the world sees.
- Students are instructed to decode a Time.Posix value using Decode.andThen.
- Richard live-codes the solution to the Decoding exercise.
Single-Page Apps
Section Duration: 29 minutes
- Richard uses the example application to demonstrate how to define a Route custom type that represents the different URL pathways in the application, and how to parse URLs into them.
- Despite the name, Single-Page Apps have multiple logical "Pages" in them. Richard demonstrates how to model these in Elm. - Maybe 0:00-1:40 ? Cliffhanger??
- Great Elm modules tend to be organized around a particular type. Richard uses the sample application to demonstrate how the modules in the example application are organized, and why the boundaries are drawn where they are.
- There are several possible strategies for loading and persisting data between pages. Richard discusses trade-offs between different strategies.
- This exercise is intended to help students to become familiar with this DSL for going from URLs to Routes.
- Richard live-codes the solution to the SPAs exercise.
Wrapping Up
Section Duration: 7 minutes
- Richard reviews the goals and topics the workshop has covered and shares additional resources. There is a special behind-the-scenes discussion with Richard to conclude the course.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops