Skip to content

Commit 0b59ee2

Browse files
authored
RequireQualifiedAccess section (#39)
1 parent a6c3ea1 commit 0b59ee2

1 file changed

Lines changed: 25 additions & 7 deletions

File tree

docs/fsharp-cheatsheet.md

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,7 +1117,7 @@ module MyNamespace.SubNamespace.Functions
11171117

11181118
<div id="open-and-autoopen"></div>
11191119

1120-
## Open and AutoOpen
1120+
## Open
11211121
The `open` keyword can be used on `module`, `namespace`, and `type`.
11221122

11231123
```fsharp
@@ -1139,7 +1139,26 @@ open type System.Text.RegularExpressions.Regex // type
11391139
let isHttp url = IsMatch("^https?:", url) // Regex.IsMatch directly accessible
11401140
```
11411141

1142-
Available to `module` declarations only, is the `AutoOpen` attribute, which alleviates the need for an `open`.
1142+
### RequireQualifiedAccess Attribute
1143+
1144+
This attribute can be used on modules, records, and discriminated unions to avoid namespace collisions and unexpected "shadowing". It can also make your code more explicit and readable.
1145+
1146+
```fsharp
1147+
[<RequireQualifiedAccess>]
1148+
module Calcs =
1149+
let add x y = x + y
1150+
let subtract x y = x - y
1151+
1152+
open Calcs // Error! Although you may open the containing namespace, if allowed.
1153+
1154+
// As you can't open the module, you must use qualified names for module members.
1155+
let sum = Calcs.add 5 3 // Works
1156+
let diff = subtract 5 3 // Error!
1157+
```
1158+
1159+
### AutoOpen Attribute
1160+
1161+
Applicable to `module` declarations only, the `AutoOpen` attribute alleviates the need for an `open`.
11431162

11441163
```fsharp
11451164
[<AutoOpen>]
@@ -1151,11 +1170,10 @@ module Groceries =
11511170
let fruit = Banana
11521171
```
11531172

1154-
*However*, `AutoOpen` should be used cautiously. When an `open` or `AutoOpen` is used, all declarations in the containing element
1155-
will be brought into scope. This can lead to [shadowing](https://en.wikipedia.org/wiki/Variable_shadowing); where the last
1156-
named declaration replaces all prior identically-named declarations. There is *no* error - or even a warning - in F#, when shadowing occurs.
1157-
A [coding convention (MS Learn)](https://learn.microsoft.com/en-us/dotnet/fsharp/style-guide/conventions#sort-open-statements-topologically) exists for `open`
1158-
statements to avoid pitfalls; `AutoOpen` would sidestep this.
1173+
#### Use `AutoOpen` and/or ignore `RequireQualifiedAccess` best practice with caution!
1174+
1175+
Functions with identical names from different modules will silently "shadow" each other, causing the most recently imported definition to be used instead of the one you might expect. **The compiler will _not_ warn you that this has happened.** Even if your code works, you may encounter compiler errors if the `open` order changes. A [coding convention (MS Learn)](https://learn.microsoft.com/en-us/dotnet/fsharp/style-guide/conventions#sort-open-statements-topologically) exists for `open` statements to avoid pitfalls.
1176+
11591177

11601178
## Accessibility Modifiers
11611179

0 commit comments

Comments
 (0)