dotnet / dotnet/fsharp

Improve Error Reporting: "inner" expressions inside computations expressions

Open
#2,739 0 comments 1 reaction 0 assignees View on GitHub
Area-Diagnostics Feature Improvement Theme-Simple-F#
Dominant language
F#
Stars
4.3k
Forks
876
Avg merge
4d 11h
Merged PRs (30d)
131

Description

@dsyme - as per your email w/ Dave Thomas...

## What
If you create a computation expression that has a nested expression inside it bound to a value, you need to explicitly create a "child" computation expression for the nested expression.

```fsharp
let x =
let text = "foo"
async {
let answer =
match text with
| "foo" ->
let! y = y // error FS0750: This construct may only be used within computation expressions
y + 5
| _ -> 0
return answer + 10
}
```

You can fix it either by explicitly wrapping the nested `match` expression branches in their own CEs: -

```fsharp
let x =
let text = "foo"
async {
let! answer =
match text with
| "foo" ->
async {
let! y = y
return y + 5 }
| _ -> async { return 0 }
return answer + 10
}
```
or the entire child expression

```fsharp
let x =
let text = "foo"
async {
let! answer = async {
match text with
| "foo" ->
let! y = y
return y + 5
| _ -> return 0 }
return answer + 10
}
```

## Why
The error message is misleading: as far are the developer is concerned, they *are* in an `async` CE; it's not clear at all that by creating a nested expression within the parent CE, the user has "left" the CE.

## How
If it's possible for the compiler to detect this, the error message should be clearer e.g.

`
Code within a nested expressions (e.g. "if" or "match") exists outside of any parent computation expression. In order to perform actions such as let! or do!, the nested expression must be wrapped within its own computation expression.
`

It would also be useful (and this is something that we should consider doing with many other error messages) to give a "before / after" example (as I've done here) either directly inside the compiler error message, or somehow linking to one.

Alternatively, depending on the complexity and whether this could be determined up front, the compiler could do this "nested wrapping" for us.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.