Skip to content

Commit d329193

Browse files
committed
Fixed formatting, made language changes H2
1 parent 0c1ede7 commit d329193

File tree

1 file changed

+33
-31
lines changed

1 file changed

+33
-31
lines changed

docs/fsharp/whats-new/fsharp-9.md

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,7 @@ F# 9 introduces a range of enhancements that make your programs safer, more resi
1111

1212
You can download the latest .NET SDK from the [.NET downloads page](https://dotnet.microsoft.com/download).
1313

14-
## F# language changes
15-
16-
This section describes updates to the language itself, changes you will notice when writing or reading F# code.
17-
18-
### Nullable reference types
14+
## Nullable reference types
1915

2016
Although F# is designed to avoid `null`, it can creep in when interfacing with .NET libraries written in C#. F# now provides a type-safe way to deal with reference types that can have `null` as a valid value.
2117

@@ -57,7 +53,7 @@ let findOrNull (index: int) (list: 'T list) : 'T | null when 'T : not struct =
5753
| None -> null
5854
```
5955

60-
### Discriminated union `.Is*` properties
56+
## Discriminated union `.Is*` properties
6157

6258
Discriminated unions now have auto-generated properties for each case, allowing you to check if a value is of a particular case. For example, for the following type:
6359

@@ -85,7 +81,7 @@ let canSendEmailTo person =
8581
person.contact.IsEmail
8682
```
8783

88-
### Partial active patterns can return `bool` instead of `unit option`
84+
## Partial active patterns can return `bool` instead of `unit option`
8985

9086
Previously, partial active patterns returned `Some ()` to indicate a match and `None` otherwise. Now, they can also return `bool`.
9187

@@ -113,7 +109,7 @@ let (|CaseInsensitive|_|) (pattern: string) (value: string) =
113109
String.Equals(value, pattern, StringComparison.OrdinalIgnoreCase)
114110
```
115111

116-
### Prefer extension methods to intrinsic properties when arguments are provided
112+
## Prefer extension methods to intrinsic properties when arguments are provided
117113

118114
To align with a pattern seen in some .NET libraries, where extension methods are defined with the same names as intrinsic properties of a type, F# now resolves these extension methods instead of failing the type check.
119115

@@ -123,54 +119,60 @@ Example:
123119
type Foo() =
124120
member val X : int = 0 with get, set
125121
126-
[&ltExtension>]
122+
[&ltExtension>]
127123
type FooExt =
128-
[&ltExtension>]
124+
[&ltExtension>]
129125
static member X (f: Foo, i: int) = f.X <- i; f
130126
131127
let f = Foo()
132128
133129
f.X(1) // We can now call the extension method to set the property and chain further calls
134130
```
135131

136-
### Support for empty-bodied computation expressions
132+
## Support for empty-bodied computation expressions
137133

138134
F# now supports empty [computation expressions](../language-reference/computation-expressions.md).
139135

140-
<pre class="language-fsharp"><code>let xs = seq { } // Empty sequence```
136+
```fsharp
137+
let xs = seq { } // Empty sequence
138+
```
141139

142140
```fsharp
143141
let html =
144142
div {
145143
p { "Some content." }
146144
p { } // Empty paragraph
147-
}```
145+
}
146+
```
148147

149148
Writing an empty computation expression will result in a call to the CE builder's `Zero` method.
150149

151150
This is a more natural syntax compared to the previously available `builder { () }`.
152151

153-
### Hash directives are allowed to take non-string arguments
152+
## Hash directives are allowed to take non-string arguments
154153

155154
Hash directives for the compiler previously only allowed string arguments passed in quotes. Now, they can take any type of argument.
156155

157156
Previously, you had:
158157
```fsharp
159158
#nowarn "0070"
160-
#time "on"```
159+
#time "on"
160+
```
161161

162162
Now, you can write:
163163
```fsharp
164164
#nowarn 0070
165-
#time on```
165+
#time on
166+
```
166167

167168
This also ties into the next two changes.
168169

169-
### Extended #help directive in fsi to show documentation in the REPL
170+
## Extended #help directive in fsi to show documentation in the REPL
170171

171172
The `#help` directive in F# Interactive now shows documentation for a given object or function, which you can now pass without quotes.
172173

173-
<pre><code>&gt; #help List.map;;
174+
```
175+
> #help List.map;;
174176
175177
Description:
176178
Builds a new collection whose elements are the results of applying the given function
@@ -192,7 +194,7 @@ Full name: Microsoft.FSharp.Collections.ListModule.map
192194
Assembly: FSharp.Core.dll
193195
```
194196

195-
### Allow #nowarn to support the FS prefix on error codes to disable warnings
197+
## Allow #nowarn to support the FS prefix on error codes to disable warnings
196198

197199
Previously, when you wanted to disable a warning and wrote `#nowarn "FS0057"`, you would get an `Invalid warning number 'FS0057'`. Even though the warning number is correct, it just wasn't supposed to have the `FS` prefix.
198200

@@ -211,30 +213,30 @@ All of these will now work:
211213

212214
It's a good idea to use the same style throughout your project.
213215

214-
### Warning about TailCall attribute on non-rec functions or let-bound values
216+
## Warning about TailCall attribute on non-rec functions or let-bound values
215217

216218
F# now emits a warning when you put the `[<TailCall>]` attribute somewhere it doesn't belong. While it has no effect on what the code does, it could confuse someone reading it.
217219

218220
For example, these usages will now emit a warning:
219221
```fsharp
220-
[&lt;TailCall&gt;]
222+
[<TailCall>]
221223
let someNonRecFun x = x + x
222224
223-
[&lt;TailCall&gt;]
225+
[<TailCall>]
224226
let someX = 23
225227
226-
[&lt;TailCall&gt;]
228+
[<TailCall>]
227229
let rec someRecLetBoundValue = nameof(someRecLetBoundValue)
228230
```
229231

230-
### Enforce attribute targets
232+
## Enforce attribute targets
231233

232234
The compiler now correctly enforces the `AttributeTargets` on let values, functions, union case declarations, implicit constructors, structs, and classes. This can prevent some hard-to-notice bugs, such as forgetting to add the unit argument to an Xunit test.
233235

234236
Previously, you could write:
235237

236238
```fsharp
237-
[&lt;Fact&gt;]
239+
[<Fact>]
238240
let ``this test always fails`` =
239241
Assert.True(false)
240242
```
@@ -303,7 +305,7 @@ This constructor makes it easier to create a custom operation for a computation
303305

304306
```fsharp
305307
type FooBuilder() =
306-
[&lt;CustomOperation&gt;] // Previously had to be [&lt;CustomOperation("bar")&gt;]
308+
[<CustomOperation>] // Previously had to be [<CustomOperation("bar")>]
307309
member _.bar(state) = state
308310
```
309311

@@ -314,13 +316,13 @@ When using F# lists and sets from C#, you can now use collection expressions to
314316
Instead of:
315317

316318
```csharp
317-
FSharpSet&lt;int&gt; mySet = SetModule.FromArray([1, 2, 3]);
319+
FSharpSet<int> mySet = SetModule.FromArray([1, 2, 3]);
318320
```
319321

320322
You can now write:
321323

322324
```csharp
323-
FSharpSet&lt;int&gt; mySet = [ 1, 2, 3 ];
325+
FSharpSet<int> mySet = [ 1, 2, 3 ];
324326
```
325327

326328
Collection expressions make it easier to use the F# immutable collections from C#. You might want to use the F# collections when you need their structural equality, which <xref:System.Collections.Immutable> collections don't have.
@@ -356,8 +358,8 @@ Now, there is an opt-in fix for this behavior available via the `--realsig+` com
356358

357359
```xml
358360
<PropertyGroup>
359-
&lt;OtherFlags&gt;--realsig+&lt;/OtherFlags&gt;
360-
&lt;/PropertyGroup&gt;
361+
<OtherFlags>--realsig+</OtherFlags>
362+
</PropertyGroup>
361363
```
362364

363365
## Performance improvements
@@ -369,7 +371,7 @@ Equality checks are now faster and allocate less memory.
369371
For example:
370372

371373
```fsharp
372-
[&lt;Struct&gt;]
374+
[<Struct>]
373375
type MyId =
374376
val Id: int
375377
new id = { Id = id }

0 commit comments

Comments
 (0)