You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It's currently hard to use Fable to write code that uses Task and compile to both Python and JS/TS. Python translates Task to native Task/Future awaitables (async / await) while for TS/JS you need to use JS.Promise.
This makes the code base filled with #if/#else even if you try to rename Promise to Task. Is it time to support Task in Fable for JS/TS that the task CE is native for F#? Ref: dbrattli/Fable.Giraffe#13 (comment)
Are Task in .NET hot or cold? In the sense do they execute on creation or wait to be invoked?
Could it lead to problems if Task are cold in .NET and/or Python, while in JavaScript promise are hot ?
While we decide on what to do here, a possible workaround for people who need to add cross platform asynchronous code is to create a module which encapsulate the compiler directives. Could benefit from helpers functions too.
Note: Code below use async but I believe the same could be applied to Task
moduleMainopenFable.Core// We need the `<'T>` here as it allows to mark the function/variable inline for better output.let inlinecrossAsync<'T>=#if FABLE_COMPILER
promise
#else
async
#endiftypeCrossAsync<'T>=#if FABLE_COMPILER
JS.Promise<'T>#else
Async<'T>#endiflethello(name :string):CrossAsync<string>=
crossAsync {return"Hello "+ name
}// Fake the API being called by the consumer code
crossAsync {let!hello= hello "World"
printfn "%s" hello
return()}#if FABLE_COMPILER
|> Promise.start
#else|> Async.Start
#endif
Tasks in .NET are hot in the sense that when you hold a Task returned from an async method then it's already running regardless if you use await or not. So Task in .NET and Promises in JS are both hot. Tasks in Python are scheduled Futures so they are hot. This is also why I'm unsure about rewriting all Task based code to use F# async for interoperability.
The workaround is nice if you own the codebase but e.g for Fable.Giraffe I want users to use their existing Giraffe webapp without having to modify their code. I.e they can decide if they want to run their web server on .NET, Python or Node (or a combination). Then it would be nice if we could call a Task for a Task.
But this is something we can probably ignore (will need some testing so see how often this "problem" occurs).
If I am reading you correctly, then we have:
.NET task are hot
Python scheduled futures are hot
JavaScript promise are hot
Rust ? @ncave What are your plans for supporting Task in Rust? Does Rust have hot task?
If all the these major targets have the same hot behaviour available natively, I think it could makes sense to try implements an equivalence between them. This would allows, people to share the same code but also to use the native APIs.
Currently, as you mentioned in your first message, we have these situations:
Situation 1
People prefers to use native primitives and so use Promise for JavaScript and Async for .Net.
Then if they need to merge the code, they needs to use compilers directives or helpers like Async.AwaitPromise / Async.StartAsPromise
Situation 2
People value more shared code and write everything using Async which are natives to .NET but not to JavaScript for example.
So implementing Task by making them use the native APIs would create a third situation which is the best of both world:
Ability to use native F# API which is standard in F# so shareable and use native APIs in the runtime.
It's currently hard to use Fable to write code that uses Task
Can you please elaborate, just trying to understand what the stated goal is.
Is it to get most of the languages (JS/TS/Rust/Python) to support at least what is needed to pass the TestTask tests?
Yes, started porting Fable.Giraffe to TS/JS. It already runs on Python so the current Task tests would solve my needs. Could we make Giraffe run on Rust? 🙈
Activity
MangelMaxime commentedon Dec 18, 2023
Are
Taskin .NET hot or cold? In the sense do they execute on creation or wait to be invoked?Could it lead to problems if
Taskare cold in .NET and/or Python, while in JavaScriptpromiseare hot ?While we decide on what to do here, a possible workaround for people who need to add cross platform asynchronous code is to create a module which encapsulate the compiler directives. Could benefit from helpers functions too.
Note: Code below use async but I believe the same could be applied to Task
dbrattli commentedon Dec 18, 2023
Tasks in .NET are hot in the sense that when you hold a
Taskreturned from an async method then it's already running regardless if you useawaitor not. SoTaskin .NET and Promises in JS are both hot. Tasks in Python are scheduled Futures so they are hot. This is also why I'm unsure about rewriting all Task based code to use F# async for interoperability.The workaround is nice if you own the codebase but e.g for Fable.Giraffe I want users to use their existing Giraffe webapp without having to modify their code. I.e they can decide if they want to run their web server on .NET, Python or Node (or a combination). Then it would be nice if we could call a Task for a Task.
MangelMaxime commentedon Dec 18, 2023
Seems like in .NET there is an exception when you use the constructor to create the task.
Source
But this is something we can probably ignore (will need some testing so see how often this "problem" occurs).
If I am reading you correctly, then we have:
If all the these major targets have the same hot behaviour available natively, I think it could makes sense to try implements an equivalence between them. This would allows, people to share the same code but also to use the native APIs.
Currently, as you mentioned in your first message, we have these situations:
Situation 1
People prefers to use native primitives and so use
Promisefor JavaScript andAsyncfor .Net.Then if they need to merge the code, they needs to use compilers directives or helpers like
Async.AwaitPromise/Async.StartAsPromiseSituation 2
People value more shared code and write everything using
Asyncwhich are natives to.NETbut not to JavaScript for example.So implementing
Taskby making them use the native APIs would create a third situation which is the best of both world:Ability to use native F# API which is standard in F# so shareable and use native APIs in the runtime.
ncave commentedon Dec 18, 2023
@MangelMaxime
There is already some partial support for
Async/AsyncBuilder,Task/TaskBuilder,Thread/ThreadPool/Monitoradded by @alexswan10k.Afaik Rust's futures are cold, but I'm not sure that is a showstopper.
@dbrattli
Can you please elaborate, just trying to understand what the stated goal is.
Is it to get most of the languages (JS/TS/Rust/Python) to support at least what is needed to pass the TestTask tests?
dbrattli commentedon Dec 18, 2023
Yes, started porting Fable.Giraffe to TS/JS. It already runs on Python so the current Task tests would solve my needs. Could we make Giraffe run on Rust? 🙈
ncave commentedon Dec 18, 2023
@dbrattli
I guess the first step would be to make the TestTask tests pass.
MangelMaxime commentedon Jun 29, 2026
The original issue has been fixed in #4694