Reflection to know if executed within a generator/async ?

classic Classic list List threaded Threaded
27 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Reflection to know if executed within a generator/async ?

Andrea Giammarchi-2
Hi there,
  just writing down some thoughts about being able to understand if a method/function has been  executed within a generator/async and is being yielded/awaited.

Rationale: API that would like to behave synchronously in some case, returning Promises in other cases.

Example:

```js
function fileGetContent(fileName) {
  // random example
  if (held) {
    return fetch(fileName).then((r)=>r.text());
  } else {
    var xhr = new XMLHttpRequest;
    xhr.open('GET', fileName, false);
    xhr.send(null);
    return xhr.responseText;
  }
}
```

Above example will virtually return always the same type and it could work inside a generator or an  async function as long as it's being held.

Does any of this make sense? Is it worth exploring this pattern?

Thanks for any sort of thought.

Best  Regards





_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Reflection to know if executed within a generator/async ?

John Lenz-4
I don't think being executed in a generator or async function is a good signal that a promise should be returned (something needs to "await" the promise).   The async function is really a chain of synchronous code split at various points, during the synchronous parts the code would still need to be synchronous and returning a promise would be wrong.   The real data you need is "will this value be consumed by an 'await' expression or be used to resolve a Promise and, in the general case,  that is not something that can't be answered at the time your example function is executing.

On Thu, Dec 3, 2015 at 4:15 AM, Andrea Giammarchi <[hidden email]> wrote:
Hi there,
  just writing down some thoughts about being able to understand if a method/function has been  executed within a generator/async and is being yielded/awaited.

Rationale: API that would like to behave synchronously in some case, returning Promises in other cases.

Example:

```js
function fileGetContent(fileName) {
  // random example
  if (held) {
    return fetch(fileName).then((r)=>r.text());
  } else {
    var xhr = new XMLHttpRequest;
    xhr.open('GET', fileName, false);
    xhr.send(null);
    return xhr.responseText;
  }
}
```

Above example will virtually return always the same type and it could work inside a generator or an  async function as long as it's being held.

Does any of this make sense? Is it worth exploring this pattern?

Thanks for any sort of thought.

Best  Regards





_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Reflection to know if executed within a generator/async ?

Andrea Giammarchi-2
Uhm... you never closed that "will this value be .... thing and I'm expecting a "dary" answer like in few emails but my whole point is consuming  an API in different scenarios: held or synchronous.

You can always create an API that always returns a Promise, that's nothing new for the language, but can you decide if it's he case to absolutely return a promise 'cause any other value would cause trouble within that generator or async function?

On Thu, Dec 3, 2015 at 4:15 PM, John Lenz <[hidden email]> wrote:
I don't think being executed in a generator or async function is a good signal that a promise should be returned (something needs to "await" the promise).   The async function is really a chain of synchronous code split at various points, during the synchronous parts the code would still need to be synchronous and returning a promise would be wrong.   The real data you need is "will this value be consumed by an 'await' expression or be used to resolve a Promise and, in the general case,  that is not something that can't be answered at the time your example function is executing.

On Thu, Dec 3, 2015 at 4:15 AM, Andrea Giammarchi <[hidden email]> wrote:
Hi there,
  just writing down some thoughts about being able to understand if a method/function has been  executed within a generator/async and is being yielded/awaited.

Rationale: API that would like to behave synchronously in some case, returning Promises in other cases.

Example:

```js
function fileGetContent(fileName) {
  // random example
  if (held) {
    return fetch(fileName).then((r)=>r.text());
  } else {
    var xhr = new XMLHttpRequest;
    xhr.open('GET', fileName, false);
    xhr.send(null);
    return xhr.responseText;
  }
}
```

Above example will virtually return always the same type and it could work inside a generator or an  async function as long as it's being held.

Does any of this make sense? Is it worth exploring this pattern?

Thanks for any sort of thought.

Best  Regards





_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Reflection to know if executed within a generator/async ?

Bradley Meck
I am against any semantics that expose how a function is used. I struggle and many others do when this occurs in CSS (display varies depending on container). I would also be hesitant to encourage things acting both synchronously and asynchronously depending on how they are used. Changing temporal behavior depending on usage is asking for race conditions.

On Thu, Dec 3, 2015 at 10:37 AM, Andrea Giammarchi <[hidden email]> wrote:
Uhm... you never closed that "will this value be .... thing and I'm expecting a "dary" answer like in few emails but my whole point is consuming  an API in different scenarios: held or synchronous.

You can always create an API that always returns a Promise, that's nothing new for the language, but can you decide if it's he case to absolutely return a promise 'cause any other value would cause trouble within that generator or async function?

On Thu, Dec 3, 2015 at 4:15 PM, John Lenz <[hidden email]> wrote:
I don't think being executed in a generator or async function is a good signal that a promise should be returned (something needs to "await" the promise).   The async function is really a chain of synchronous code split at various points, during the synchronous parts the code would still need to be synchronous and returning a promise would be wrong.   The real data you need is "will this value be consumed by an 'await' expression or be used to resolve a Promise and, in the general case,  that is not something that can't be answered at the time your example function is executing.

On Thu, Dec 3, 2015 at 4:15 AM, Andrea Giammarchi <[hidden email]> wrote:
Hi there,
  just writing down some thoughts about being able to understand if a method/function has been  executed within a generator/async and is being yielded/awaited.

Rationale: API that would like to behave synchronously in some case, returning Promises in other cases.

Example:

```js
function fileGetContent(fileName) {
  // random example
  if (held) {
    return fetch(fileName).then((r)=>r.text());
  } else {
    var xhr = new XMLHttpRequest;
    xhr.open('GET', fileName, false);
    xhr.send(null);
    return xhr.responseText;
  }
}
```

Above example will virtually return always the same type and it could work inside a generator or an  async function as long as it's being held.

Does any of this make sense? Is it worth exploring this pattern?

Thanks for any sort of thought.

Best  Regards





_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Reflection to know if executed within a generator/async ?

Claude Pache
In reply to this post by Andrea Giammarchi-2
How would you detect that the following call to your `fileGetContent` function should return a Promise?

```js
function oldSchool() {
    return fileGetContent("foo").then(function (c) {
        // ....
    })
}
```

—Claude


> Le 3 déc. 2015 à 13:15, Andrea Giammarchi <[hidden email]> a écrit :
>
> Hi there,
>   just writing down some thoughts about being able to understand if a method/function has been  executed within a generator/async and is being yielded/awaited.
>
> Rationale: API that would like to behave synchronously in some case, returning Promises in other cases.
>
> Example:
>
> ```js
> function fileGetContent(fileName) {
>   // random example
>   if (held) {
>     return fetch(fileName).then((r)=>r.text());
>   } else {
>     var xhr = new XMLHttpRequest;
>     xhr.open('GET', fileName, false);
>     xhr.send(null);
>     return xhr.responseText;
>   }
> }
> ```
>
> Above example will virtually return always the same type and it could work inside a generator or an  async function as long as it's being held.
>
> Does any of this make sense? Is it worth exploring this pattern?
>
> Thanks for any sort of thought.
>
> Best  Regards
>
>
>
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

RE: Reflection to know if executed within a generator/async ?

Ron Buckton
In reply to this post by Bradley Meck

I agree with Bradley, and kindly refer you to this oft referenced blog post regarding synchronous and asynchronous APIs: http://blog.ometer.com/2011/07/24/callbacks-synchronous-and-asynchronous/

 

Ron

 

 


From: Bradley Meck
Sent: Thursday, December 3, 2015 8:57 AM
To: Andrea Giammarchi
Cc: [hidden email]
Subject: Re: Reflection to know if executed within a generator/async ?

 

 

I am against any semantics that expose how a function is used. I struggle and many others do when this occurs in CSS (display varies depending on container). I would also be hesitant to encourage things acting both synchronously and asynchronously depending on how they are used. Changing temporal behavior depending on usage is asking for race conditions.

On Thu, Dec 3, 2015 at 10:37 AM, Andrea Giammarchi <[hidden email]> wrote:
Uhm... you never closed that "will this value be .... thing and I'm expecting a "dary" answer like in few emails but my whole point is consuming  an API in different scenarios: held or synchronous.

You can always create an API that always returns a Promise, that's nothing new for the language, but can you decide if it's he case to absolutely return a promise 'cause any other value would cause trouble within that generator or async function?

On Thu, Dec 3, 2015 at 4:15 PM, John Lenz <[hidden email]> wrote:
I don't think being executed in a generator or async function is a good signal that a promise should be returned (something needs to "await" the promise).   The async function is really a chain of synchronous code split at various points, during the synchronous parts the code would still need to be synchronous and returning a promise would be wrong.   The real data you need is "will this value be consumed by an 'await' expression or be used to resolve a Promise and, in the general case,  that is not something that can't be answered at the time your example function is executing.

On Thu, Dec 3, 2015 at 4:15 AM, Andrea Giammarchi <[hidden email]> wrote:
Hi there,
  just writing down some thoughts about being able to understand if a method/function has been  executed within a generator/async and is being yielded/awaited.

Rationale: API that would like to behave synchronously in some case, returning Promises in other cases.

Example:

```js
function fileGetContent(fileName) {
  // random example
  if (held) {
    return fetch(fileName).then((r)=>r.text());
  } else {
    var xhr = new XMLHttpRequest;
    xhr.open('GET', fileName, false);
    xhr.send(null);
    return xhr.responseText;
  }
}
```

Above example will virtually return always the same type and it could work inside a generator or an  async function as long as it's being held.

Does any of this make sense? Is it worth exploring this pattern?

Thanks for any sort of thought.

Best  Regards





_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Reflection to know if executed within a generator/async ?

Andrea Giammarchi-2
In reply to this post by Claude Pache
I guess `held` would be like an arrow function, "transparent" when it comes to held invokes (like context or arguments)

On Thu, Dec 3, 2015 at 5:23 PM, Claude Pache <[hidden email]> wrote:
How would you detect that the following call to your `fileGetContent` function should return a Promise?

```js
function oldSchool() {
    return fileGetContent("foo").then(function (c) {
        // ....
    })
}
```

—Claude


> Le 3 déc. 2015 à 13:15, Andrea Giammarchi <[hidden email]> a écrit :
>
> Hi there,
>   just writing down some thoughts about being able to understand if a method/function has been  executed within a generator/async and is being yielded/awaited.
>
> Rationale: API that would like to behave synchronously in some case, returning Promises in other cases.
>
> Example:
>
> ```js
> function fileGetContent(fileName) {
>   // random example
>   if (held) {
>     return fetch(fileName).then((r)=>r.text());
>   } else {
>     var xhr = new XMLHttpRequest;
>     xhr.open('GET', fileName, false);
>     xhr.send(null);
>     return xhr.responseText;
>   }
> }
> ```
>
> Above example will virtually return always the same type and it could work inside a generator or an  async function as long as it's being held.
>
> Does any of this make sense? Is it worth exploring this pattern?
>
> Thanks for any sort of thought.
>
> Best  Regards
>
>
>
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Reflection to know if executed within a generator/async ?

Andrea Giammarchi-2
In reply to this post by Ron Buckton
Ron it's not about being ambiguous, it's actually the opposite: know when returning directly a value would actually break "outside expectations"

So my idea is to indeed offer either a sync or an async result and not both (in  terms of same execution context/scope/logic)

On Thu, Dec 3, 2015 at 5:48 PM, Ron Buckton <[hidden email]> wrote:

I agree with Bradley, and kindly refer you to this oft referenced blog post regarding synchronous and asynchronous APIs: http://blog.ometer.com/2011/07/24/callbacks-synchronous-and-asynchronous/

 

Ron

 

 


From: Bradley Meck
Sent: Thursday, December 3, 2015 8:57 AM
To: Andrea Giammarchi
Cc: [hidden email]
Subject: Re: Reflection to know if executed within a generator/async ?

 

 

I am against any semantics that expose how a function is used. I struggle and many others do when this occurs in CSS (display varies depending on container). I would also be hesitant to encourage things acting both synchronously and asynchronously depending on how they are used. Changing temporal behavior depending on usage is asking for race conditions.

On Thu, Dec 3, 2015 at 10:37 AM, Andrea Giammarchi <[hidden email]> wrote:
Uhm... you never closed that "will this value be .... thing and I'm expecting a "dary" answer like in few emails but my whole point is consuming  an API in different scenarios: held or synchronous.

You can always create an API that always returns a Promise, that's nothing new for the language, but can you decide if it's he case to absolutely return a promise 'cause any other value would cause trouble within that generator or async function?

On Thu, Dec 3, 2015 at 4:15 PM, John Lenz <[hidden email]> wrote:
I don't think being executed in a generator or async function is a good signal that a promise should be returned (something needs to "await" the promise).   The async function is really a chain of synchronous code split at various points, during the synchronous parts the code would still need to be synchronous and returning a promise would be wrong.   The real data you need is "will this value be consumed by an 'await' expression or be used to resolve a Promise and, in the general case,  that is not something that can't be answered at the time your example function is executing.

On Thu, Dec 3, 2015 at 4:15 AM, Andrea Giammarchi <[hidden email]> wrote:
Hi there,
  just writing down some thoughts about being able to understand if a method/function has been  executed within a generator/async and is being yielded/awaited.

Rationale: API that would like to behave synchronously in some case, returning Promises in other cases.

Example:

```js
function fileGetContent(fileName) {
  // random example
  if (held) {
    return fetch(fileName).then((r)=>r.text());
  } else {
    var xhr = new XMLHttpRequest;
    xhr.open('GET', fileName, false);
    xhr.send(null);
    return xhr.responseText;
  }
}
```

Above example will virtually return always the same type and it could work inside a generator or an  async function as long as it's being held.

Does any of this make sense? Is it worth exploring this pattern?

Thanks for any sort of thought.

Best  Regards





_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Reflection to know if executed within a generator/async ?

Claude Pache
In reply to this post by Andrea Giammarchi-2

Le 3 déc. 2015 à 20:04, Andrea Giammarchi <[hidden email]> a écrit :

I guess `held` would be like an arrow function, "transparent" when it comes to held invokes (like context or arguments)

? Sorry, but I don't understand how that would help to answer my question. 

—Claude 


On Thu, Dec 3, 2015 at 5:23 PM, Claude Pache <[hidden email]> wrote:
How would you detect that the following call to your `fileGetContent` function should return a Promise?

```js
function oldSchool() {
    return fileGetContent("foo").then(function (c) {
        // ....
    })
}
```

—Claude


> Le 3 déc. 2015 à 13:15, Andrea Giammarchi <[hidden email]> a écrit :
>
> Hi there,
>   just writing down some thoughts about being able to understand if a method/function has been  executed within a generator/async and is being yielded/awaited.
>
> Rationale: API that would like to behave synchronously in some case, returning Promises in other cases.
>
> Example:
>
> ```js
> function fileGetContent(fileName) {
>   // random example
>   if (held) {
>     return fetch(fileName).then((r)=>r.text());
>   } else {
>     var xhr = new XMLHttpRequest;
>     xhr.open('GET', fileName, false);
>     xhr.send(null);
>     return xhr.responseText;
>   }
> }
> ```
>
> Above example will virtually return always the same type and it could work inside a generator or an  async function as long as it's being held.
>
> Does any of this make sense? Is it worth exploring this pattern?
>
> Thanks for any sort of thought.
>
> Best  Regards
>
>
>
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Reflection to know if executed within a generator/async ?

Andrea Giammarchi-2
Sorry I misread your code. Your case assumes fileGetContent always returns a Promise so my proposal won't be useful there because it's already used as Promise.

My idea is more about migrating to full async code without changing all the things around, giving an API the ability to behave differently.

Maybe it's too complicated or too magic to implement, that's OK anyway.

On Thu, Dec 3, 2015 at 8:59 PM, Claude Pache <[hidden email]> wrote:

Le 3 déc. 2015 à 20:04, Andrea Giammarchi <[hidden email]> a écrit :

I guess `held` would be like an arrow function, "transparent" when it comes to held invokes (like context or arguments)

? Sorry, but I don't understand how that would help to answer my question. 

—Claude 


On Thu, Dec 3, 2015 at 5:23 PM, Claude Pache <[hidden email]> wrote:
How would you detect that the following call to your `fileGetContent` function should return a Promise?

```js
function oldSchool() {
    return fileGetContent("foo").then(function (c) {
        // ....
    })
}
```

—Claude


> Le 3 déc. 2015 à 13:15, Andrea Giammarchi <[hidden email]> a écrit :
>
> Hi there,
>   just writing down some thoughts about being able to understand if a method/function has been  executed within a generator/async and is being yielded/awaited.
>
> Rationale: API that would like to behave synchronously in some case, returning Promises in other cases.
>
> Example:
>
> ```js
> function fileGetContent(fileName) {
>   // random example
>   if (held) {
>     return fetch(fileName).then((r)=>r.text());
>   } else {
>     var xhr = new XMLHttpRequest;
>     xhr.open('GET', fileName, false);
>     xhr.send(null);
>     return xhr.responseText;
>   }
> }
> ```
>
> Above example will virtually return always the same type and it could work inside a generator or an  async function as long as it's being held.
>
> Does any of this make sense? Is it worth exploring this pattern?
>
> Thanks for any sort of thought.
>
> Best  Regards
>
>
>
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Reflection to know if executed within a generator/async ?

Jordan Harband
I think that migration path is typically 1) make the breaking change so that everything returns a promise ASAP, 2) seamlessly migrate sync parts to async at your leisure, without a breaking change.

On Thu, Dec 3, 2015 at 1:07 PM, Andrea Giammarchi <[hidden email]> wrote:
Sorry I misread your code. Your case assumes fileGetContent always returns a Promise so my proposal won't be useful there because it's already used as Promise.

My idea is more about migrating to full async code without changing all the things around, giving an API the ability to behave differently.

Maybe it's too complicated or too magic to implement, that's OK anyway.

On Thu, Dec 3, 2015 at 8:59 PM, Claude Pache <[hidden email]> wrote:

Le 3 déc. 2015 à 20:04, Andrea Giammarchi <[hidden email]> a écrit :

I guess `held` would be like an arrow function, "transparent" when it comes to held invokes (like context or arguments)

? Sorry, but I don't understand how that would help to answer my question. 

—Claude 


On Thu, Dec 3, 2015 at 5:23 PM, Claude Pache <[hidden email]> wrote:
How would you detect that the following call to your `fileGetContent` function should return a Promise?

```js
function oldSchool() {
    return fileGetContent("foo").then(function (c) {
        // ....
    })
}
```

—Claude


> Le 3 déc. 2015 à 13:15, Andrea Giammarchi <[hidden email]> a écrit :
>
> Hi there,
>   just writing down some thoughts about being able to understand if a method/function has been  executed within a generator/async and is being yielded/awaited.
>
> Rationale: API that would like to behave synchronously in some case, returning Promises in other cases.
>
> Example:
>
> ```js
> function fileGetContent(fileName) {
>   // random example
>   if (held) {
>     return fetch(fileName).then((r)=>r.text());
>   } else {
>     var xhr = new XMLHttpRequest;
>     xhr.open('GET', fileName, false);
>     xhr.send(null);
>     return xhr.responseText;
>   }
> }
> ```
>
> Above example will virtually return always the same type and it could work inside a generator or an  async function as long as it's being held.
>
> Does any of this make sense? Is it worth exploring this pattern?
>
> Thanks for any sort of thought.
>
> Best  Regards
>
>
>
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Reflection to know if executed within a generator/async ?

Claude Pache
In reply to this post by Andrea Giammarchi-2

Le 3 déc. 2015 à 22:07, Andrea Giammarchi <[hidden email]> a écrit :

Sorry I misread your code. Your case assumes fileGetContent always returns a Promise so my proposal won't be useful there because it's already used as Promise.

You can remove that assumption by replacing `fileGetContent("foo")` with `Promise.resolve(fileGetContent("foo"))`.


My idea is more about migrating to full async code without changing all the things around, giving an API the ability to behave differently.

The key fact of my example is that I can (and do) write full async code without generators or async functions (just with ES3 + Promise), and you have no way to detect that.
For example, the following code:

```js
function bar() {
    return Promise.resolve(fileGetContent("foo")).then(function (c) {
        // whatever
    })
}
```

is functionally equivalent to:

```js
async function bar() {
    const c = await fileGetContent("foo")
    // whatever
}
```

In both cases, I can receive a value or a promise for a value, and in both cases getting a promise is strictly better.
I don't want to be served an inferior version of `fileGetContent` in the first case just because you were unable to guess my intentions,
and I won’t hurry to migrate my existing code to use the second pattern, because the difference is only cosmetic.

—Claude




Maybe it's too complicated or too magic to implement, that's OK anyway.

On Thu, Dec 3, 2015 at 8:59 PM, Claude Pache <[hidden email]> wrote:

Le 3 déc. 2015 à 20:04, Andrea Giammarchi <[hidden email]> a écrit :

I guess `held` would be like an arrow function, "transparent" when it comes to held invokes (like context or arguments)

? Sorry, but I don't understand how that would help to answer my question. 

—Claude 


On Thu, Dec 3, 2015 at 5:23 PM, Claude Pache <[hidden email]> wrote:
How would you detect that the following call to your `fileGetContent` function should return a Promise?

```js
function oldSchool() {
    return fileGetContent("foo").then(function (c) {
        // ....
    })
}
```

—Claude


> Le 3 déc. 2015 à 13:15, Andrea Giammarchi <[hidden email]> a écrit :
>
> Hi there,
>   just writing down some thoughts about being able to understand if a method/function has been  executed within a generator/async and is being yielded/awaited.
>
> Rationale: API that would like to behave synchronously in some case, returning Promises in other cases.
>
> Example:
>
> ```js
> function fileGetContent(fileName) {
>   // random example
>   if (held) {
>     return fetch(fileName).then((r)=>r.text());
>   } else {
>     var xhr = new XMLHttpRequest;
>     xhr.open('GET', fileName, false);
>     xhr.send(null);
>     return xhr.responseText;
>   }
> }
> ```
>
> Above example will virtually return always the same type and it could work inside a generator or an  async function as long as it's being held.
>
> Does any of this make sense? Is it worth exploring this pattern?
>
> Thanks for any sort of thought.
>
> Best  Regards
>
>
>
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss





_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Reflection to know if executed within a generator/async ?

Andrea Giammarchi-2
Jordan please let's avoid discussions about migration patterns, I'm sure we've all done that and we all know how to. This is not the point of my idea.

Claude, again, you are using promises already so you won't need this "magic".  Your API returns promises,  you are good to update to async/await or generators.

However, in the future you won't write promises directly if not as returning values within some method .... right ?

Looking at your code, I would always go for the second pattern instead of the first one. So what if you'd like to use that already, simply adding async and await and the only change to do in a well known/used *synchronous* API would be to check if the returned value is held and behave accordingly?

That would give you a way to easily migrate to non-blocking as API consumer, and an easy way as API author to update to a non blocking version without breaking compatibility with other consumers.

In this scenario,  you are still free to use `Promise.resolve(fileGetContent("foo"))` which not on hold and not concretely asynchronous in terms of `fileGetContent("foo")` operations, but as soon as you go for async/await or a generator that function will return a Promise for you.

I hope it's clear now what is my idea.

Regards




On Fri, Dec 4, 2015 at 6:41 AM, Claude Pache <[hidden email]> wrote:

Le 3 déc. 2015 à 22:07, Andrea Giammarchi <[hidden email]> a écrit :

Sorry I misread your code. Your case assumes fileGetContent always returns a Promise so my proposal won't be useful there because it's already used as Promise.

You can remove that assumption by replacing `fileGetContent("foo")` with `Promise.resolve(fileGetContent("foo"))`.


My idea is more about migrating to full async code without changing all the things around, giving an API the ability to behave differently.

The key fact of my example is that I can (and do) write full async code without generators or async functions (just with ES3 + Promise), and you have no way to detect that.
For example, the following code:

```js
function bar() {
    return Promise.resolve(fileGetContent("foo")).then(function (c) {
        // whatever
    })
}
```

is functionally equivalent to:

```js
async function bar() {
    const c = await fileGetContent("foo")
    // whatever
}
```

In both cases, I can receive a value or a promise for a value, and in both cases getting a promise is strictly better.
I don't want to be served an inferior version of `fileGetContent` in the first case just because you were unable to guess my intentions,
and I won’t hurry to migrate my existing code to use the second pattern, because the difference is only cosmetic.

—Claude




Maybe it's too complicated or too magic to implement, that's OK anyway.

On Thu, Dec 3, 2015 at 8:59 PM, Claude Pache <[hidden email]> wrote:

Le 3 déc. 2015 à 20:04, Andrea Giammarchi <[hidden email]> a écrit :

I guess `held` would be like an arrow function, "transparent" when it comes to held invokes (like context or arguments)

? Sorry, but I don't understand how that would help to answer my question. 

—Claude 


On Thu, Dec 3, 2015 at 5:23 PM, Claude Pache <[hidden email]> wrote:
How would you detect that the following call to your `fileGetContent` function should return a Promise?

```js
function oldSchool() {
    return fileGetContent("foo").then(function (c) {
        // ....
    })
}
```

—Claude


> Le 3 déc. 2015 à 13:15, Andrea Giammarchi <[hidden email]> a écrit :
>
> Hi there,
>   just writing down some thoughts about being able to understand if a method/function has been  executed within a generator/async and is being yielded/awaited.
>
> Rationale: API that would like to behave synchronously in some case, returning Promises in other cases.
>
> Example:
>
> ```js
> function fileGetContent(fileName) {
>   // random example
>   if (held) {
>     return fetch(fileName).then((r)=>r.text());
>   } else {
>     var xhr = new XMLHttpRequest;
>     xhr.open('GET', fileName, false);
>     xhr.send(null);
>     return xhr.responseText;
>   }
> }
> ```
>
> Above example will virtually return always the same type and it could work inside a generator or an  async function as long as it's being held.
>
> Does any of this make sense? Is it worth exploring this pattern?
>
> Thanks for any sort of thought.
>
> Best  Regards
>
>
>
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss






_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Reflection to know if executed within a generator/async ?

Bradley Meck
The more I read about this the more I think that `await` is what you want to change *not the behavior of functions*. Rephrased to what I think is being asked:

If `await` encounters a non-thenable value, `Promise.resolve` the value before awaiting.

Isn't this already the case?

On Fri, Dec 4, 2015 at 2:44 AM, Andrea Giammarchi <[hidden email]> wrote:
Jordan please let's avoid discussions about migration patterns, I'm sure we've all done that and we all know how to. This is not the point of my idea.

Claude, again, you are using promises already so you won't need this "magic".  Your API returns promises,  you are good to update to async/await or generators.

However, in the future you won't write promises directly if not as returning values within some method .... right ?

Looking at your code, I would always go for the second pattern instead of the first one. So what if you'd like to use that already, simply adding async and await and the only change to do in a well known/used *synchronous* API would be to check if the returned value is held and behave accordingly?

That would give you a way to easily migrate to non-blocking as API consumer, and an easy way as API author to update to a non blocking version without breaking compatibility with other consumers.

In this scenario,  you are still free to use `Promise.resolve(fileGetContent("foo"))` which not on hold and not concretely asynchronous in terms of `fileGetContent("foo")` operations, but as soon as you go for async/await or a generator that function will return a Promise for you.

I hope it's clear now what is my idea.

Regards




On Fri, Dec 4, 2015 at 6:41 AM, Claude Pache <[hidden email]> wrote:

Le 3 déc. 2015 à 22:07, Andrea Giammarchi <[hidden email]> a écrit :

Sorry I misread your code. Your case assumes fileGetContent always returns a Promise so my proposal won't be useful there because it's already used as Promise.

You can remove that assumption by replacing `fileGetContent("foo")` with `Promise.resolve(fileGetContent("foo"))`.


My idea is more about migrating to full async code without changing all the things around, giving an API the ability to behave differently.

The key fact of my example is that I can (and do) write full async code without generators or async functions (just with ES3 + Promise), and you have no way to detect that.
For example, the following code:

```js
function bar() {
    return Promise.resolve(fileGetContent("foo")).then(function (c) {
        // whatever
    })
}
```

is functionally equivalent to:

```js
async function bar() {
    const c = await fileGetContent("foo")
    // whatever
}
```

In both cases, I can receive a value or a promise for a value, and in both cases getting a promise is strictly better.
I don't want to be served an inferior version of `fileGetContent` in the first case just because you were unable to guess my intentions,
and I won’t hurry to migrate my existing code to use the second pattern, because the difference is only cosmetic.

—Claude




Maybe it's too complicated or too magic to implement, that's OK anyway.

On Thu, Dec 3, 2015 at 8:59 PM, Claude Pache <[hidden email]> wrote:

Le 3 déc. 2015 à 20:04, Andrea Giammarchi <[hidden email]> a écrit :

I guess `held` would be like an arrow function, "transparent" when it comes to held invokes (like context or arguments)

? Sorry, but I don't understand how that would help to answer my question. 

—Claude 


On Thu, Dec 3, 2015 at 5:23 PM, Claude Pache <[hidden email]> wrote:
How would you detect that the following call to your `fileGetContent` function should return a Promise?

```js
function oldSchool() {
    return fileGetContent("foo").then(function (c) {
        // ....
    })
}
```

—Claude


> Le 3 déc. 2015 à 13:15, Andrea Giammarchi <[hidden email]> a écrit :
>
> Hi there,
>   just writing down some thoughts about being able to understand if a method/function has been  executed within a generator/async and is being yielded/awaited.
>
> Rationale: API that would like to behave synchronously in some case, returning Promises in other cases.
>
> Example:
>
> ```js
> function fileGetContent(fileName) {
>   // random example
>   if (held) {
>     return fetch(fileName).then((r)=>r.text());
>   } else {
>     var xhr = new XMLHttpRequest;
>     xhr.open('GET', fileName, false);
>     xhr.send(null);
>     return xhr.responseText;
>   }
> }
> ```
>
> Above example will virtually return always the same type and it could work inside a generator or an  async function as long as it's being held.
>
> Does any of this make sense? Is it worth exploring this pattern?
>
> Thanks for any sort of thought.
>
> Best  Regards
>
>
>
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss






_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Reflection to know if executed within a generator/async ?

Andrea Giammarchi-2
Eyes don't see, mind don't care?

The fact await doesn't break, if that's the case, is cool and glorious. The fact a consumed API would like to keep working with synchronous projects and **realy** behave asynchronously with most modern one, is a different thing.

To better describe a common use case,  think about CommonJS  `require('module')` API.

There's no way it should break on all platforms (not jsut node and browsers) that implemented CommonJS, it could still return a Promise, through my `held` like idea, for Web and new async based code.

async works with old code, old code cannot be promoted to async one. All I am trying to explain is that I'd love to give well known, de-facto standard, universally used APIs the ability to behave, for real, asynchronously whenever the future of the language is available.

How bad is that?

Regards






On Fri, Dec 4, 2015 at 1:59 PM, Bradley Meck <[hidden email]> wrote:
The more I read about this the more I think that `await` is what you want to change *not the behavior of functions*. Rephrased to what I think is being asked:

If `await` encounters a non-thenable value, `Promise.resolve` the value before awaiting.

Isn't this already the case?

On Fri, Dec 4, 2015 at 2:44 AM, Andrea Giammarchi <[hidden email]> wrote:
Jordan please let's avoid discussions about migration patterns, I'm sure we've all done that and we all know how to. This is not the point of my idea.

Claude, again, you are using promises already so you won't need this "magic".  Your API returns promises,  you are good to update to async/await or generators.

However, in the future you won't write promises directly if not as returning values within some method .... right ?

Looking at your code, I would always go for the second pattern instead of the first one. So what if you'd like to use that already, simply adding async and await and the only change to do in a well known/used *synchronous* API would be to check if the returned value is held and behave accordingly?

That would give you a way to easily migrate to non-blocking as API consumer, and an easy way as API author to update to a non blocking version without breaking compatibility with other consumers.

In this scenario,  you are still free to use `Promise.resolve(fileGetContent("foo"))` which not on hold and not concretely asynchronous in terms of `fileGetContent("foo")` operations, but as soon as you go for async/await or a generator that function will return a Promise for you.

I hope it's clear now what is my idea.

Regards




On Fri, Dec 4, 2015 at 6:41 AM, Claude Pache <[hidden email]> wrote:

Le 3 déc. 2015 à 22:07, Andrea Giammarchi <[hidden email]> a écrit :

Sorry I misread your code. Your case assumes fileGetContent always returns a Promise so my proposal won't be useful there because it's already used as Promise.

You can remove that assumption by replacing `fileGetContent("foo")` with `Promise.resolve(fileGetContent("foo"))`.


My idea is more about migrating to full async code without changing all the things around, giving an API the ability to behave differently.

The key fact of my example is that I can (and do) write full async code without generators or async functions (just with ES3 + Promise), and you have no way to detect that.
For example, the following code:

```js
function bar() {
    return Promise.resolve(fileGetContent("foo")).then(function (c) {
        // whatever
    })
}
```

is functionally equivalent to:

```js
async function bar() {
    const c = await fileGetContent("foo")
    // whatever
}
```

In both cases, I can receive a value or a promise for a value, and in both cases getting a promise is strictly better.
I don't want to be served an inferior version of `fileGetContent` in the first case just because you were unable to guess my intentions,
and I won’t hurry to migrate my existing code to use the second pattern, because the difference is only cosmetic.

—Claude




Maybe it's too complicated or too magic to implement, that's OK anyway.

On Thu, Dec 3, 2015 at 8:59 PM, Claude Pache <[hidden email]> wrote:

Le 3 déc. 2015 à 20:04, Andrea Giammarchi <[hidden email]> a écrit :

I guess `held` would be like an arrow function, "transparent" when it comes to held invokes (like context or arguments)

? Sorry, but I don't understand how that would help to answer my question. 

—Claude 


On Thu, Dec 3, 2015 at 5:23 PM, Claude Pache <[hidden email]> wrote:
How would you detect that the following call to your `fileGetContent` function should return a Promise?

```js
function oldSchool() {
    return fileGetContent("foo").then(function (c) {
        // ....
    })
}
```

—Claude


> Le 3 déc. 2015 à 13:15, Andrea Giammarchi <[hidden email]> a écrit :
>
> Hi there,
>   just writing down some thoughts about being able to understand if a method/function has been  executed within a generator/async and is being yielded/awaited.
>
> Rationale: API that would like to behave synchronously in some case, returning Promises in other cases.
>
> Example:
>
> ```js
> function fileGetContent(fileName) {
>   // random example
>   if (held) {
>     return fetch(fileName).then((r)=>r.text());
>   } else {
>     var xhr = new XMLHttpRequest;
>     xhr.open('GET', fileName, false);
>     xhr.send(null);
>     return xhr.responseText;
>   }
> }
> ```
>
> Above example will virtually return always the same type and it could work inside a generator or an  async function as long as it's being held.
>
> Does any of this make sense? Is it worth exploring this pattern?
>
> Thanks for any sort of thought.
>
> Best  Regards
>
>
>
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss






_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Reflection to know if executed within a generator/async ?

Bradley Meck
Be very clear, this is interesting, but dangerous.

I care very much but not in a positive way due to ironing out what would happen if the WHATWG Loader spec were to use Promises (either under the hood or explicitly). The amount of possible timing differences caused https://github.com/whatwg/loader/issues/54 which caused a huge refactor of the entire spec since timing implications of Promises are very different from synchronous code.

My thoughts on things can be summed up as: if timing change implicity/based upon situations outside of your code -> side effects change -> code can break based upon when it is being used (rather than how it is being called).

On Fri, Dec 4, 2015 at 11:31 AM, Andrea Giammarchi <[hidden email]> wrote:
Eyes don't see, mind don't care?

The fact await doesn't break, if that's the case, is cool and glorious. The fact a consumed API would like to keep working with synchronous projects and **realy** behave asynchronously with most modern one, is a different thing.

To better describe a common use case,  think about CommonJS  `require('module')` API.

There's no way it should break on all platforms (not jsut node and browsers) that implemented CommonJS, it could still return a Promise, through my `held` like idea, for Web and new async based code.

async works with old code, old code cannot be promoted to async one. All I am trying to explain is that I'd love to give well known, de-facto standard, universally used APIs the ability to behave, for real, asynchronously whenever the future of the language is available.

How bad is that?

Regards






On Fri, Dec 4, 2015 at 1:59 PM, Bradley Meck <[hidden email]> wrote:
The more I read about this the more I think that `await` is what you want to change *not the behavior of functions*. Rephrased to what I think is being asked:

If `await` encounters a non-thenable value, `Promise.resolve` the value before awaiting.

Isn't this already the case?

On Fri, Dec 4, 2015 at 2:44 AM, Andrea Giammarchi <[hidden email]> wrote:
Jordan please let's avoid discussions about migration patterns, I'm sure we've all done that and we all know how to. This is not the point of my idea.

Claude, again, you are using promises already so you won't need this "magic".  Your API returns promises,  you are good to update to async/await or generators.

However, in the future you won't write promises directly if not as returning values within some method .... right ?

Looking at your code, I would always go for the second pattern instead of the first one. So what if you'd like to use that already, simply adding async and await and the only change to do in a well known/used *synchronous* API would be to check if the returned value is held and behave accordingly?

That would give you a way to easily migrate to non-blocking as API consumer, and an easy way as API author to update to a non blocking version without breaking compatibility with other consumers.

In this scenario,  you are still free to use `Promise.resolve(fileGetContent("foo"))` which not on hold and not concretely asynchronous in terms of `fileGetContent("foo")` operations, but as soon as you go for async/await or a generator that function will return a Promise for you.

I hope it's clear now what is my idea.

Regards




On Fri, Dec 4, 2015 at 6:41 AM, Claude Pache <[hidden email]> wrote:

Le 3 déc. 2015 à 22:07, Andrea Giammarchi <[hidden email]> a écrit :

Sorry I misread your code. Your case assumes fileGetContent always returns a Promise so my proposal won't be useful there because it's already used as Promise.

You can remove that assumption by replacing `fileGetContent("foo")` with `Promise.resolve(fileGetContent("foo"))`.


My idea is more about migrating to full async code without changing all the things around, giving an API the ability to behave differently.

The key fact of my example is that I can (and do) write full async code without generators or async functions (just with ES3 + Promise), and you have no way to detect that.
For example, the following code:

```js
function bar() {
    return Promise.resolve(fileGetContent("foo")).then(function (c) {
        // whatever
    })
}
```

is functionally equivalent to:

```js
async function bar() {
    const c = await fileGetContent("foo")
    // whatever
}
```

In both cases, I can receive a value or a promise for a value, and in both cases getting a promise is strictly better.
I don't want to be served an inferior version of `fileGetContent` in the first case just because you were unable to guess my intentions,
and I won’t hurry to migrate my existing code to use the second pattern, because the difference is only cosmetic.

—Claude




Maybe it's too complicated or too magic to implement, that's OK anyway.

On Thu, Dec 3, 2015 at 8:59 PM, Claude Pache <[hidden email]> wrote:

Le 3 déc. 2015 à 20:04, Andrea Giammarchi <[hidden email]> a écrit :

I guess `held` would be like an arrow function, "transparent" when it comes to held invokes (like context or arguments)

? Sorry, but I don't understand how that would help to answer my question. 

—Claude 


On Thu, Dec 3, 2015 at 5:23 PM, Claude Pache <[hidden email]> wrote:
How would you detect that the following call to your `fileGetContent` function should return a Promise?

```js
function oldSchool() {
    return fileGetContent("foo").then(function (c) {
        // ....
    })
}
```

—Claude


> Le 3 déc. 2015 à 13:15, Andrea Giammarchi <[hidden email]> a écrit :
>
> Hi there,
>   just writing down some thoughts about being able to understand if a method/function has been  executed within a generator/async and is being yielded/awaited.
>
> Rationale: API that would like to behave synchronously in some case, returning Promises in other cases.
>
> Example:
>
> ```js
> function fileGetContent(fileName) {
>   // random example
>   if (held) {
>     return fetch(fileName).then((r)=>r.text());
>   } else {
>     var xhr = new XMLHttpRequest;
>     xhr.open('GET', fileName, false);
>     xhr.send(null);
>     return xhr.responseText;
>   }
> }
> ```
>
> Above example will virtually return always the same type and it could work inside a generator or an  async function as long as it's being held.
>
> Does any of this make sense? Is it worth exploring this pattern?
>
> Thanks for any sort of thought.
>
> Best  Regards
>
>
>
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss






_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss





_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Reflection to know if executed within a generator/async ?

Andrea Giammarchi-2
Didn't know about that thread, interesting indeed.

My point in a TL;DR version: if the future is able to deal with sync code satisfying async calls, why couldn't the future be even better giving old sync code the backward-compatible ability to understand if it's invoked in a future-like defined constrain such a generator or an async callback ...  it looks like a limit from the future of the language, rather than a real limit of what the current ES5/6 specification can provide.

Hence my `held` idea.

Regards

On Fri, Dec 4, 2015 at 7:13 PM, Bradley Meck <[hidden email]> wrote:
Be very clear, this is interesting, but dangerous.

I care very much but not in a positive way due to ironing out what would happen if the WHATWG Loader spec were to use Promises (either under the hood or explicitly). The amount of possible timing differences caused https://github.com/whatwg/loader/issues/54 which caused a huge refactor of the entire spec since timing implications of Promises are very different from synchronous code.

My thoughts on things can be summed up as: if timing change implicity/based upon situations outside of your code -> side effects change -> code can break based upon when it is being used (rather than how it is being called).

On Fri, Dec 4, 2015 at 11:31 AM, Andrea Giammarchi <[hidden email]> wrote:
Eyes don't see, mind don't care?

The fact await doesn't break, if that's the case, is cool and glorious. The fact a consumed API would like to keep working with synchronous projects and **realy** behave asynchronously with most modern one, is a different thing.

To better describe a common use case,  think about CommonJS  `require('module')` API.

There's no way it should break on all platforms (not jsut node and browsers) that implemented CommonJS, it could still return a Promise, through my `held` like idea, for Web and new async based code.

async works with old code, old code cannot be promoted to async one. All I am trying to explain is that I'd love to give well known, de-facto standard, universally used APIs the ability to behave, for real, asynchronously whenever the future of the language is available.

How bad is that?

Regards






On Fri, Dec 4, 2015 at 1:59 PM, Bradley Meck <[hidden email]> wrote:
The more I read about this the more I think that `await` is what you want to change *not the behavior of functions*. Rephrased to what I think is being asked:

If `await` encounters a non-thenable value, `Promise.resolve` the value before awaiting.

Isn't this already the case?

On Fri, Dec 4, 2015 at 2:44 AM, Andrea Giammarchi <[hidden email]> wrote:
Jordan please let's avoid discussions about migration patterns, I'm sure we've all done that and we all know how to. This is not the point of my idea.

Claude, again, you are using promises already so you won't need this "magic".  Your API returns promises,  you are good to update to async/await or generators.

However, in the future you won't write promises directly if not as returning values within some method .... right ?

Looking at your code, I would always go for the second pattern instead of the first one. So what if you'd like to use that already, simply adding async and await and the only change to do in a well known/used *synchronous* API would be to check if the returned value is held and behave accordingly?

That would give you a way to easily migrate to non-blocking as API consumer, and an easy way as API author to update to a non blocking version without breaking compatibility with other consumers.

In this scenario,  you are still free to use `Promise.resolve(fileGetContent("foo"))` which not on hold and not concretely asynchronous in terms of `fileGetContent("foo")` operations, but as soon as you go for async/await or a generator that function will return a Promise for you.

I hope it's clear now what is my idea.

Regards




On Fri, Dec 4, 2015 at 6:41 AM, Claude Pache <[hidden email]> wrote:

Le 3 déc. 2015 à 22:07, Andrea Giammarchi <[hidden email]> a écrit :

Sorry I misread your code. Your case assumes fileGetContent always returns a Promise so my proposal won't be useful there because it's already used as Promise.

You can remove that assumption by replacing `fileGetContent("foo")` with `Promise.resolve(fileGetContent("foo"))`.


My idea is more about migrating to full async code without changing all the things around, giving an API the ability to behave differently.

The key fact of my example is that I can (and do) write full async code without generators or async functions (just with ES3 + Promise), and you have no way to detect that.
For example, the following code:

```js
function bar() {
    return Promise.resolve(fileGetContent("foo")).then(function (c) {
        // whatever
    })
}
```

is functionally equivalent to:

```js
async function bar() {
    const c = await fileGetContent("foo")
    // whatever
}
```

In both cases, I can receive a value or a promise for a value, and in both cases getting a promise is strictly better.
I don't want to be served an inferior version of `fileGetContent` in the first case just because you were unable to guess my intentions,
and I won’t hurry to migrate my existing code to use the second pattern, because the difference is only cosmetic.

—Claude




Maybe it's too complicated or too magic to implement, that's OK anyway.

On Thu, Dec 3, 2015 at 8:59 PM, Claude Pache <[hidden email]> wrote:

Le 3 déc. 2015 à 20:04, Andrea Giammarchi <[hidden email]> a écrit :

I guess `held` would be like an arrow function, "transparent" when it comes to held invokes (like context or arguments)

? Sorry, but I don't understand how that would help to answer my question. 

—Claude 


On Thu, Dec 3, 2015 at 5:23 PM, Claude Pache <[hidden email]> wrote:
How would you detect that the following call to your `fileGetContent` function should return a Promise?

```js
function oldSchool() {
    return fileGetContent("foo").then(function (c) {
        // ....
    })
}
```

—Claude


> Le 3 déc. 2015 à 13:15, Andrea Giammarchi <[hidden email]> a écrit :
>
> Hi there,
>   just writing down some thoughts about being able to understand if a method/function has been  executed within a generator/async and is being yielded/awaited.
>
> Rationale: API that would like to behave synchronously in some case, returning Promises in other cases.
>
> Example:
>
> ```js
> function fileGetContent(fileName) {
>   // random example
>   if (held) {
>     return fetch(fileName).then((r)=>r.text());
>   } else {
>     var xhr = new XMLHttpRequest;
>     xhr.open('GET', fileName, false);
>     xhr.send(null);
>     return xhr.responseText;
>   }
> }
> ```
>
> Above example will virtually return always the same type and it could work inside a generator or an  async function as long as it's being held.
>
> Does any of this make sense? Is it worth exploring this pattern?
>
> Thanks for any sort of thought.
>
> Best  Regards
>
>
>
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss






_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss






_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Reflection to know if executed within a generator/async ?

Claude Pache
In reply to this post by Andrea Giammarchi-2

> Le 4 déc. 2015 à 18:31, Andrea Giammarchi <[hidden email]> a écrit :
>
>
> async works with old code, old code cannot be promoted to async one. All I am trying to explain is that I'd love to give well known, de-facto standard, universally used APIs the ability to behave, for real, asynchronously whenever the future of the language is available.
>
> How bad is that?
>
> Regards
>

I think that the only place where you can safely provide a promise when a value was previously expected, is when you are in tail-position inside an async function (as part of either `await` or `return`). The "tail-position" restriction is bad for your case, because it is easy to switch between tail- and non-tail-position by refactoring, and thus switching semantics unexpectedly.

Given that sync and async code may behave differently (race conditions...), picking randomly (because of unreliable guess) one semantics or the other is going to make it more difficult to debug.

—Claude

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Reflection to know if executed within a generator/async ?

Bergi
In reply to this post by Andrea Giammarchi-2
Andrea Giammarchi schrieb:

> simply adding
> async and await and the only change to do in a well known/used
> *synchronous* API would be to check if the returned value is held and
> behave accordingly?

No, making a consumer of an API asynchronous should not be simple.
Unless you are only writing pure functions, everything that involves
states will very likely break. Concurrency is not trivial, it needs a
lot of consideration.

> as soon as you go for
> async/await or a generator that function will return a Promise for you.

Please never do that. Functions that sometimes return promises and
sometimes not are already known to be an antipattern. Making this
obscurely dependent on some fragile syntactic conditions could only make
this worse.

If you want to migrate your library to asynchrony, just make it a
breaking change. Your consumers will thank you for it.

Kind regards,
  Bergi
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Reflection to know if executed within a generator/async ?

Andrea Giammarchi-2
I've asked for opinions and if in 2 days I haven't replied means I got it my idea is not welcome which is OK and fair enough.

However, I'm curious to know about this "Functions that sometimes return promises and sometimes not are already known to be an antipattern" because I have a library that does that in somehow explicit way (if you pass a callback it doesn't return  a promise, it invokes such callback once resolved) and it works without any real-world problem.

Mind pointing me at the library that failed returning Promises arbitrarily?


On Mon, Dec 7, 2015 at 12:48 AM, Bergi <[hidden email]> wrote:
Andrea Giammarchi schrieb:

simply adding
async and await and the only change to do in a well known/used
*synchronous* API would be to check if the returned value is held and
behave accordingly?

No, making a consumer of an API asynchronous should not be simple. Unless you are only writing pure functions, everything that involves states will very likely break. Concurrency is not trivial, it needs a lot of consideration.

as soon as you go for
async/await or a generator that function will return a Promise for you.

Please never do that. Functions that sometimes return promises and sometimes not are already known to be an antipattern. Making this obscurely dependent on some fragile syntactic conditions could only make this worse.

If you want to migrate your library to asynchrony, just make it a breaking change. Your consumers will thank you for it.

Kind regards,
 Bergi

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
12