New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal, async, await, promise, holistic, language improvement tweak, with idea of were Javascript, TypeScript, nodeJS, c# have and are heading, to simplify things. #1258

Closed
wesleyolis opened this Issue Jul 10, 2018 · 5 comments

Comments

Projects
None yet
3 participants
@wesleyolis

wesleyolis commented Jul 10, 2018

Hi,

Having issues getting thought to the mailing list es-discuss@mozilla.org waiting on sub email, need to move on now with other work again, so hope this will surfice in the mean time.

I shall see how much more time, I get that I can put into this to convince you that this is the path forward with async work from a language agnostic point of view. Going to be a very long day to morrow/ night and rest of the week, dead lines.

Hopefully this is enough to get you guys thinking about this so far.

I have just written a whole lot of typescript for nodeJS, this typically what I have seen is the problems and sticking points. I have also spent a fair about of time in dot net core with async work and classes as well, so my take on everything with a step back from just a single language.

I expecting that c# will probably also follow this route in the longer term, that mainly return type with async modifier will be used and an implicit method, function, procedure call async modifier keyword, that instead cause code to converted to async code/promises..

Document is open for commenting, unless their better tracking tools you guys are using, of which I saw a really nice one geared at university master projects, for were multiple people all work on the same document to vet it, or in this case bring it to a consensus.

Kind Regards,

Wesley Oliver

See the document below:

https://docs.google.com/document/d/1QigfqvlM2vMNl-4szjuPj9tFXIQle2zsbrsnze9bAIU/edit?usp=sharing

Proposal,async, await, promise, holistic, language improvement tweak, with idea of were Javascript, TypeScript, nodeJS, c# have and are heading, to simplify things.

Well were to start I guess, as simple as these definitions changes are to how the language behaviors, there are many different perspectives and angles to look at this from at how it improves things. So please bear with me as I hopefully try to present all the cases with reason to you. What I am going to do is include my rough thoughts at the end of things, incase nothing is that clear, you try decipher those. If my understanding may be slightly off in an area keep focused on the bigger picture, there are alot of details. Please not that I am looking at this from a typescript perspective, that wraps plain old vanilla javascript, as we want everything to work perfectly together, in future.

Terminology:

Async Work (Wordload)

A:

‘await myfunAsync() // where return type is (async) Promise

B:

‘Const handle = async myfunctionAsync() // where reutnr type is (async) Promise

…..instruction that execute on the current caller stack.

Await handle;

C: sync code, that is converted into and async code(task/promise) New

‘async myfunction() : void’

`const handle = async myfunction() : void

… instructions that execute on the current caller stack.

Await handle;

The Language Changes:

Change A: async function keyword modifier

async keyword in front of a function signature, functionality meaning and behaviour change

async function (a : boolean, b : string) : (async) Promise | (async) void

{

}

Current -> meaning/ functionality/constraints

This results in the function being converted to Promisified function implicitly as my understanding is. The return type of the function is automatically promisified.

It is a requirement for a function signature to be declared as async, for one to be able to have an await call inside the method/function/procedure body.

Gripes, pitfalls of this method.

This is a top approach to promisifcation creating async task or work flow, it is the approach that C# has taken. Feels like a direct copy actually, javascript has promises.

As in c# this top level approach to create async running function, violates encapsulation if you think of it, because now the top level function needs to know about async work.
Typically we want to hide implementation details, no one, should need to know that this function has code in it that runs asyncly, that is implementation details, that no needs to know that.

Current methods, that take callback and run the callback asyncly, now have to implement async await versions of all nifty forEach function and all the rest, run as expected sync code. So the callback style of writing code is out the window for already existing functions and it will break them, make life a pain when wanting to upgrade and use simple sync callback functions, no harmony here.

New -> meaning/functionality/constraints.

This keyword function as a constraint, as in c#, it requires that async work(workload) method/function/procedure to have been call in here at least, and emits a compiler warning with typescript, that can be disabled, just like in c#, when its missing.
When we say it can call async work (workload), what that entails is a new definition, see above definition explanation.

It will no longer create an async function that will be the job of async keyword calling a function that modifies it into a task, async work, explicitly were the function is being called.
Yes, probably took the approach to do it at function level, as to prevent too my code generation, but better this way, beside, generate both sync and async version of a function, but at much higher level, which results in a much larger workload sharing the same stack, as function would naturall call it be inlined or collapsed.

It is merly now use as a hit to caller functions that this method has some calls to async work, could be enforce, would really make no difference, just be good for debugging on text base editor, with now ide, to provide hint that the call contains some async code.

The return type in typescript should be used to communicate async task, make a specialy return type name should be used. Could use async before the fun () : async void

This means that foreach simple methods like this will now work by default, as the function is not converted to an async executing block of code, only awaited(async work load) in the call back will be.

Change B:

Return type dictates with a function is async or not and method name for readability must have async in it.

Just like is currently happening the return type of a function if a promise is async work loaded, Promise introduction of the use of async in the return type before the actually function return type, could be a more language formal abstraction name, instead of Promise.. Just register return type async as Promise at runtime.

For sanity purposes when reading function calls, to be able to differential the correct code execution behaviour and predict it in text form. A function with an async return type, name must all have a suffix of async, otherwise it is an error. This also allows on to later automatically route between async/sync function calls, were there exists to specific implementations. A sync one and async one, were be differential by name, since javascript doesn’t know of any types in the first place.

Most importantly, this means that a function when refactored, is change from a return type Promise to void it can be detected and the compiler can emit errors for procedural calls, in older old, were async suffix is not enforce, the behaviour change can now be spotted. I don’t see any other way, here unless add a key word to proceed the function call, which then become extremely verbose and not be backward compatible.

myFun() // which is actually myFunc() : (async) Promise

// versus can be differentiated clearly., in future.

myFun() // which is actually myFunc() : (async) void

Change C: async myfunc()

Aysnc function call modifier

`

Const handle = async mySyncFun();

…. Code on the current stack to be execute.

Await handle

`

`

myFun() // which is actually myFunc() : (async) Promise

// versus can be differentiated.

myFun() // which is actually myFunc() : (async) void

`

The keyword async infront of a function call will now allow us to automatically convert any code to a task, aysnc workload that can be executed.

Their should be good inlining of code before and actually await, that functionality is nestled deep in the code, that no needs to know about encapsulation.

Change D: async workload function calls parameters introduce ref keyword, for parameters that are not from the local function bock are require to be called with ref, to say I want a referance..

This going to be a breaking change that typically only typescript could enforce with typings.

Rough thoughts on things

Javascript, Typescript = aysnc/await language improvement

Async keyword before a function shouldn’t convert a function to async, the return type should do that, this is the biggest mistake. The async keyword, should just be used to say that inside this function I expect their to be a call to an async method or newly created task from a function.

Potentially async keyword, could be used communicate out of the call hierarchy that some were in this neast mess their is an async function call, so that for debugging purposes, from a top level, know their is some aysnc code execution some were.

So basically two constraints, is that either there is a function called with return type of promise

Or that call at least one function that has async in front of it communicate that in that function their

Is some async work being performed. It is an error for a async function signature to not have called either of these two.

Then the Promise should have a compiler enforce that a function be named with a Suffix “Async”

This allows a method at a top level to communicate that it returns a promise, without any inspection of the return type.

When a function is to be called, if preceded, by and async keyword it will cause a non async function to be wrapped and converted to a promisify function.

Look into enhance compiler mapping of function calls, by default all methods would call an async versions and only a top level sync versions should be exposed, but if their is a function with the same name, that didn’t have the async name, their basically route between the two functions, using a keyword.

Were basically sync keyword infront of an async function would call the same function without the async keyword, or generate blocking code, but then that is why we have await, causes any async function to be run like that. Then in this cases, what can happen is this can be performance optermization.

If their two versions of a function async and sync, then await async version will call the optermized sync versions of that function, speeding up code execution.

How do we go about detecting refactoring of are return Promise and void function, so that the compiler can pick up the difference in behaviour that an await would be needed, introduction of async key word when a method is called as stand alone, shouldn’t be too many functions like this already, most in existing code bases, should already be awaited.. But need to support backwards compatability, which means, this break things so promises that return Promise

Should be call with prefix keyword of async or await, if it is the async keyword, then all existing function that are not called with async, that have not been awaited would fail, but their should be very few of these, because this as they are hand off function, that never again interact with the scope of the current function someone is writing. It update some othe global, link the screen, with painining, or queue some finished work for someone else to complete.

Promise chain, would typically end with a .then which would have a a void return type, so we wouldn’t break any existing functionality.

If wanted a whole function to be run as async, then instead the top level async keyword approach,

Just wrap the code and have it in a return type of Promise.

I know that return type mayn’t have been included in the function signature and by design this is a limitation, but limitation and flaw, that makes so difficult, messy unpredictable and prone to error, that

It warrants us looking to fix it. If it the function signature is fixed, by preparsing enforcing Async to be in the function signature name.

Also look at the ability to have preflighted promise code execution, that have setup, init, run code.

Where setup, is warmed up overhead, that could already be launched in parallel and cache, init is last minute parameters for for binary code to fill in. then run the promise, this would allow the V8 engine to better cache promises in machine code, as implemented the ability for the designer to classify things better, in which the compiler can also improve thens.

Then when calling function that are promisified using async call way, or return type, then

Parameters that are not of local function scope, which and are of global scope must be called explicitly with the keyword ref to acknowledge that going to mutate global code, it should also be a requirement that

Any passed in parameters to async executable, should support locking mechanism, by default and we can added code such that things like race conditions can be detected. Typically all parameters should be passed as a deep copy to async function calls (Promise), unless preceded, by ref, which allows reference, to reduce errors, the question now is how to deal with locking and race conditions automatically. The only thing left, to do, is to figure out how to constrain the problems now at design time to prevent race conditions.

Then compiler warnings, generating, for some of the case, in which case, only be for those procedures now that return a promise, that are not called with the async keyword, this covers mostly everything now.

Does this resolve the issues around the forEach(() =>

{

await some function
}

Yes it does, since now the return type and not the keyword in front of callback function, in the previous cases all existing methods that have existing, would need Async version that have been implemented, that would await the call, but this is a messed.

Encapsulation of code and not really needing to know what is going on under the hood is lost with this current approach, use the return type of promise, because it is much easier.

The reason they probably choose async that they top, is potentially to be able to abstract the whole function and the fact they probably came from C#, in which case they copied it directly, which was a mistake. c# should actually follow the typescript and javasript way.

The other thing to look at is my loop pattern from dot active, new for loop syntax and must all the language abstraction as suggestions I used it all to many times.

c# can siable the async keyword, if nothing aysnc work actually done in function, error, like we did for netcon write.

Async function call is equivalent of c# task.

Ref rsuted approache variable is nulled after passed in.

Different pattern for switch syntax.

switch( by default with break)

Case a, b, c, d : default with break

Implement a new caseif(...) case a, b,c,d implicity break, case e,g,h

Look ahead shortcut function call inline versus recursive pattern.

**** Hoist functionality in pulling executupting, basically impossible, as have to wait for code anyways, unless want to delay the waiting, in which case that is the only dis advantage, like saying call thi async, function deep drop, but return it as a call back, so current stack can keep executing..in parrallel,to the async work load, then later do somthing with it. This the only cases, I am trying to figure out why one would do this, think why one would want to do this. As far as I can see right now the code, should jsut be broken up, no point having it in the same function, their was no dependancies, ok that this one delt with.

@wesleyolis

This comment has been minimized.

Show comment
Hide comment
@wesleyolis

wesleyolis Jul 10, 2018

I have made some updates Tuesday 10 Jully 2018.

Which with a rather long debate to get onto the same page, terminology of describing the problems and different perspectives on meanings, intepretations and intentions of Promise and async, task.., with my colleague, these are more things that make it much clearer pros and cons and then couple more things I have thought up now while mutating this, on how I would further improve things and more benefits that would come from this minor interpretation change in the bigger picture.

https://docs.google.com/document/d/1QigfqvlM2vMNl-4szjuPj9tFXIQle2zsbrsnze9bAIU/edit?usp=sharing

Updated snap shot for the record.

Proposal,async, await, promise, holistic, language improvement tweak, with idea of were Javascript, TypeScript, nodeJS, c# have and are heading, to simplify things.

Well were to start I guess, as simple as these definitions changes are to how the language behavior, there are many different perspectives and angles to look at this from at how it improves things. So please bear with me as I hopefully try to present all the cases with reason to you. What I am going to do is include my rough thoughts at the end of things, incase nothing is that clear, you try decipher those. If my understanding may be slightly off in an area keep focused on the bigger picture, there are alot of details. Please not that I am looking at this from a typescript perspective, that wraps plain old vanilla javascript, as we want everything to work perfectly together, in future.

To be clear one want to have the ability to decide on whether I await on a workload to finish as I am interested in the results, or whether to fire and forget about it, as mutates some global function or updates some UI in the future.

Terminology:

Async Work (Wordload)

A:
‘await myfunAsync() // where return type is (async) Promise

B:
‘Const handle = myfunctionAsync() // where return type is (async) Promise
…..instruction that execute on the current caller stack.
Await handle;

C: sync code, that is converted into and async code(task/promise) New
‘async myfunction() : void’

`const handle = async myfunction() : void
… instructions that execute on the current caller stack.
Await handle;

The Language Changes:

Change A: async function keyword modifier

async keyword in front of a function signature, functionality meaning and behaviour change

async function (a : boolean, b : string) : (async) Promise | (async) void
{

}

Current -> meaning/ functionality/constraints

This results in the function being converted to Promisified function implicitly as my understanding is. The return type of the function is automatically promisified.

It is a requirement for a function signature to be declared as async, for one to be able to have an await call inside the method/function/procedure body.

Current also used to cascade communicate to a top level the intrinsic of this function execution behaviour details that it has some out of order execution or benefit from some IRQ work.

Question to ask yourself what communicating these intrinsic details benefit us?
For one it allows us to determine if all the code is sync or whether some of it is async. This helps us upfront know whether creating a task async work of 10000X the same function may potentially yield any performance gain in execution. If all code is syncness then it is performance degradation, if their potentially is async code in their, then we know may benefit from async execution.

When looking at what the async modifier cascade keyword can communicate to us, consider this when reading this proposal, because it is a very small amount of information, but still important to know up front as may await many task, but if the function at top level is not have async return type, the we shall use the await async loop (fun - 1, fun - 2, fun - 3, fun - 4), which cause them to be launched async, which is what we want.

By still having the async function modifier keyword used to hit or communicate the intrinsic behaviours of a function that their is some async work load in here.

We can emit compiler warning when async is called on a function that has absolute no async work in it, say that there be no benefit of this, unless another thread execution which rare case or when its a procedure and we don’t care about the results.

If were explicitly async of a loop of a 10000 X async workloads were the return type is number, but the function being called is async modifier keyword prefix, then we wouldn’t emit a warning, because their would potentially be a speed up.

Visa versa the compiler can also give a hit to say you may benefit from executing this code async as it know their is some async workload in their intrinsically by the prefix async keyword modifier.

It would be great if I could make this async keyword visible in a function name, which means we don’t have to rely on the compiler to help us out at a top level as to how we should be executing this function. So function with async prefix keyword, is used to communicate, that in this function body there is a call some to async workload and can only be used if the return type of the function is not a promise or async return type.

Wait what if we implement a new suffix convention, that any function with the async prefix keyword modifier, name must have in its name otherwise it is an error.
What shall it be Async already means it return a promise all has the raw code to deal with IO, IRQ extra.. Or provides some very light weight security wrapper or something.

Let take a vote without thinking too much how about the keyword how about, Vsync, its like async, but only happen in a single plain, and is already well know and has a nice own to it. Mabye PSync for partially sync..

Guess the only pitfall is if we decide to differentiate between async work that can run on a single thread of execution or run on multiple threads, it would be good to know which function support which modes for a designer perspective, and we could implement another keyword. XSync means it potentially can run across multiple threads/cores, but then again I would prefer to do analysis on the parameters that should be passed in.
Can enforce constraints on all variables referenced in the body of the function, that have be of local scope or have had some locking and things like that. But then I think their ward was to potentially constrain a pattern so that things are not blocking, but that's the next step.

Gripes, pitfalls, performance loss of this method.

This is a top approach to promisifcation creating async task or work flow, it is the approach that C# has taken. Feels like a direct copy actually, javascript has promises.

As in c# this top level approach to create async running function, violates encapsulation if you think of it, because now the top level function needs to know about async work.
Typically we want to hide implementation details, no one, should need to know that this function has code in it that runs asyncly, that is implementation details, that no needs to know that.

Current methods, that take callback and run the callback asyncly, now have to implement async await versions of all nifty forEach function and all the rest, to run as expected sync code. So the callback style of writing code is out the window for already existing functions and it will break them, make life a pain when wanting to upgrade and use simple sync callback functions, no harmony here.

If one wants to await an async workload inside a function body, then one has to current make this function an async function by adding the prefix modifier. Now at the next function that calls this, you will have to now once again by default have to await it then by requirement have make the caller function async, this then cascades all the way to the root of your program. Everything then is promisified.

Everything becomes promisified, when wrap a single async IO function with a whole bunch of sync code, that actually performs the logic and sync manipulation. This means everything now has the overheads of promises, they're no longer is a light weight function, if any function in the neasted call heighrache at the bottom contained async method, their every other function now bears the overheard, this is crazy. Were one could rather have just had all the sync code run before the await workload(promise) and sync code run afterwards.

New -> meaning/functionality/constraints.

This keyword function acts as a constraint, as in c#, it requires that async work(workload) method/function/procedure to have been call in here at least, and emits a compiler warning with typescript, that can be disabled, just like in c#, when its missing.
When we say it can call async work (workload), what that entails is a new definition, see above definition explanation.

It no longer is a requirement for the function in which their is await in the body, to have the async keyword, you call await anywhere you want on function that has promise(async) return type. The only requirement now will be for the caller function to have the modifier or just the suffix of PSync, don’t need duplicate work. As the function name is really the only readable peace of information as prefix and suffix, async/return type can’t be read only interrogate by a compiler. Mabye to speed up compilering - can be allowed infunction names, which allows us to simplere differential, the suffix faster fo the compiler, however it 4 chars we have 8 char wide ascii, so single compartive op on end of string, just may not be register align, which may it slower.. Not point really for the dash.

It will no longer create an async function that will be the job of async keyword calling a function that modifies it into a task, async work load, explicitly their in the caller function body were the function is being called or the return type of promise or new suffix async keyword, which implicity makes it imediately execute and requires await, as the return type is of type async.

Yes, probably took the approach to do it at function level, as to prevent too my code generation, but better this way, beside, generate both sync and async version of a function, but at much higher level, which results in a much larger workload sharing the same stack, as function would naturally allow themselves to be inlined or collapsed.

It is merely now use as a hit to caller functions that this method has some calls to async work, could be enforce, would really make no difference, just be good for debugging on text base editor, with now ide, to provide hint that the call contains some async code. Actually go see the function comment question about this above, that is much better PSync..

The return type in typescript should be used to communicate asynctask, make a specially return type name should be used. Could use async before the fun () : async void

This means that foreach simple methods like this will now work by default, as the function is not converted to an async executing block of code, only awaited(async work load) in the call back will be.

Performance gain only experience the async workload overhead were an await statement is used and nowhere else, as as the cascading problem has been avoided. Be nice to await prom1, prom2, prom2.

Prefix async modifier can still be used

Change B:

Return type dictates with a function is async or not and method name for readability must have async in it.
Just like is currently happening the return type of a function if a promise is async work loaded, Promise introduction of the use of async in the return type before the actually function return type, could be a more language formal abstraction name, instead of Promise.. Just register return type async as Promise at runtime.

For sanity purposes when reading function calls, to be able to differential the correct code execution behaviour and predict it in text form. A function with an async return type, name must all have a suffix of async, otherwise it is an error. This also allows on to later automatically route between async/sync function calls, were there exists to specific implementations. A sync one and async one, were be differential by name, since javascript doesn’t know of any types in the first place.

We could also say if we use the suffix, that their is not point to have to stutter and use the async keyword and the Async suffix, the one is implied by the other, but only the one implied from the readable name, should be allowed as we are going for code readability here at a glance one needs to know what is going on.

Most importantly, this means that a function when refactored, is change from a return type Promise to void it can be detected and the compiler can emit errors for procedural calls, in older old, were async suffix is not enforce, the behaviour change can now be spotted. I don’t see any other way, here unless add a keyword to proceed the function call, which then become extremely verbose and not be backward compatible.

myFun() // which is actually myFunc() : (async) Promise
// versus can be differentiated clearly., in future.
myFun() // which is actually myFunc() : (async) void

Change C: async myfunc()

Aysnc function call modifier

Const handle = async mySyncFun(); …. Code on the current stack to be execute. Await handle

myFun() // which is actually myFunc() : (async) Promise<void> // versus can be differentiated. myFun() // which is actually myFunc() : (async) void

The keyword async infront of a function call will now allow us to automatically convert any code to a task, aysnc workload that can be executed.
Their should be good inlining of code before and actually await, that functionality is nestled deep in the code, that no needs to know about encapsulation.

Change D: async workload function calls parameters introduce ref keyword, for parameters that are not from the local function bock are require to be called with ref, to say I want a referance..
This going to be a breaking change that typically only typescript could enforce with typings.

wesleyolis commented Jul 10, 2018

I have made some updates Tuesday 10 Jully 2018.

Which with a rather long debate to get onto the same page, terminology of describing the problems and different perspectives on meanings, intepretations and intentions of Promise and async, task.., with my colleague, these are more things that make it much clearer pros and cons and then couple more things I have thought up now while mutating this, on how I would further improve things and more benefits that would come from this minor interpretation change in the bigger picture.

https://docs.google.com/document/d/1QigfqvlM2vMNl-4szjuPj9tFXIQle2zsbrsnze9bAIU/edit?usp=sharing

Updated snap shot for the record.

Proposal,async, await, promise, holistic, language improvement tweak, with idea of were Javascript, TypeScript, nodeJS, c# have and are heading, to simplify things.

Well were to start I guess, as simple as these definitions changes are to how the language behavior, there are many different perspectives and angles to look at this from at how it improves things. So please bear with me as I hopefully try to present all the cases with reason to you. What I am going to do is include my rough thoughts at the end of things, incase nothing is that clear, you try decipher those. If my understanding may be slightly off in an area keep focused on the bigger picture, there are alot of details. Please not that I am looking at this from a typescript perspective, that wraps plain old vanilla javascript, as we want everything to work perfectly together, in future.

To be clear one want to have the ability to decide on whether I await on a workload to finish as I am interested in the results, or whether to fire and forget about it, as mutates some global function or updates some UI in the future.

Terminology:

Async Work (Wordload)

A:
‘await myfunAsync() // where return type is (async) Promise

B:
‘Const handle = myfunctionAsync() // where return type is (async) Promise
…..instruction that execute on the current caller stack.
Await handle;

C: sync code, that is converted into and async code(task/promise) New
‘async myfunction() : void’

`const handle = async myfunction() : void
… instructions that execute on the current caller stack.
Await handle;

The Language Changes:

Change A: async function keyword modifier

async keyword in front of a function signature, functionality meaning and behaviour change

async function (a : boolean, b : string) : (async) Promise | (async) void
{

}

Current -> meaning/ functionality/constraints

This results in the function being converted to Promisified function implicitly as my understanding is. The return type of the function is automatically promisified.

It is a requirement for a function signature to be declared as async, for one to be able to have an await call inside the method/function/procedure body.

Current also used to cascade communicate to a top level the intrinsic of this function execution behaviour details that it has some out of order execution or benefit from some IRQ work.

Question to ask yourself what communicating these intrinsic details benefit us?
For one it allows us to determine if all the code is sync or whether some of it is async. This helps us upfront know whether creating a task async work of 10000X the same function may potentially yield any performance gain in execution. If all code is syncness then it is performance degradation, if their potentially is async code in their, then we know may benefit from async execution.

When looking at what the async modifier cascade keyword can communicate to us, consider this when reading this proposal, because it is a very small amount of information, but still important to know up front as may await many task, but if the function at top level is not have async return type, the we shall use the await async loop (fun - 1, fun - 2, fun - 3, fun - 4), which cause them to be launched async, which is what we want.

By still having the async function modifier keyword used to hit or communicate the intrinsic behaviours of a function that their is some async work load in here.

We can emit compiler warning when async is called on a function that has absolute no async work in it, say that there be no benefit of this, unless another thread execution which rare case or when its a procedure and we don’t care about the results.

If were explicitly async of a loop of a 10000 X async workloads were the return type is number, but the function being called is async modifier keyword prefix, then we wouldn’t emit a warning, because their would potentially be a speed up.

Visa versa the compiler can also give a hit to say you may benefit from executing this code async as it know their is some async workload in their intrinsically by the prefix async keyword modifier.

It would be great if I could make this async keyword visible in a function name, which means we don’t have to rely on the compiler to help us out at a top level as to how we should be executing this function. So function with async prefix keyword, is used to communicate, that in this function body there is a call some to async workload and can only be used if the return type of the function is not a promise or async return type.

Wait what if we implement a new suffix convention, that any function with the async prefix keyword modifier, name must have in its name otherwise it is an error.
What shall it be Async already means it return a promise all has the raw code to deal with IO, IRQ extra.. Or provides some very light weight security wrapper or something.

Let take a vote without thinking too much how about the keyword how about, Vsync, its like async, but only happen in a single plain, and is already well know and has a nice own to it. Mabye PSync for partially sync..

Guess the only pitfall is if we decide to differentiate between async work that can run on a single thread of execution or run on multiple threads, it would be good to know which function support which modes for a designer perspective, and we could implement another keyword. XSync means it potentially can run across multiple threads/cores, but then again I would prefer to do analysis on the parameters that should be passed in.
Can enforce constraints on all variables referenced in the body of the function, that have be of local scope or have had some locking and things like that. But then I think their ward was to potentially constrain a pattern so that things are not blocking, but that's the next step.

Gripes, pitfalls, performance loss of this method.

This is a top approach to promisifcation creating async task or work flow, it is the approach that C# has taken. Feels like a direct copy actually, javascript has promises.

As in c# this top level approach to create async running function, violates encapsulation if you think of it, because now the top level function needs to know about async work.
Typically we want to hide implementation details, no one, should need to know that this function has code in it that runs asyncly, that is implementation details, that no needs to know that.

Current methods, that take callback and run the callback asyncly, now have to implement async await versions of all nifty forEach function and all the rest, to run as expected sync code. So the callback style of writing code is out the window for already existing functions and it will break them, make life a pain when wanting to upgrade and use simple sync callback functions, no harmony here.

If one wants to await an async workload inside a function body, then one has to current make this function an async function by adding the prefix modifier. Now at the next function that calls this, you will have to now once again by default have to await it then by requirement have make the caller function async, this then cascades all the way to the root of your program. Everything then is promisified.

Everything becomes promisified, when wrap a single async IO function with a whole bunch of sync code, that actually performs the logic and sync manipulation. This means everything now has the overheads of promises, they're no longer is a light weight function, if any function in the neasted call heighrache at the bottom contained async method, their every other function now bears the overheard, this is crazy. Were one could rather have just had all the sync code run before the await workload(promise) and sync code run afterwards.

New -> meaning/functionality/constraints.

This keyword function acts as a constraint, as in c#, it requires that async work(workload) method/function/procedure to have been call in here at least, and emits a compiler warning with typescript, that can be disabled, just like in c#, when its missing.
When we say it can call async work (workload), what that entails is a new definition, see above definition explanation.

It no longer is a requirement for the function in which their is await in the body, to have the async keyword, you call await anywhere you want on function that has promise(async) return type. The only requirement now will be for the caller function to have the modifier or just the suffix of PSync, don’t need duplicate work. As the function name is really the only readable peace of information as prefix and suffix, async/return type can’t be read only interrogate by a compiler. Mabye to speed up compilering - can be allowed infunction names, which allows us to simplere differential, the suffix faster fo the compiler, however it 4 chars we have 8 char wide ascii, so single compartive op on end of string, just may not be register align, which may it slower.. Not point really for the dash.

It will no longer create an async function that will be the job of async keyword calling a function that modifies it into a task, async work load, explicitly their in the caller function body were the function is being called or the return type of promise or new suffix async keyword, which implicity makes it imediately execute and requires await, as the return type is of type async.

Yes, probably took the approach to do it at function level, as to prevent too my code generation, but better this way, beside, generate both sync and async version of a function, but at much higher level, which results in a much larger workload sharing the same stack, as function would naturally allow themselves to be inlined or collapsed.

It is merely now use as a hit to caller functions that this method has some calls to async work, could be enforce, would really make no difference, just be good for debugging on text base editor, with now ide, to provide hint that the call contains some async code. Actually go see the function comment question about this above, that is much better PSync..

The return type in typescript should be used to communicate asynctask, make a specially return type name should be used. Could use async before the fun () : async void

This means that foreach simple methods like this will now work by default, as the function is not converted to an async executing block of code, only awaited(async work load) in the call back will be.

Performance gain only experience the async workload overhead were an await statement is used and nowhere else, as as the cascading problem has been avoided. Be nice to await prom1, prom2, prom2.

Prefix async modifier can still be used

Change B:

Return type dictates with a function is async or not and method name for readability must have async in it.
Just like is currently happening the return type of a function if a promise is async work loaded, Promise introduction of the use of async in the return type before the actually function return type, could be a more language formal abstraction name, instead of Promise.. Just register return type async as Promise at runtime.

For sanity purposes when reading function calls, to be able to differential the correct code execution behaviour and predict it in text form. A function with an async return type, name must all have a suffix of async, otherwise it is an error. This also allows on to later automatically route between async/sync function calls, were there exists to specific implementations. A sync one and async one, were be differential by name, since javascript doesn’t know of any types in the first place.

We could also say if we use the suffix, that their is not point to have to stutter and use the async keyword and the Async suffix, the one is implied by the other, but only the one implied from the readable name, should be allowed as we are going for code readability here at a glance one needs to know what is going on.

Most importantly, this means that a function when refactored, is change from a return type Promise to void it can be detected and the compiler can emit errors for procedural calls, in older old, were async suffix is not enforce, the behaviour change can now be spotted. I don’t see any other way, here unless add a keyword to proceed the function call, which then become extremely verbose and not be backward compatible.

myFun() // which is actually myFunc() : (async) Promise
// versus can be differentiated clearly., in future.
myFun() // which is actually myFunc() : (async) void

Change C: async myfunc()

Aysnc function call modifier

Const handle = async mySyncFun(); …. Code on the current stack to be execute. Await handle

myFun() // which is actually myFunc() : (async) Promise<void> // versus can be differentiated. myFun() // which is actually myFunc() : (async) void

The keyword async infront of a function call will now allow us to automatically convert any code to a task, aysnc workload that can be executed.
Their should be good inlining of code before and actually await, that functionality is nestled deep in the code, that no needs to know about encapsulation.

Change D: async workload function calls parameters introduce ref keyword, for parameters that are not from the local function bock are require to be called with ref, to say I want a referance..
This going to be a breaking change that typically only typescript could enforce with typings.

@ljharb

This comment has been minimized.

Show comment
Hide comment
@ljharb

ljharb Jul 10, 2018

Member

@wesleyolis Thanks for your thorough writeup of your thoughts.

As you hinted at the beginning, es-discuss, not here, is the better place to have this discussion.

Member

ljharb commented Jul 10, 2018

@wesleyolis Thanks for your thorough writeup of your thoughts.

As you hinted at the beginning, es-discuss, not here, is the better place to have this discussion.

@ljharb ljharb closed this Jul 10, 2018

@wesleyolis

This comment has been minimized.

Show comment
Hide comment
@wesleyolis

wesleyolis Jul 10, 2018

@ljharb I would love to have the discussion their, but still block from the mailing list and have yet to get any emails for account authorisation, so I still can't submit anything to them at all. So this partially the next best thing, until I can end up being authorised..

Change E: Async Pattern

One grip, the introduce of the async keyword modifier, should not enforce a default promise or task library to be used(shim), but on a library implementation that means a certain interface requirement be met. Which means the ecosystem is still open innovation as provide async, await conforming implementation for the return type of promise or task that implements the behaviour interface. We also can import multiple different async library versions and they can all work together in the same file, with no issues. This means the way in which we deal with async type code with await, async approach, is also future proofed any other similar patterns to which async await lend themselves to, were may be more specialized threading functionality developed.

This interface is to be implemented by a promise library, which once imported,
will register this function with the async harnus provided by typescript.
Typescript must support multiple harnus implementations.
Async hardnus life cycle only exist for the period that it is imported.
Typescript, will iterate all registered implementations of AsyncPatternBase to find the appropriate matching AsycBase type implementation, implementation functions to call.

// This interface is the contract behaviour that each promise library would be required to implement at minimum, to work with async pattern.

Interface AsyncBase
{
New : ..
Then :
Catch :
Callback :
Resolve :	// internal
Cancel :	// ability to terminate.
Convert : 	// convert a promise from another library, circular reference, warning
}

// wire up the async pattern behaviour for each library to be registered with the async pattern harnus.

Interface AsyncPatternBase<T extends AsyncBase>
{
	readableSufficForFunctionContainingAsyncWorkLoad : string
	readableSuffixForAsyncReturn: string
	async: : <T>(fun : () => T) => Wrapper<T>
await : <T>(Wrapper<T>) => T 
}

wesleyolis commented Jul 10, 2018

@ljharb I would love to have the discussion their, but still block from the mailing list and have yet to get any emails for account authorisation, so I still can't submit anything to them at all. So this partially the next best thing, until I can end up being authorised..

Change E: Async Pattern

One grip, the introduce of the async keyword modifier, should not enforce a default promise or task library to be used(shim), but on a library implementation that means a certain interface requirement be met. Which means the ecosystem is still open innovation as provide async, await conforming implementation for the return type of promise or task that implements the behaviour interface. We also can import multiple different async library versions and they can all work together in the same file, with no issues. This means the way in which we deal with async type code with await, async approach, is also future proofed any other similar patterns to which async await lend themselves to, were may be more specialized threading functionality developed.

This interface is to be implemented by a promise library, which once imported,
will register this function with the async harnus provided by typescript.
Typescript must support multiple harnus implementations.
Async hardnus life cycle only exist for the period that it is imported.
Typescript, will iterate all registered implementations of AsyncPatternBase to find the appropriate matching AsycBase type implementation, implementation functions to call.

// This interface is the contract behaviour that each promise library would be required to implement at minimum, to work with async pattern.

Interface AsyncBase
{
New : ..
Then :
Catch :
Callback :
Resolve :	// internal
Cancel :	// ability to terminate.
Convert : 	// convert a promise from another library, circular reference, warning
}

// wire up the async pattern behaviour for each library to be registered with the async pattern harnus.

Interface AsyncPatternBase<T extends AsyncBase>
{
	readableSufficForFunctionContainingAsyncWorkLoad : string
	readableSuffixForAsyncReturn: string
	async: : <T>(fun : () => T) => Wrapper<T>
await : <T>(Wrapper<T>) => T 
}
@ljharb

This comment has been minimized.

Show comment
Hide comment
@ljharb

ljharb Jul 10, 2018

Member

@wesleyolis in that case I think the best option is to wait, silently, until you've gotten access. You may want to check your spam folder; others seem able to join the list just fine.

Regardless, this is all rather long, and it's not clear to me what you're asking for - this seems like it might be a better blog post?

Member

ljharb commented Jul 10, 2018

@wesleyolis in that case I think the best option is to wait, silently, until you've gotten access. You may want to check your spam folder; others seem able to join the list just fine.

Regardless, this is all rather long, and it's not clear to me what you're asking for - this seems like it might be a better blog post?

@allenwb

This comment has been minimized.

Show comment
Hide comment
@allenwb

allenwb Jul 11, 2018

Member

@wesleyolis what email address do you think is blocked for you on es-discuss?

I don't see a user record that looks like it might be you and there aren't any pending administrator requests.

When did you last try to subscribe via https://mail.mozilla.org/listinfo/es-discuss

Member

allenwb commented Jul 11, 2018

@wesleyolis what email address do you think is blocked for you on es-discuss?

I don't see a user record that looks like it might be you and there aren't any pending administrator requests.

When did you last try to subscribe via https://mail.mozilla.org/listinfo/es-discuss

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment