Search code examples
f#comefrom

How do you implement comefrom in F#?


I've begun to be accustomed to the F# way of implementing goto control flow, but I'm not quite sure how I can handle comefrom, a la INTERCAL.

comefrom is a very useful construct that allows you to jump from a label. The following example program uses it to print the complete instructions for washing your hands:

comefrom repeat
Console.Write "Lather"
Console.Write "Rinse"
repeat

The beauty of comefrom is that you can put a label in multiple places.

comefrom restart
Console.Write "Do you want to restart this program?"
let a = Console.ReadLine()
match a with
| "Y" -> restart
| _   -> Console.Write "Too bad! It will restart whether you like it or not!"
         restart

I tried both of these programs, but the capricious F# compiler decided to disappoint me. How can I take advantage of comefrom in F#?


Solution

  • This is pretty close to the syntax you want.

    let comefrom f = 
      let rec g = (fun () -> f g)
      f g
    
    comefrom (fun restart ->
      Console.Write "Do you want to restart this program?"
      let a = Console.ReadLine()
      match a with
      | "Y" -> restart()
      | _   -> Console.Write "Too bad! It will restart whether you like it or not!"
               restart())
    

    Once you wrap your head around a function, f, accepting a function, g, which itself is passed to f, it's relatively straightforward.

    Migrating INTERCAL code to F# is hard. This hopefully should reduce the work involved.