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.

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…
17 August 2021

TIL Elixir's || supports nil fallback

TIL Elixir can do nil || something (evaluating to something) just like the Javascript trick:

default_value = 123
my_value = my_map[:some_field] || default_value

If :some_field is present & non-nil, my_value will be assigned the value from the map; otherwise it will fall back to default_value.

(Note that this works with the || operator, but not or—if this is as surprising to you as it was to me, see TIL about the differences between Elixir’s boolean operators. 😅)

12 July 2021

TIL Elixir's for comprehension supports filtering

TIL about the filtering support in Elixir’s for comprehensions (“don’t call it a loop”):

# Create a record every 5 seconds for a day
for seconds <- 0..(60 * 60 * 24),
    rem(seconds, 5) == 0 do
  create_record_at_offset(seconds)
end

For more on the amazing superpowers of the for comprehension, see Mitch Hanberg’s Comprehensive Guide to Elixir’s List Comprehension.

26 June 2021

TIL: Elixir's match?/2 turns a match result into a predicate

TIL about Elixir’s Kernel.match?/2.

iex> list = [a: 1, b: 2, a: 3]
iex> Enum.filter(list, &match?({:a, _}, &1))
[a: 1, a: 3]

So many times I’ve hacked around not knowing about this. 🤯

Where this gets really useful is in tests where you want to assert part of the shape of a map. For instance:

assert Enum.count(
         results,
         &match?(%{id: ^my_id, inserted_at: ^time}, &1)
       ) == 1
03 March 2021

Iterating Over a Generic Sequence in Swift

Here’s a goofy bit of generic programming I do all the time in Swift—ironically, it’s one thing C++ makes easier than Swift!

Continue reading…
19 January 2021

A look inside X-Plane’s massive multiplayer server

This morning I published a blog post on the X-Plane Developer blog titled “Have You Heard the Good News About Elixir?.” It’s a look at the requirements and goals that drove me to choose Elixir for X-Plane’s massive multiplayer game server, with a look at both the pros and cons of that choice.

This post (and the feature itself!) was a long time in coming. It’s cool to be able to talk about it publicly.

On a related note, we open-sourced the Elixir implementation of the networking protocol we use for MMO. The README there gives a pretty good overview of the architecture of our MMO server—long story short, we go to great lengths to minimize shared state.

This won’t be of use to many people, but I do hope it’s useful to the next poor soul who needs to build a server around RakNet. ☺️

13 December 2020

Missing SwiftUI Preview Window in Xcode

This is no doubt obvious if you’ve dutifully watched all the WWDC sessions on SwiftUI, but if you’re like me and just diving in and hacking the hell out of it, you might be baffled that the much-renowned preview pane isn’t showing up when you create your SwiftUI View.

Continue reading…
13 December 2020

Creating a SwiftUI Window in an Objective-C AppKit App

I’ve been “rehabbing” a legacy Objective-C app (the Unbound photo browser), trying to make up for a couple years of neglect, and I wanted to start building new views in SwiftUI. There are a lot of good tutorials online for hosting SwiftUI views in UIKit apps (either iOS/iPadOs or macOS + Catalyst), but not much on how to do this for Mac and AppKit… and especially not when you’re still mostly Obj-C!

Continue reading…
20 August 2020

Warning: std::numeric_limits::min() > 0

Here’s a baffling design choice (which I’m reliably informed C++ inherited from older C limits.h).

std::numeric_limits<int>::min() is roughly -2 billion (assuming 32 bit ints, etc.).

But std::numeric_limits<float>::min() is smallest positive floating point value… something like +0.00000000000000000000000000000000000001.

CppReference warns this is the case for all floating point types with denormalization (thus it applies to double and long double as well on vaguely x86-like platforms).

What you’re probably looking for (the actual opposite of std::numeric_limits<float>::max()) is std::numeric_limits::lowest().

20 August 2020

Default Capacity & Growth Rate of C++ std::vector

If you’re creating a lot of small vectors in C++, you should probably consider using a small-size optimized vector instead. But, if you can’t do that for some reason, you might wonder if there is any win to be had by reserve()ing a small size in advance.

Continue reading…
02 July 2020

Warning: __attribute__((const)) does not mean function purity

Clang and GCC (and others) support function attributes __attribute__((const)) and __attribute__((pure)). These had always been explained to me thus:

Continue reading…
05 February 2020

The fastest way to iterate a Map’s values in Elixir

Say you have an Elixir Map. What’s the fastest way to iterate the values?

Continue reading…
27 May 2019

Go ahead, call yourself a software engineer.

Ian Bogost writes for The Atlantic that programmers should stop calling themselves engineers. It’s a good article, and he’s right about software devs cheapening the word “engineer” with their Wild West practices. This is a sentiment that’s been echoed for years. Continue reading…
08 May 2019

No Size Fits All

The most recent episode of CppCast featuring David Sankel ends with a good reminder:

There is no One Software Methodology to Rule Them All, because we work in different contexts.

Your environment matters. If you’re a startup whose principle threat is obscurity, “move fast and break things” is good advice. If you’re an avionics developer, not so much.

When you push your way of doing things—even when it works really well for you!—as a universal panacea, something everyone everywhere should adopt, you’re missing the fact that it works in a particular set of circumstances… a particular time, with a particular team, with a particular set of goals, on a codebase with a particular history.

29 January 2019

Benchmarks of Cache-Friendly Data Structures in C++

Suppose you’re a savvy C++ developer who knows all about data-oriented design and the importance of optimizing for cache locality if you want a prayer of running fast on modern hardware. Now suppose you want to go beyond basics—”just use std::vector” is a good starting point, but you want more!

Continue reading…
23 January 2019

Data Normalization Matters

In describing for a coworker a place where two different subsystems have their own (hopefully identical!) ideas about the state of the UI, I was reminded of this quote from the database world:

Between any two copies of the same data, there will be differences.

I’ve tried unsuccessfully to find attribution for this… if you know where it comes from, give me a shout!