Impossible or Illegal States
“Make Impossible States Impossible”. This was a phrase I heard when I was living in the Elm world (for two years 😍). Richard Feldman had a talk with the same title. That was my first exposure to the concept when I stepped into the beautiful world of Elm (it’s even part of the Elm patterns site).
But I had never heard of any other phrases akin to this. Until today.
I came across a subreddit post on r/functionalprogramming about an even older version of this term by Yaron Minsky: “Make illegal states unrepresentable”.
This concept works really well with strictly typed languages that have [sum types]. When paired with a strong compiler, we can catch errors at compile-time.
Example in Elm
Imagine you’re building a form that can be in different states: loading, success with data, or error. In a traditional approach, you might have separate boolean flags:
-- BAD: Multiple boolean flags can create impossible states
type alias BadFormState =
{ isLoading : Bool
, data : Maybe UserData
, error : Maybe String
}
-- This creates impossible states like:
-- { isLoading = True, data = Just userData, error = Just "error" }
-- { isLoading = False, data = Nothing, error = Nothing }
Instead, use a custom type to make impossible states unrepresentable:
-- GOOD: Sum type eliminates impossible states
type FormState
= Loading
| Success UserData
| Error String
-- Now you can only have valid states:
-- Loading (no data, no error)
-- Success userData (has data, no error)
-- Error "message" (no data, has error)
viewForm : FormState -> Html msg
viewForm state =
case state of
Loading ->
text "Loading..."
Success userData ->
viewUserData userData
Error errorMessage ->
div [ class "error" ] [ text errorMessage ]