Skip to content

Commit 17628ab

Browse files
dsymegewarren
andauthored
Apply suggestions from code review
Co-authored-by: Genevieve Warren <[email protected]>
1 parent 87532a8 commit 17628ab

File tree

9 files changed

+30
-29
lines changed

9 files changed

+30
-29
lines changed

docs/fsharp/language-reference/casting-and-conversions.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ Integer literals for int64 may be used:
146146
Tensor.Create([100L; 10L; 10L])
147147
```
148148

149-
or integer literals for int32:
149+
Or integer literals for int32:
150150

151151
```fsharp
152152
Tensor.Create([int64 100; int64 10; int64 10])
@@ -182,7 +182,9 @@ let partNos = purchaseOrder.Descendants("Item")
182182

183183
You can also optionally enable the warning 3390 (`/warnon:3390` or property `<WarnOn>3390</WarnOn>`) to show a warning at every point a .NET-style implicit conversion is used.
184184

185-
.NET-style `op_Implicit` conversions are also applied automatically for non-method-argument expressions in the same situations as implicit upcasts. However, when used widely or inappropriately, implicit conversions can interact poorly with type inference and lead to code that's harder to understand. For this reason these always generate warnings when used in non-argument positions.
185+
.NET-style `op_Implicit` conversions are also applied automatically for non-method-argument expressions in the same situations as implicit upcasts. However, when used widely or inappropriately, implicit conversions can interact poorly with type inference and lead to code that's harder to understand. For this reason, these always generate warnings when used in non-argument positions.
186+
187+
To show a warning at every point that a .NET-style implicit conversion is used for a non-method argument, you can enable warning 3391 (`/warnon:3391` or property `<WarnOn>3391</WarnOn>`).
186188

187189
### Summary of warnings related to conversions
188190

@@ -193,8 +195,6 @@ The following optional warnings are provided for uses of implicit conversions:
193195
* `/warnon:3390` (`op_Implicit` at method arguments)
194196
* `/warnon:3391` (`op_Implicit` at non-method arguments, on by default)
195197

196-
You may optionally enable the warning 3390 (`/warnon:3389` or property `<WarnOn>3389</WarnOn>`) to show a warning at every point implicit numeric widening is used.
197-
198198
## See also
199199

200200
- [F# Language Reference](index.md)

docs/fsharp/language-reference/computation-expressions.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -427,15 +427,15 @@ type QueryBuilder with
427427
System.Linq.Enumerable.Any (source.Source, Func<_,_>(predicate)) |> not
428428
```
429429

430-
Custom operations may be overloaded, see [F# RFC FS-1056 - Allow overloads of custom keywords in computation expressions](https://github.com/fsharp/fslang-design/blob/main/FSharp-6.0/FS-1056-allow-custom-operation-overloads.md).
430+
Custom operations can be overloaded. For more information, see [F# RFC FS-1056 - Allow overloads of custom keywords in computation expressions](https://github.com/fsharp/fslang-design/blob/main/FSharp-6.0/FS-1056-allow-custom-operation-overloads.md).
431431

432432
## Compiling computation expressions efficiently
433433

434-
F# computation expressions that suspend execution can be compiled to highly efficient state machines through careful use of a low-level feature called "resumable code". Resumable code is documented in [F# RFC FS-1087](https://github.com/fsharp/fslang-design/blob/main/FSharp-6.0/FS-1087-resumable-code.md) and used for [Task Expressions](task-expressions.md).
434+
F# computation expressions that suspend execution can be compiled to highly efficient state machines through careful use of a low-level feature called *resumable code*. Resumable code is documented in [F# RFC FS-1087](https://github.com/fsharp/fslang-design/blob/main/FSharp-6.0/FS-1087-resumable-code.md) and used for [Task Expressions](task-expressions.md).
435435

436-
F# computation expressions that are synchronous (that do no suspend execution) can alternatively be compiled to efficient state machines through the use of [inline functions](functions/inline-functions.md) including the `InlineIfLambda` attribute. Examples are given in [F# RFC FS-1098](https://github.com/fsharp/fslang-design/blob/main/FSharp-6.0/FS-1098-inline-if-lambda.md).
436+
F# computation expressions that are synchronous (that is, they don't suspend execution) can alternatively be compiled to efficient state machines through the use of [inline functions](functions/inline-functions.md) including the `InlineIfLambda` attribute. Examples are given in [F# RFC FS-1098](https://github.com/fsharp/fslang-design/blob/main/FSharp-6.0/FS-1098-inline-if-lambda.md).
437437

438-
List expressions, array expressions and sequence expressions are given special treatment by the F# compiler to ensure generation of high-performance code.
438+
List expressions, array expressions, and sequence expressions are given special treatment by the F# compiler to ensure generation of high-performance code.
439439

440440
## See also
441441

docs/fsharp/language-reference/functions/entry-point.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ ms.date: 10/29/2021
55
---
66
# Console Applications
77

8-
In this topic you learn how to structure an F# console application.
8+
In this article, you learn how to structure an F# console application.
99

1010
## Implicit Entry Point
1111

@@ -29,13 +29,13 @@ exit 100
2929

3030
## Explicit Entry Point
3131

32-
If you wish, you can use an explicit entry point. This is usually done for one or all of the following reasons:
32+
If you want, you can use an explicit entry point. This is usually done for one or all of the following reasons:
3333

3434
* You prefer to access the command-line arguments via an argument passed to a function, rather than using `System.Environment.GetCommandLineArgs()`.
3535

36-
* You wish to return an error code from via a return result, rather than using `exit`.
36+
* You want to return an error code via a return result, rather than using `exit`.
3737

38-
* You wish to unit test the code in the last file of your console application.
38+
* You want to unit test the code in the last file of your console application.
3939

4040
The following example illustrates a simple `main` function with an explicit entry point.
4141

docs/fsharp/language-reference/functions/inline-functions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ This means that the function accepts any type that supports a conversion to **fl
3535

3636
## InlineIfLambda
3737

38-
The F# compiler includes an optimizer that performs inlining of code. The `InlineIfLambda` attribute allows code to optionally indicate that, if an argument is determined to be a lambda function, then that argument should itself always be inlined at call sites. See [F# RFC FS-1098](https://github.com/fsharp/fslang-design/blob/main/FSharp-6.0/FS-1098-inline-if-lambda.md).
38+
The F# compiler includes an optimizer that performs inlining of code. The `InlineIfLambda` attribute allows code to optionally indicate that, if an argument is determined to be a lambda function, then that argument should itself always be inlined at call sites. For more information, see [F# RFC FS-1098](https://github.com/fsharp/fslang-design/blob/main/FSharp-6.0/FS-1098-inline-if-lambda.md).
3939

4040
For example, consider the following `iterateTwice` function to traverse an array:
4141

docs/fsharp/language-reference/members/indexed-properties.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ The syntax for accessing a non-default indexed property is to provide the name o
5151

5252
Regardless of which form you use, you should always use the curried form for the set method on an indexed property. For information about curried functions, see [Functions](../functions/index.md).
5353

54-
Prior to F# 6 the syntax `expr.[idx]` was used for indexing. You can activate an optional informational warning (`/warnon:3566` or property `<WarnOn>3566</WarnOn>`) to report uses of the `expr.[idx]` notation.
54+
Prior to F# 6, the syntax `expr.[idx]` was used for indexing. You can activate an optional informational warning (`/warnon:3566` or property `<WarnOn>3566</WarnOn>`) to report uses of the `expr.[idx]` notation.
5555

5656
## Example
5757

docs/fsharp/language-reference/slices.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ let unboundedEnd = fullArray[94..]
5252
printfn $"Unbounded end slice: {unboundedEnd}"
5353
```
5454

55-
Prior to F# 6, slicing used the syntax `expr.[start..finish]` with the extra `.`. You may still optionally use this syntax. See [RFC FS-1110](https://github.com/fsharp/fslang-design/blob/main/FSharp-6.0/FS-1110-index-syntax.md).
55+
Prior to F# 6, slicing used the syntax `expr.[start..finish]` with the extra `.`. If you choose, you can still use this syntax. For more information, see [RFC FS-1110](https://github.com/fsharp/fslang-design/blob/main/FSharp-6.0/FS-1110-index-syntax.md).
5656

5757
## Slicing multidimensional arrays
5858

docs/fsharp/language-reference/symbol-and-operator-reference/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ and no implementations of these operator are provided in the F# core library.
223223

224224
## Reference cell operators (deprecated)
225225

226-
The following table describes symbols related to [Reference Cells](../reference-cells.md). The use of these operators generates advisory messages as of F# 6, see [Reference cell operation advisory messages](https://github.com/fsharp/fslang-design/blob/main/FSharp-6.0/FS-1111-refcell-op-information-messages.md#summary).
226+
The following table describes symbols related to [Reference Cells](../reference-cells.md). The use of these operators generates advisory messages as of F# 6. For more information, see [Reference cell operation advisory messages](https://github.com/fsharp/fslang-design/blob/main/FSharp-6.0/FS-1111-refcell-op-information-messages.md#summary).
227227

228228
|Symbol or operator|Links|Description|
229229
|------------------|-----|-----------|

docs/fsharp/language-reference/task-expressions.md

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@ ms.date: 10/29/2021
77

88
This article describes support in F# for task expressions, which are similar to [async expressions](async-expressions.md) but allow you to author .NET tasks directly. Like async expressions, task expressions execute code asynchronously, that is, without blocking execution of other work.
99

10-
Asynchronous code is normally authored using async expressions. Using task expressions is preferred when interoperating extensively with .NET libraries that create or consume .NET tasks. Task expressions can also improve performance and improve debugging. However, task expressions come with some limitations, described below.
10+
Asynchronous code is normally authored using async expressions. Using task expressions is preferred when interoperating extensively with .NET libraries that create or consume .NET tasks. Task expressions can also improve performance and the debugging experience. However, task expressions come with some limitations, which are described later in the article.
1111

1212
## Syntax
1313

1414
```fsharp
1515
task { expression }
1616
```
1717

18-
In the previous syntax, the computation represented by `expression` is set up to run as a .NET task. The task is started immediately this code is executed and runs on the current thread until its first asynchronous operation is performed (e.g. an asynchronous sleep, asynchronous I/O or other primitive asynchronous operation). The type of the expression is `Task<'T>`, where `'T` is the type returned by the expression when the `return` keyword is used.
18+
In the previous syntax, the computation represented by `expression` is set up to run as a .NET task. The task is started immediately after this code is executed and runs on the current thread until its first asynchronous operation is performed (for example, an asynchronous sleep, asynchronous I/O, or other primitive asynchronous operation). The type of the expression is `Task<'T>`, where `'T` is the type returned by the expression when the `return` keyword is used.
1919

2020
## Binding by using let!
2121

@@ -47,7 +47,7 @@ Within task expressions, `return! expr` is used to return the result of another
4747

4848
## Control flow
4949

50-
Task expressions can include control-flow constructs `for .. in .. do`, `while .. do`, `try .. with ..`, `try .. finally ..`, `if .. then .. else`, `if .. then ..`. These may in turn include further task constructs, with the exception of the `with` and `finally` handlers, which execute synchronously. If an asynchronous `try .. finally ..` is needed you should use a `use` binding in combination with an object of type `IAsyncDisposable`.
50+
Task expressions can include the control-flow constructs `for .. in .. do`, `while .. do`, `try .. with ..`, `try .. finally ..`, `if .. then .. else`, and `if .. then ..`. These may in turn include further task constructs, with the exception of the `with` and `finally` handlers, which execute synchronously. If you need an asynchronous `try .. finally ..`, use a `use` binding in combination with an object of type `IAsyncDisposable`.
5151

5252
## `use` and `use!` bindings
5353

@@ -57,9 +57,9 @@ In addition to `let!`, you can use `use!` to perform asynchronous bindings. The
5757

5858
## Value Tasks
5959

60-
Value tasks are structs used to avoid allocations in task-based programming. A value task is an ephemeral value which is turned into a real task by using `.AsTask()`.
60+
Value tasks are structs used to avoid allocations in task-based programming. A value task is an ephemeral value that's turned into a real task by using `.AsTask()`.
6161

62-
To create a value task from a task expression, use `|> ValueTask<ReturnType>`, or `|> ValueTask`. For example:
62+
To create a value task from a task expression, use `|> ValueTask<ReturnType>` or `|> ValueTask`. For example:
6363

6464
```fsharp
6565
let makeTask() =
@@ -70,7 +70,7 @@ makeTask() |> ValueTask<int>
7070

7171
## Adding cancellation tokens and cancellation checks
7272

73-
Unlike F# async expressions, task expressions do not implicitly pass a cancellation token and doesn't implicitly perform cancellation checks. If your code requires a cancellation token, you should take the cancellation token as a parameter. For example:
73+
Unlike F# async expressions, task expressions do not implicitly pass a cancellation token and don't implicitly perform cancellation checks. If your code requires a cancellation token, you should specify the cancellation token as a parameter. For example:
7474

7575
```fsharp
7676
open System.Threading
@@ -82,21 +82,22 @@ let someTaskCode (cancellationToken: CancellationToken) =
8282
}
8383
```
8484

85-
If you intend to correctly make your code cancellable, you should very carefully check that you pass the cancellation token through to all .NET library operations that support cancellation. For example, `Stream.ReadAsync` has multiple overloads, one of which accepts a cancellation token. If you do not use this overload, that specific asynchronous read operation will not be cancellable.
85+
If you intend to correctly make your code cancellable, carefully check that you pass the cancellation token through to all .NET library operations that support cancellation. For example, `Stream.ReadAsync` has multiple overloads, one of which accepts a cancellation token. If you do not use this overload, that specific asynchronous read operation will not be cancellable.
8686

8787
## Background tasks
8888

8989
By default, .NET tasks are scheduled using <xref:System.Threading.SynchronizationContext.Current%2A?displayProperty=nameWithType> if present. This allows tasks to serve as cooperative, interleaved agents executing on a user interface thread without blocking the UI. If not present, task continuations are scheduled to the .NET thread pool.
9090

91-
In practice, it is often desirable that library code generating tasks ignores the synchronization context and instead always switches to the .NET thread pool if necessary This can be achieved using `backgroundTask { }`:
91+
In practice, it's often desirable that library code generating tasks ignores the synchronization context and instead always switches to the .NET thread pool, if necessary. This can be achieved using `backgroundTask { }`:
9292

9393
```fsharp
9494
backgroundTask { expression }
9595
```
9696

97-
A background task ignores any `SynchronizationContext.Current` in the following sense: if started on a thread with non-null `SynchronizationContext.Current`, it switches to a background thread in the thread pool using Task.Run. If started on a thread with null `SynchronizationContext.Current`, it executes on that same thread.
97+
A background task ignores any `SynchronizationContext.Current` in the following sense: if started on a thread with non-null `SynchronizationContext.Current`, it switches to a background thread in the thread pool using `Task.Run`. If started on a thread with null `SynchronizationContext.Current`, it executes on that same thread.
9898

99-
> NOTE: This means in practice that calls to `ConfigureAwait(false)` are not typically needed in F# task code. Instead, tasks that are intended to run in the background should be authored using `backgroundTask { ... }`. Any outer task binding to a background task will resynchronize to the `SynchronizationContext.Current` on completion of the background task.
99+
> [!NOTE]
100+
> In practice, this means that calls to `ConfigureAwait(false)` are not typically needed in F# task code. Instead, tasks that are intended to run in the background should be authored using `backgroundTask { ... }`. Any outer task binding to a background task will resynchronize to the `SynchronizationContext.Current` on completion of the background task.
100101
101102
## Limitations of tasks with regard to tailcalls
102103

@@ -116,7 +117,7 @@ let t = taskLoopBad 10000000
116117
t.Wait()
117118
```
118119

119-
This coding style should not be used with task expressions: this code will create a chain of 10000000 tasks and cause a `StackOverflowException`. If an asynchronous operation is added on each loop invocation, the code will use essentially unbounded heap. You should consider switching this code to use an explicit loop, for example:
120+
This coding style should not be used with task expressions&mdash;it will create a chain of 10000000 tasks and cause a `StackOverflowException`. If an asynchronous operation is added on each loop invocation, the code will use an essentially unbounded heap. Consider switching this code to use an explicit loop, for example:
120121

121122
```fsharp
122123
let taskLoopGood (count: int) : Task<string> =
@@ -130,7 +131,7 @@ let t = loopBad 10000000
130131
t.Wait()
131132
```
132133

133-
If asynchronous tailcalls are required, you should use an F# async expression, which do support tailcalls. For example:
134+
If asynchronous tailcalls are required, use an F# async expression, which does support tailcalls. For example:
134135

135136
```fsharp
136137
let rec asyncLoopGood (count: int) =

docs/fsharp/language-reference/units-of-measure.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ The addition of unsigned integer types to this feature is documented in [F# RFC
114114

115115
## Pre-defined Units of Measure
116116

117-
A unit library is available in the `FSharp.Data.UnitSystems.SI` namespace. It includes SI units in both their symbol form (like `m` for meter) in the `UnitSymbols` sub-namespace, and their full name (like `meter` for meter) in the `UnitNames` sub-namespace.
117+
A unit library is available in the `FSharp.Data.UnitSystems.SI` namespace. It includes SI units in both their symbol form (like `m` for meter) in the `UnitSymbols` subnamespace, and in their full name (like `meter` for meter) in the `UnitNames` subnamespace.
118118

119119
## Using Generic Units
120120

0 commit comments

Comments
 (0)