Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Equivalent of C# async main in F#

I was wondering what would be the equivalent of the C# async main in F#. More to the point, is there a special way of consuming/using async methods from main in an F# program or is it just a matter of waiting for completion?

To be more concrete, say we are using the .NET Core Generic Host.

In a C# program, main might look like this:

class Program
{
    static async Task Main(string[] args)
    {
         await new HostBuilder().Build().RunAsync();
    }
}

In an F# program, my instinct would be to do something like this:

[<EntryPoint>]
let main args =
    HostBuilder().Build.RunAsync().Wait()

...or...

[<EntryPoint>]
let main args =
    HostBuilder().Build.RunAsync() |> Async.AwaitTask |> Async.RunSynchronously

...or...

[<EntryPoint>]
let main args = 
    async {
        return HostBuilder().Build.RunAsync() |> Async.AwaitTask
    } |> Async.RunSynchronously

...or just avoid async...but that's no fun...

[<EntryPoint>]
let main args =
    HostBuilder().Build.Run()

There are a few more formulations I could show but I think these make the point.

I imagine that part of the answer lies in answering these other questions

  1. "what does it mean to run an async main method" and
  2. "what's the point of making main async?"

Going by examples, async main seems mostly to be about making it possible for other places to call main in an async way (in those cases where main is not really "main", ie. unit testing, etc).

In the case of F#, I imagine there are at least 2 things preventing one from just returning an Async computation from main:

  1. The EntryPointAttribute that enforces an int return type for status codes...right?
  2. The compiler probably is not prepared to handle the async computation as the exit value of the program...right?
like image 543
lambdakris Avatar asked Mar 17 '19 15:03

lambdakris


People also ask

What is the equivalent of class in C?

There is nothing equivalent to classes . Its a totally different paradigm. You can use structures in C. Have to code accordingly to make structures do the job.

What is the equivalent of new in C?

There's no new / delete expression in C. The closest equivalent are the malloc and free functions, if you ignore the constructors/destructors and type safety.

What is the equivalent of this in C++?

The C++ equivalent is this ; that is, the keyword is the same. Do not forget the -> thats probably what the OP is missing.

What is delete in C?

delete keyword in C++ Delete is an operator that is used to destroy array and non-array(pointer) objects which are created by new expression. Delete can be used by either using Delete operator or Delete [ ] operator. New operator is used for dynamic memory allocation which puts variables on heap memory.


1 Answers

AFAIK there's no async main equivalent in F#.

If you look at C# implementation behind the scenes it looks like this:

private static void <Main>(string[] args)
{
   Program.Main(args).GetAwaiter().GetResult();
}

Program.Main is the async main.

Personally I find this pattern slightly scary depending on what SynchronizationContext is used.

To emulate async main I would:

let theAsyncTask : Async<int> = ...

[<EntryPoint>]
let main argv =
  async {
    do! Async.SwitchToThreadPool ()
    return! theAsyncTask
  } |> Async.RunSynchronously

theAsyncTask is the actual work to be done, the embedded async switches to the thread pool so that the main thread can safely block and await the result.

like image 185
Just another metaprogrammer Avatar answered Sep 29 '22 12:09

Just another metaprogrammer