Skip to content

FS0748 error "This construct may only be used in computation expresions" reported for 'return' when it is not true #4653

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
abelbraaksma opened this issue Mar 31, 2018 · 4 comments

Comments

@abelbraaksma
Copy link
Contributor

I knew I was testing potentially invalid code, but I was surprised to see the error:

image

Or in text for googleability:

FS0748: This construct may only be used within computation expressions. To return a value from an ordinaty function simply write the expression without 'return'.

Repro steps

Use something like return 1, return 2 at the end of any computation expression.

Expected behavior

Some syntax error, but not the one mentioned above.

Actual behavior

Error FS0748 as mentioned is reported, but the error says I am not inside a computation expression, while I am.

Known workarounds

Don't listen to the error, but fix your code ;).

Related information

As an aside (as always): it would be interesting to here thoughts on allowing return x, return y, but I'm not sure if we can get the behavior defined cleanly. My expectation would be that it would return a tuple of two instances of the computation expression.

  • Seen in VS 15.6 and 15.7, but likely the same in any recent version.
@dsyme
Copy link
Contributor

dsyme commented Apr 3, 2018

@abelbraaksma If it helps, the expr in a return expr doesn't count as part of the computation expression. You;ll find similar error message issues with async { let x = return expr in ... } and such things

Agreed the error message could be better here

@isaacabraham
Copy link
Contributor

Linking to #2739

@abelbraaksma
Copy link
Contributor Author

If it helps, the expr in a return expr doesn't count as part of the computation expression.

@dsyme, Actually, that makes sense, though it isn't immediately obvious that expr, return otherexpr is evaluated first. That is, I don't think it is entirely unreasonable to think of this as a tupled form of yield.

Say you have this:

let x = 
    result { 
        let! (a, _) = someResult
        return a
    },
    result { 
        let! (_, b) = someResult
        return b
    }

Then this seems like a nice shortcut:

let x = 
    result { 
        let! (a, b) = someResult
        return a, return b   // creating two returned values, i.e. Result<_> * Result<_>, instead of Result<_,_>
    }

I've had similar challenges on the let!-binding part, i.e., it would sometimes be nice to write let! a, let! b = result1, result2, as opposed to two separate let! instructions.

But I understand that would be a language change and likely not an orthogonal one.

@jkone27
Copy link
Contributor

jkone27 commented Aug 2, 2023

is this related to the same? this is annoying with match expressions inside task ce...
image

in my case the reason was just the missing _ in:
| _ ->
for all cases, so I think the error is misleading, should suggest missing match case instead.

i didn't see it right away because the compiler error was not useful...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: New
Development

No branches or pull requests

5 participants