Elm Radio

Elm Radio

By Dillon Kearns, Jeroen EngelsTechnology
Download on the App Store

Elm Radio episodes

  • 006: elm/parser
    What is a parser?
    • yacc/lex
    • AST (Abstract Syntax Tree) vs. CST (Concrete Syntax Tree)
    • JSON decoding vs. parsing
    • JSON decoding is validating a data structure that has already been parsed. Assumes a valid structure.
    • elm/parser
    • Haskell parsec library - initially used for the Elm compiler, now uses custom parser
    What is a parser?
    • One character at a time
    • Takes input string, turns it into structued data (or error)
    Comitting
    • Backtrackable parsers
    • chompIf and chompWhile
    • Parser.oneOf
    Benchmarking
    • elm-explorations/benchmark
    • Benchmark before making assumptions about where performance bottlenecks are
    • Write unit tests for your parser
    • GFM table parsing live stream
    • Parser.succeed
    Elm regex vs elm parser

    Indications that you might be better off with parser

    • Lots of regex capture groups
    • Want very precise error messages
    Getting source code locations
    • Parser.getRow and getCol
    • Parser.getSource
    Parser.loop
    • Loop docs in elm/parser
    • Looping allows you to track state and parse groups of expressions
    • Loop over repeated expression type, tell it termination condition with Step type (Loop and Done)
    Error Messages
    • You can fail with Parser.problem
    • Parser.Advanced module is designed to give you more precise context and error messages on failure
    • Parser.Advanced.inContext
    Getting Started with a Parser Project
    • Write lots of unit tests with elm-test!

    There's likely a specification doc if you're parsing a language or formal syntax

    • CommonMark Spec
    • GitHub-Flavored Markdown Spec
    • dillonkearns/elm-markdown test results directory from executing spec examples

    Look at examples of parser projects

    • dillonkearns/elm-markdown
    • elm-in-elm parser
    • elm-in-elm conference talk
    • mdgriffith/elm-markup - good reference for parsing, fault-tolerant parsing, and giving nice error messages
    • Tereza's YAML parser
    • Tereza's elm conf talk "Demystifying Parsers"
    • Jeroen's elm/parser Ellie
    • "It's not hacking if you have tests."

    Look at elm/parser docs and resources

    • elm/parser project's semantics document describes backtrackable behavior in detail
    1 hr 5 min
  • 005: How (And When) to Publish a Package
    What is an Elm Package?
    • Elm package repository
    • Elm packages enforce SemVer for the public package API
    • The SemVer (Semantic Versioning) Spec
    • Interesting note: the SemVer spec says breaking changes only refers to the public API. But a core contributor clarifies that breaking changes can come from changes to the public contract that you intend users to depend on. See this GitHub thread.
    • list-extra package
    • dict-extra package
    • Minimize dependencies in your package to make it easier for users to manage their dependencies
    • "Vendoring" elm packages (using a local copy instead of doing elm install author/package-name) can be useful in some cases to remove a dependency from your package
    Should you publish a package?
    • The Elm package ecosystem has a high signal to noise ratio
    • Elm packages always start at version 1.0.0
    • SemVer has different semantics before 1.0.0 (patch releases can be breaking before 1) - see SemVer spec item 4

    Major version zero (0.y.z) is for initial development. Anything MAY change at any time. The public API SHOULD NOT be considered stable.

    • Elm package philosophy is to do an alpha phase before publishing package
    Keep yourself honest about solving meaningful problems
    • Start by asking "What problem are you solving? Who are you solving it for?"

    • Scratch your own itch

    • elm-graphql

    • servant-elm (for Haskell servant)

    • Keep yourself honest about solving problems by starting with an examples/ folder

    • Early elm-graphql commits started with examples before anything else

    • Write meaningful test cases with elm-test

    • elm-verify-examples

    • Have a clear vision

    • Ask people for feedback

    • Let ease of explanation guide you to refine core concepts

    Make it easy for people to understand your package goals and philosophy
    • Include code examples in readme and docs to make it easier for people to get started
    • elm-review live stream video
    • Use meaningful examples solving concrete problems (images/screenshots are good, too)
    • Richard Feldman's Exploring elm-spa-example talk
    • Luke's elm-http-builder package
    • elm-spa-example's custom http request builder module
    • Instead of writing a package, in some cases it could make sense to publish a blog post to share a pattern
    Porting libraries vs. Coming Up With an Idiomatic Solution for Elm
    • Instead of moment js ported to Elm, have an API built for a typed context
    • Ryan's date-format package
    How to design an Elm package API
    • Define your constraints/guarantees, make impossible states impossible
    • Charlie Koster's Advanced Types in Elm blog post series
    • Avoid exposing internals of your data
    • Elm Radio episode 002: Intro to Opaque Types
    Pay attention to how other packages solve problems
    • Richard Feldman's talk The Design Evolution of elm-css and elm-test
    • Brian Hicks' talk Let's publish nice packages
    • Look at prior art, including in other ecosystems
    • Look at github issues and blog posts from projects in other ecosystems
    Pick your constraints instead of trying to solve every problem
    • Helps you choose between tradeoffs
    • Having clear project goals explicitly in your Readme makes it easier to discuss tradeoffs with users and set expectations
    • Idiomatic elm package guide has lots of info on basic mechanics and best practices for publishing Elm packages
    The mechanics of publishing an elm package
    • elm make --docs docs.json will tell you if you're missing docs or if there are documentation validation errors
    • elm-doc-preview
    • Can use elm-doc-preview site to share documentation of branches, or packages that haven't been published yet
    • Set up a CI
    • Dillon's CI script for dillonkearns/elm-markdown package
    • Dillon's elm-publish-action GitHub Action will publish package versions when you increment the version in your elm.json - nice because it runs CI checks before finalizing a new package release
    • elm publish will walk you through the steps you need before publishing the first version of your Elm package
    • #packages channel on the Elm slack shows a feed of packages as they're published
    • #api-design channel on the Elm slack is a good place to ask for feedback on your API design and package idea
    Continue the Conversation

    Share your package ideas with us @elmradiopodcast on Twitter!

    51 min
  • 004: JSON Decoders
    Basics
    • elm/json package docs
    • Elm Guide section on JSON Decoders
    • Validates that data has the expected shape. Similar to the pattern we discussed in episode 002 Intro to Opaque Types.
    Ports and Flags

    Here's an Ellie example that shows the error when you have an implicit type that your flags decode to and it's incorrect.

    Sorry Dillon... Jeroen won the trivia challenge this time 😉 It turns out that ports will throw exceptions when they are given a bad value from JavaScript, but it doesn't bring down your Elm app. Elm continues to run with an unhandled exception. Here's an Ellie example.

    Flags and ports will never throw a runtime exception in your Elm app if you always use Json.Decode.Values and Json.Encode.Values for them and handle unexpected cases. Flags and ports are the one place that Elm lets you make unsafe assumptions about JSON data.

    Benefits of Elm's Approach to JSON
    • Bad data won't end up deep in your application logic where it's hard to debug (and discover in the first place)
    • Decouples serialization format from your Elm data types
    • You can do data transformations locally as you build up your decoder, rather than passing your giant data structure through a single transform function
    Decoding Into Ideal Types
    • Richard Feldman's elm-iso8601 package
    • elm/time package
    • Programming by intention
    • Json.Decode.succeed is helpful for stubbing out data
    • Dillon's Incremental Type Driven Design talk at elm Europe
    • Json.Decode.fail lets you validate data and fail your whole decoder if there’s a problem
    • Parse, don’t validate blog post by Alexis King
    • Dillon's elm-cli-options-parser package
    • Json.Decode.maybe docs

    Note about Decode.maybe. It can be unsafe to use this function because it can cover up failures.

    Json.Decode.maybe will cover up some cases that you may not have intended to. For example, if an API returns a float we would suddenly get Nothing back, but we probably want a decoding failure here:

    import Json.Decode as Decode
    """ {"temperatureInF": 86} """ |> Decode.decodeString (Decode.maybe (Decode.field "temperatureInF" Decode.int))
    --> Ok (Just 86)
    """ {"temperatureInF": 86.14} """ |> Decode.decodeString (Decode.maybe (Decode.field "temperatureInF" Decode.int))
    --> Ok Nothing

    Json.Decode.Extra.optionalNullableField might have more intuitive and desirable behavior for these cases.

    Thank you to lydell for the tip! See the discussion in this discourse thread.

    Learning resource
    • Brian Hicks' book The JSON Survival Kit
    Joël Quenneville’s Blog Posts About JSON Decoders
    • Getting Unstuck with Elm JSON Decoders
    • 5 Common JSON Decoders
    • Elm's Universal Pattern
    Guaranteeing that json is valid before runtime
    • elm-graphql package
    • The basics of GraphQL
    • Dillon's Types Without Borders Elm Conf talk
    • Elm Radio 001 Getting Started with elm-pages
    • elm-pages StaticHttp API docs
    • Kris Jenkins' elm-export tool for Haskell types to Elm.
    • Mario Rogic's Evergreen Elm elm Europe talk
    Autogenerating json decoders
    • json-to-elm tool - generates Elm decoders from raw JSON values
    • intellij-elm JSON decoder generator
    Organizing your decoders
    • Evan Czaplicki's elm Europe keynote The life of a file
    • Evan's experience report on implicit decoding in Haskell
    Getting Started
    • Understand Json.Decode.map
    • Understand record type aliases - the function that comes from defining type alias Album = { ... }

    Submit your question to Elm Radio!

    58 min
  • 002: Intro to Opaque Types
    Opaque Types

    Some patterns

    • Runtime validations - conditionally return type, wrapped in Result or Maybe
    • Guarantee constraints through the exposed API of the module (like PositiveInteger or AuthToken examples)
    Package-Opaque Modules

    Example - the Element type in elm-ui.
    Definition of the Element type alias

    elm-ui's elm.json file does not expose the internal module where the real Element type is defined.

    Example from elm-graphql codebase - CamelCaseName opaque type

    40 min
  • 001: Getting started with elm-pages

    elm-pages hydrates into a full Elm app. It solves similar problems to what GatsbyJS solves in the ReactJS ecosystem.

    Static site generators with JS-free output

    https://korban.net/elm/elmstatic/
    https://jekyllrb.com/
    Eleventy

    Meta Tags

    Open Graph tags

    Asset management with elm-pages (CSS vs. SASS,etc.)

    Github issue discussing using the Unix Toolchain Philosophy in the context of keeping elm-pages focused on primitive assets for elm apps

    Compared to extending the Gatsby webpack config

    SOLID Open-Closed Principle

    elm-pages showcase

    Chandu's art showcase (built with elm-pages) - https://tennety.art/

    Headless CMSes vs. monolothic site providers

    https://www.sanity.io/
    contentful.com
    https://airtable.com/
    netlifycms.org

    CDN hosting provider Netlify

    Static Site Generators and The JAMstack

    https://jekyllrb.com/ - static site builder in Ruby - perhaps the first static site generator?
    Eleventy - spritual successor to Jekyll - but more flexible
    More info on what exactly is the JAMstack?

    Getting started with elm-pages

    elm-pages-starter repo

    elm-pages vs. elm/browser

    Pages.Platform.application

    The elm-pages StaticHttp API

    StaticHttp Docs (there's a description of when and why you would use this compared to elm/http)

    elm-pages.com blog post A is for API - talks about StaticHttp and its lifecycle, including some example code.

    Core Concepts
    • SEO - elm-pages SEO API docs
    • Secrets - docs
    • Section in StaticHttp blog post about how you don't use Msgs for your StaticHttp data
    • generateFiles hook

    Incremental Elm Live - Twitch streaming series

    Where to learn more
    • elm-pages.com
    • Join the Elm slack and say hello in the elm-pages channel!
    52 min

About Elm Radio

From the publisher's feed

Tune in to the tools and techniques in the Elm ecosystem.