---
title: Who is empowered by your API design?
teaser: 'Analysing API design through lens of skill floors and ceilings can help us
  think about the impact of adding a feature.

  '
tags: design,web,f#
author: Joël Quenneville
published_on: 2021-10-07
---

A [recent discussion][1] about introducing typeclasses to F# resulted in this
comment:

> Adding type-level programming of any kind can lead to communities where the
> most empowered programmers are those with deep expertise in certain kinds of
> highly abstract mathematics (e.g. category theory). Programmers uninterested
> in this kind of thing are disempowered. I don't want F# to be the kind of
> language where the most empowered person in the discord chat is the category
> theorist.
>
> -- Don Syme, designer of F#

Don brings up a fascinating question when it comes to language and API design:
**what kind of user do you most want to empower?**

## A mental model from gaming

In gaming, MOBA (multiplayer online battle arena) players have a mental
framework for describing just what kind of player is empowered by different
characters. This framework describes all characters in terms of two statistics:
their [skill floor and their skill ceiling][2].

A character's **skill floor** is the minimum level of skill needed to be
effective with a character. A character's **skill ceiling** is the level at
which getting more skillful doesn't really bring much benefit.

<figure>
  <img
    src="https://images.thoughtbot.com/main/kQpdxk3XRParSiCzHsVq_character-skill-ranges.png"
    alt="Two continuum diagrams, one above each other. The top one is labeled 'AoE character' and shows a narrow highlighted zone towards the left of the spectrum. The second is labeled 'Skillshot character' and shows a broader highlighted zone shifted towards the right side of the spectrum."
  />
  <figcaption>Skill ranges of different character types</figcaption>
</figure>

Consider a character whose abilities are mostly single button press, area of
effect (AoE). These are hard to miss and don't require much coordination. This
character has a low skill floor because a player with relatively low skill can
still be effective with it. It also has a low skill ceiling since an experienced
player isn't going to be _that_ much better than a newer one.

Now contrast with a character whose abilities require skillshots and precisely
timed combos. This character has a high skill floor because the character is
hard to play for newer players. It also has a high skill ceiling because players
with higher skill can get a lot more value out of the character.

Finally, it's interesting to think about a character's **range**. Characters
with a narrow range (e.g. both low skill floor and low skill ceiling) are
usually designed for a particular player type. Characters with a broader range
are designed to be useful to players with a more diverse levels of skill.

## Applying the framework to `F#`

This mental model isn't just useful when thinking about the design of MOBA
characters. It can be used to [analyse games as a whole][3]. Going beyond that,
we can use it to think about our own API designs.

In the F# example above, introducing typeclasses would raise the skill ceiling.
Experienced devs (and category theorists in particular) now get more value out
of their skill. However, introducing the feature will also _raise the skill
floor_. This means the language will be less accessible to developers with less
experience.

The changes in these two boundaries won't always move in tandem. A feature that
raises the skill ceiling slightly might move up the skill floor by a lot,
resulting in a narrower range than before. Narrow ranges aren't necessarily bad
per-se but they should definitely be centered on your core audience.

<figure>
  <img
    src="https://images.thoughtbot.com/main/4viBey1Q7i70ZRidzahW_f-sharp-skill-ranges.png"
    alt="Two continuum diagrams, one above each other. The top one is labeled 'F# currently' and shows a wide highlighted zone towards the middle of the spectrum. The second is labeled 'F# with typeclasses' and shows a narrower highlighted zone shifted towards the right side of the spectrum."
  />
  <figcaption>Artist's rendition of how adding typeclasses might affect F#'s skill ranges</figcaption>
</figure>

## Thinking about our own API designs

**All new features impose a cost on your API**. Not just to develop or
maintain, but on your design as a whole by shifting the skill floor and ceiling
boundaries. Most commonly, new features will make it harder for inexperienced
users to use your product or tool.

Consider a command-line tool like `tar`. It provides many flags to customize its
behavior. This makes it a more powerful tool, but it also makes it [notorious
for no one being able to remember how to use it][4].

Designing a tool with broad range, one that has both a low skill floor _and_ a
high skill ceiling is incredibly difficult, sometimes even impossible. Moving
one boundary usually also moves the other in some way.

## Who are you designing for?

Don asks a great question: "_who should my design focus on empowering?_". A good
design targets a particular audience. A system designed for beginners will often
be quite different from a system designed for experts.

In F#'s case, it looks like Don wants to focus on empowering users more in the
middle of the skill range. This means passing on a useful advanced feature that
would disempower his core audience.

[1]: https://github.com/fsharp/fslang-suggestions/issues/243#issuecomment-916079347
[2]: https://www.youtube.com/watch?v=kspilSv1W3Q
[3]: https://kionay.medium.com/skill-floor-skill-ceiling-441c559363ab
[4]: https://xkcd.com/1168/
