You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Revised computation expression translation table for consistency & clarity (dotnet#36432)
- Changed the syntax to consistently make use of {{ and }} instead of mixed {| |} and { }
- Refer to the process of changing computation expressions to their builder calls only as 'translation'
- Modified for...in and for...to translations so that terms appear the same in both the initial and translated forms
- Removed unbalanced parenthesis for try...with translation
Copy file name to clipboardExpand all lines: docs/fsharp/language-reference/computation-expressions.md
+23-23Lines changed: 23 additions & 23 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -276,36 +276,36 @@ Many of the methods in a builder class use and return an `M<'T>` construct, whic
276
276
277
277
Many functions use the result of `Delay` as an argument: `Run`, `While`, `TryWith`, `TryFinally`, and `Combine`. The `Delayed<'T>` type is the return type of `Delay` and consequently the parameter to these functions. `Delayed<'T>` can be an arbitrary type that does not need to be related to `M<'T>`; commonly `M<'T>` or `(unit -> M<'T>)` are used. The default implementation is `M<'T>`. See [here](https://fsharpforfunandprofit.com/posts/computation-expressions-builder-part3/#understanding-the-type-constraints) for a more in-depth look.
278
278
279
-
The compiler, when it parses a computation expression, converts the expression into a series of nested function calls by using the methods in the preceding table and the code in the computation expression. The nested expression is of the following form:
279
+
The compiler, when it parses a computation expression, translates the expression into a series of nested function calls by using the methods in the preceding table and the code in the computation expression. The nested expression is of the following form:
280
280
281
281
```fsharp
282
-
builder.Run(builder.Delay(fun () -> {| cexpr |}))
282
+
builder.Run(builder.Delay(fun () -> {{ cexpr }}))
283
283
```
284
284
285
-
In the above code, the calls to `Run` and `Delay` are omitted if they are not defined in the computation expression builder class. The body of the computation expression, here denoted as `{| cexpr |}`, is translated into calls involving the methods of the builder class by the translations described in the following table. The computation expression `{| cexpr |}` is defined recursively according to these translations where `expr`is an F# expression and `cexpr`is a computation expression.
285
+
In the above code, the calls to `Run` and `Delay` are omitted if they are not defined in the computation expression builder class. The body of the computation expression, here denoted as `{{ cexpr }}`, is translated into further calls to the methods of the builder class. This process is defined recursively according to the translations in the following table. Code within double brackets `{{ ... }}` remains to be translated, `expr`represents an F# expression and `cexpr`represents a computation expression.
286
286
287
287
|Expression|Translation|
288
288
|----------|-----------|
289
-
|<code>{ let binding in cexpr }</code>|<code>let binding in {| cexpr |}</code>|
|<code>{ use pattern = expr in cexpr }</code>|<code>builder.Using(expr, (fun pattern -> {| cexpr |}))</code>|
297
-
|<code>{ use! value = expr in cexpr }</code>|<code>builder.Bind(expr, (fun value -> builder.Using(value, (fun value -> { cexpr }))))</code>|
298
-
|<code>{ if expr then cexpr0 |}</code>|<code>if expr then { cexpr0 } else builder.Zero()</code>|
299
-
|<code>{ if expr then cexpr0 else cexpr1 |}</code>|<code>if expr then { cexpr0 } else { cexpr1 }</code>|
300
-
|<code>{ match expr with | pattern_i -> cexpr_i }</code>|<code>match expr with | pattern_i -> { cexpr_i }</code>|
301
-
|<code>{ for pattern in expr do cexpr }</code>|<code>builder.For(enumeration, (fun pattern -> { cexpr }))</code>|
302
-
|<code>{ for identifier = expr1 to expr2 do cexpr }</code>|<code>builder.For(enumeration, (fun identifier -> { cexpr }))</code>|
303
-
|<code>{ while expr do cexpr }</code>|<code>builder.While(fun () -> expr, builder.Delay({ cexpr }))</code>|
304
-
|<code>{ try cexpr with | pattern_i -> expr_i }</code>|<code>builder.TryWith(builder.Delay({ cexpr }), (fun value -> match value with | pattern_i -> expr_i | exn -> System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(exn).Throw())))</code>|
|<code>{{ use pattern = expr in cexpr }}</code>|<code>builder.Using(expr, (fun pattern -> {{ cexpr }}))</code>|
297
+
|<code>{{ use! value = expr in cexpr }}</code>|<code>builder.Bind(expr, (fun value -> builder.Using(value, (fun value -> {{ cexpr }}))))</code>|
298
+
|<code>{{ if expr then cexpr0 }}</code>|<code>if expr then {{ cexpr0 }} else builder.Zero()</code>|
299
+
|<code>{{ if expr then cexpr0 else cexpr1 }}</code>|<code>if expr then {{ cexpr0 }} else {{ cexpr1 }}</code>|
300
+
|<code>{{ match expr with | pattern_i -> cexpr_i }}</code>|<code>match expr with | pattern_i -> {{ cexpr_i }}</code>|
301
+
|<code>{{ for pattern in enumerable-expr do cexpr }}</code>|<code>builder.For(enumerable-expr, (fun pattern -> {{ cexpr }}))</code>|
302
+
|<code>{{ for identifier = expr1 to expr2 do cexpr }}</code>|<code>builder.For([expr1..expr2], (fun identifier -> {{ cexpr }}))</code>|
303
+
|<code>{{ while expr do cexpr }}</code>|<code>builder.While(fun () -> expr, builder.Delay({{ cexpr }}))</code>|
304
+
|<code>{{ try cexpr with | pattern_i -> expr_i }}</code>|<code>builder.TryWith(builder.Delay({{ cexpr }}), (fun value -> match value with | pattern_i -> expr_i | exn -> System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(exn).Throw()))</code>|
In the previous table, `other-expr` describes an expression that is not otherwise listed in the table. A builder class does not need to implement all of the methods and support all of the translations listed in the previous table. Those constructs that are not implemented are not available in computation expressions of that type. For example, if you do not want to support the `use` keyword in your computation expressions, you can omit the definition of `Use` in your builder class.
0 commit comments