fsharp / fsharp/fslang-suggestions

attribute enforcing explicit matching of DU cases

Open
#731 12 comments 5 reactions 0 assignees View on GitHub
approved-in-principle area: unions
Dominant language
No language data
Stars
373
Forks
21
PR merge metrics
No merged PRs in 30d

Description

The safety around exhaustive pattern matching is one of the strong point of F# type system,

For F# users, discarding some cases of a DU in a match is always a fine balance between future changes and state of the code using the DU.

I'm sure many F# users face situations while adding cases to the DU or reviewing / adjusting the existing matches or those to add asking self:

* should I just put a wild card?
* is this existing wild card correct?

In specific cases, it would be relevant to make usage of the wildcard discouraged more than morally, but with the tools of software engineers: the compiler.

### sample

```fsharp
type NormalDU = Normal1 | Normal2 | Normal3

[]
type StrictDU = Enforced1 | Enforced2 | Enforced3

let test normal strict =
let interesting =
match normal with
| Normal1 -> true
| _ -> false

let moreInteresting =
match strict with
| Enforced1 -> true
| _ -> false // compile error

(interesting, moreInteresting)

```

**What:**

> Case `Enforced2` has not been matched explicitly.

**Why:**

> `StrictDU` is declared with `[]` disallowing usage of wildcard in pattern matching.

**How To Fix:**

> All cases need to be matched explicitly.

**Where:**

```
| _ -> false
^
```

NB: An error is produced opposed to the warning we usually get if there is no wildcard and missing cases.

Usage in other conditional constructs is an area of investigation / suggestions, maybe usage outside `match` and `function` should lead to a new warning.

This could be refined to apply to individual cases in a later revision, if the feature is relevant and doable.

Using this attribute could lead to a design time technique, where F# user would flip the attribute on while adding cases and removing it once all code changes and tests are done or to keep only in debug build; bringing some extra confidence of having reviewed all the matches.

## Pros and Cons

The advantages of making this adjustment to F# are:
* correctness better enforced in type modeling
* express coding standards around matching / conditionals
* reinforces "compiler is helpful" feeling

The disadvantages of making this adjustment to F# are:
* the costs to integrate in compiler codebase, logic handling pattern matches is assumed to be large
* compile time will increase a bit whenever a `_` is used (many places...)
* some doubts around potential false positives or misses, pattern matching is key area, requires thourough testing
* reinforces "compiler is slow" feeling

## Extra information

Estimated cost (XS, S, M, L, XL, XXL): medium

rfc: small
compiler: medium
tests: medium-large
documentation / guidelines: medium

Related suggestions: #414

## Affidavit

* [x] This is not a breaking change to the F# language design
* [ ] I or my company would be willing to help implement and/or test this

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the sample match and function cases and review related suggestion #414. No implementation files or tests are named; define the attribute's supported scope and diagnostics, then add compiler tests for wildcard and explicit DU cases and document the behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
fsharp
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.