-
Notifications
You must be signed in to change notification settings - Fork 796
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
Mutual Recursion with Async Workflow Possible Compiler Issue #3326
Comments
The repro code in case anyone doesn't want to download the zip. #light
module app.main
open System
open System.IO
type message =
| HeatUp
| CoolDown
let climateControl1 = MailboxProcessor.Start( fun inbox ->
// NOTE compiles
let rec heating() = async {
printfn "Heating"
let! msg = inbox.Receive()
match msg with
| CoolDown -> return! cooling()
| _ -> return! heating()} // NOTE placement of }
and cooling() = async {
printfn "Cooling"
let! msg = inbox.Receive()
match msg with
| HeatUp -> return! heating()
| _ -> return! cooling()} // NOTE placement of }
heating()
)
let climateControl2 = MailboxProcessor.Start( fun inbox ->
// NOTE compiles
let rec heating() = async {
printfn "Heating"
let! msg = inbox.Receive()
match msg with
| CoolDown -> return ()
| _ -> return! heating()
} // NOTE placement of }
heating()
)
let climateControl3 = MailboxProcessor.Start( fun inbox ->
// NOTE does not compile
let rec heating() = async {
printfn "Heating"
let! msg = inbox.Receive()
match msg with
| CoolDown -> return! cooling()
| _ -> return! heating()
} // NOTE placement of }
and cooling() = async {
printfn "Cooling"
let! msg = inbox.Receive()
match msg with
| HeatUp -> return! heating()
| _ -> return! cooling()
} // NOTE placement of }
heating()
)
[<EntryPoint>]
let main argv =
printfn "test"
0 |
We will treat this by design, though please feel free to add an issure at http://github.com/fsharp/fslang-suggestions. Just indent the closing |
@dsyme What is the rationale for by-designing this? I think it's fairly reasonable to expect people to want to put the closing brace as the example shows. Currently, the auto de-indentation feature in VS will auto de-indent to the same indentation level as the After all, it's valid already, and given that the |
@cartermp OK, I try to take a look next week at what it would take to fix this. |
Thanks! |
Fixed in preview #11772 |
The placement of a mutually recursive async workflow's ending curly brace seems to impact compilation success when it probably shouldn't. The sample code with comments demonstrates the issue. If I'm mistaken, I'd appreciate an explanation (i.e. some offside issue that I'm not seeing).
Repro steps
main.zip
Expected behavior
I would have expected that the placement of the ending curly brace in climateControl3, which is the same as in the non-mutual recursive function climateControl2, would not generate compiler errors.
Actual behavior
The above sample code will generate climateControl3 compiler errors when compiled:
main.fs(45,5): error FS0588: The block following this 'let' is unfinished. Every code block is an expression and must have a result. 'let' cannot be the final code element in a block. Consider giving this block an explicit result.
main.fs(53,5): error FS0010: Unexpected keyword 'and' in lambda expression. Expected incomplete structured construct at or before this point or other token.
main.fs(62,5): error FS0010: Incomplete structured construct at or before this point in binding. Expected incomplete str uctured construct at or before this point or other token.
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft SDKs\F#\4.1\Framework\v4.0\fsc.EXE"' : return code '0x1'
Stop.
Known workarounds
The placement of the ending brace should follow the example in climateControl1.
Related information
Provide any related information
The text was updated successfully, but these errors were encountered: