Tyler A. Young’s Blog

Hi, I’m Tyler.

I’m a product-focused Elixir developer building my own software service and doing contract development on the side.

22 May 2022

TIL you can have type predicates in TypeScript

TIL in TypeScript you can have type predicates, where the return value of your function indicate the type of an argument.

Instead of:

function isUserRole(role: string): boolean { }

…you can do:

function isUserRole(role: string): role is UserRole { }

That can be used to inform the type system of the value’s type, letting you do this:

const validatedRole =
  isUserRole(roleInput) ?
    roleInput :
    undefined;

…and use validatedRole as an optional UserRole rather than just a string.

02 May 2022

Translating User Interfaces Is Way Harder Than You Think (And You’re Probably Doing It Wrong)

Say you want to build a tool to handle translating a user interface. Whether in a native app or on the web, this seems like it should be pretty simple. You'll take each string in your UI, run it through a function that looks the string up in the user's preferred language, and you're done. Continue reading…
25 April 2022

Don’t Write Exploding Streams

Suppose you have a Stream of values that you want to insert into the database. You can do this easily in many modern programming languages, but here’s what it might look like in Elixir:

Continue reading…
14 April 2022

Refactoring Toward Algorithms in Elixir

Algorithms give a name to a kind of data transformation. They’re the building blocks of programs, and they’re fractal: a program as a whole can be seen as an algorithm, and it’s made up of many smaller algorithms; those algorithms are in turn made up of smaller ones.

Continue reading…
12 April 2022

Taking Hashrocket’s “Ultimate Elixir CI” to the Next Level

Over on the Felt blog I wrote about how we pushed our continuous integration (CI) system for Elixir to enable devs to be more productive. The examples are all in GitHub Actions, but you can probably translate it to whatever CI system you’re using.

The highlights:

  1. Deploy a staging environment (a complete reproduction of our production environment) for every PR, and update it as new commits get added
  2. Run most CI jobs in parallel so that you get the fastest feedback, and make the jobs never “fail fast,” so you’ll know all the things you need to fix on the first run
  3. Refactor boilerplate for setting up and caching the project into shared “composite” actions
  4. Clear the build cache when a human asks for a retry, neatly resolving mistrust of build caches
  5. Report code coverage in the GitHub PR description, and update it as new commits are added
  6. Run as much static analysis as we can
  7. Use Dependabot to get PRs to update our dependencies

Read the full post

Jump to the sample project

12 April 2022

TIL about the differences between Elixir's boolean operators

TIL the difference between Elixir’s “relaxed”/symbolic Boolean operators (||, &&) and their “strict”/word correspondents (and, or).

  1. Relaxed versions do type coercion; strict require exactly true or false
  2. Strict versions are allowed in guards

Relevant docs:

28 March 2022

TIL: Elixir doctests support import: true

TIL Elixir’s doctests support an import: true flag so that you don’t have to write out the full module name in your doctests.

Super useful! I can’t tell you how many times my doctests have all started App.Context.Module.Submodule.func(...)!

16 March 2022

Write More Pure Functions

Let me begin by saying: you probably shouldn’t read this. You have a limited amount of time, and you’re probably better served reading John Hughes’ seminal Why Functional Programming Matters. But this is my perspective on why pure functions are important—the stuff I feel viscerally day to day, not academically. It’s my exhortation to think about this stuff constantly in the course of programming, even in languages that don’t strictly enforce it—maybe especially in those languages.

Continue reading…
17 February 2022

TIL about default parameters in Elixir

TIL default parameters in Elixir that are function calls get re-evaluated every time you call the function.

This is how you’d hope this sort of thing works, but I think years of being burned by Python made me mistrust it.

Somehow I missed this my first time through the outstanding Testing Elixir by Andrea Leopardi and Jeffrey Matthias. Every time I open that book up I get something new and valuable.

This is a godsend for testability!

16 February 2022

TIL the difference between Elixir URI's parse/1 and new/1

TIL the difference between URI​.new/1 and URI.parse/1 in Elixir 1.13.

  • new/1 does a bunch of validation to ensure the URI is within spec
  • parse/1 does no validation at all

Lots of URIs in the wild are technically invalid, but web browsers handle them just fine.

Obviously URI.parse/1 is somewhat unsafe, so in our app we’ve combined it with some hand-rolled validation to ensure the URI is vaguely URL-like:

  • It has a scheme of HTTP or HTTPS
  • The authority contains a plausible TLD
08 January 2022

TIL about the Elixir typedstruct package

TIL about the Elixir typed_struct package.

It allows you to specify defaults, enforced keys, typespecs, and typedocs all in one block. So much cleaner! 😍

08 January 2022

What You Need to Know as a New Team Lead

So you’re becoming a software team lead. If this is your first foray into the management track (as it was for me), you probably have a lot of questions about what you’re, um, supposed to do. This is a brain dump of some of the stuff a new team lead might need to know—things I wish I’d known when I started.

Continue reading…
02 December 2021

Shooting Yourself in the Foot with GenServers

Elixir’s GenServers are great. Their fault tolerance makes them a natural choice for situations where you need to store some state over time in a resilient way. They’re not without their gotchas, though. In particular, it’s quite easy to fall into traps with respect to scheduling work within the GenServer’s process.

Continue reading…
15 November 2021

TIL about Elixir's System.unique_integer/1

TIL about System.unique_integer/1, which guarantees you an integer that it hasn’t (yet) handed out in the current runtime. 😍

Pass in [:positive, :monotonic] as the argument to get a unique, increasing number—useful for ordering in tests to know at a glance that one entity was created before another:

user1 =
  AccountsFixtures.user_fixture(%{
    email: "u#{System.unique_integer([:positive, :monotonic])}@example.com"
  })

user2 =
  AccountsFixtures.user_fixture(%{
    email: "u#{System.unique_integer([:positive, :monotonic])}@example.com"
  })

(I’d started writing my own GenServer to do this, but gave up quickly trying to handle a bunch of edge cases. 😅)

06 November 2021

Enum.slide/3 is coming in Elixir 1.13

Earlier this week, José Valim merged my first PR to the Elixir standard library. (Woohoo!) I figured it was worth creating a blog post to explain what a “slide” is, and why it might be valuable.

Continue reading…
01 November 2021

TIL Elixir always runs tests within a test module synchronously

TIL I totally misunderstood what ExUnit’s async: true does.

I thought it made ExUnit run the tests in this module/file concurrently.

In fact, it always run tests in this module synchronously, but :async schedules them in parallel with tests in other files.

Imagine that… reading the docs teaches you things. It’s right there at the top. 😅

:async - configures tests in this module to run concurrently with tests in other modules. Tests in the same module never run concurrently. It should be enabled only if tests do not change any global state. Defaults to false.

12 September 2021

Architecting GenServers for Testability in Elixir

[Post-publication update: This post turned into a conference talk at ElixirConf 2021, embedded here for posterity.]

Continue reading…