Fable icon indicating copy to clipboard operation
Fable copied to clipboard

Fable2Rust issue compiling function returning lookup of a readOnlyDict

Open smoothdeveloper opened this issue 2 years ago • 1 comments

I'm getting a compile error with this F# code:

exception Goto of name:string
let rec execute blocks =
  let blocksAsDict = readOnlyDict (List.toSeq blocks)
  let getBlock blockName = blocksAsDict[blockName]

  let rec doBlock (label,block) =
    try
      block()
      label
    with
      Goto name ->
        doBlock (name, getBlock name)
  
  let rec executeBlocks remainingBlocks =
    match remainingBlocks with
    | [] -> ()
    | (labelAndBlock :: remainingBlocks) as b ->
      printfn $"eb: %A{b}"
      let label,_ = labelAndBlock
      let labelAfterExecuting = doBlock labelAndBlock
      if label <> labelAfterExecuting then
        let indexOfExit = blocks |> List.findIndex (fst >> ((=) labelAfterExecuting))
        if indexOfExit < blocksAsDict.Count - 1 then
          executeBlocks (List.skip (indexOfExit+1) blocks)
      else
        executeBlocks remainingBlocks
  executeBlocks blocks
let goto name = raise (Goto name)
let ffffmain () =
  let mutable i = 0
  
  execute
    [
      "loop", fun () ->
        if i >= 5 then goto "out" else
        printfn $"{i} Hello, World"
        i <- i + 1
        goto "loop"
      "out", fun () ->
        printfn "Done."
    ]
    
  let mutable i = 0
  let gotoIncrI label = i <- i + 1; goto label 
  execute
   [
     "1", fun () -> printfn "1"
     "2", fun () -> printfn "2"; gotoIncrI "4"
     "3", fun () -> printfn "3"
     "4", fun () -> printfn "4"; gotoIncrI "6"
     "5", fun () -> printfn "5"
     "6", fun () -> printfn "6"; if i < 10 then gotoIncrI "3"
   ]

it seems to occur due to how getBlock is emitted.

smoothdeveloper avatar Jun 15 '23 20:06 smoothdeveloper

@smoothdeveloper Unfortunately F# exceptions are not well supported for Rust yet. Simple .NET system exceptions (exn) are somewhat supported (on targets that support unwinding), but the rest is still todo, since Rust doesn't have inheritance and most exceptions are inheritance-based.

Simple raise (exn "name")/failwith/failwithf should work, as well as simple try..with | _ -> / try..with | ex ->.

There is also a small capturing issue with the rec lambda, I'll take a look.

Inheritance is something that's still on the back-burner for Fable Rust, any ideas are welcome.

ncave avatar Jun 16 '23 04:06 ncave