Comment by cjbgkagh
3 days ago
F# is a big language, it is a ML multi paradigm language that interoperates with C# so there is a lot of necessary complexity and many ways to do the same thing. A strong benefit of this is the ability to create a working functional paradigm prototype that can iteratively be refined to a faster version of itself by hot spot optimizing the slower parts with equivalent highly mutable functions while staying within the same language. Similar how one would use python and C++ and over time replace the python code with C++ code where performance is important.
For the specific case of C# use of await it is unfortunate that C# didn't design this feature with F# interop in mind so it does require extra steps. F# did add the task builder to help with this so the 'await' is replaced with a 'let!' within a task builder block.
let getById(id:int) : Task<string> = failwith "never"
let doWork(post:string) : unit = failwith "never"
let doThing() = task {
let! post = getById(42);
doWork(post); }
Alternatively the task can be converted to a normal F# async with the Async.AwaitTask function.
let getPostById1(id:int) : Async<string> = async { return! getById(id) |> Async.AwaitTask }
let getPostById2(id:int) : Async<string> = getById(id) |> Async.AwaitTask
let getPostById3 : int -> Async<string> = getById >> Async.AwaitTask
It is best to just use task CE full-time unless you need specific behavior of async CEs.
The author of the original comment, however, does not know this nor tried verifying whether F# actually works seamlessly with this nowadays (it does).
Writing asynchronous code in F# involves less syntax noise than in C#. None of that boilerplate is required, F# should not be written that way at all.
F# is a big language so I think it is to be expected that beginners will not know these things. I don't think the fix is to simplify F# we should just understand that F# is not for everyone and that is ok.
This is perfectly fine, but I think it's better to be unsure about specific language feature than confidently state something that is not correct (anymore).
Personally, I'm just annoyed by never-ending cycle of ".NET is bad because {reason x}", "When was this the case?", "10 years ago", "So?".
Like in the example above, chances are you just won't see new F# code do this.
It will just use task { ... } normally.
I understand that you CAN do this, I'm saying that it makes your code look like shit and takes away some of the elegance of ML
Please stop insisting on this. Task CE exists since F# 6.0 and handles awaiting the CoreLib Tasks and ValueTasks without any ceremony.
Are you saying you prefer Ocaml to F# or C# to F#? Your example was indeed inelegant but it is also poorly designed as you take 4 lines to reproduce a function that is already built in, people can poorly design code in any language.
7 replies →