Re: Re: Alternative way to achieve cancelable promise

2016-10-20 Thread Kagami Rosylight
Hi Bergi:

>You're not the only one who is unsatisfied with the current proposal :-) Also 
>have a look at

Great! I’m yet to read them but I definitely will soon to discuss more.

>Promises are result values that can be passed to multiple consumers, and not 
>every consumer should be allowed to cancel the computation. So by default, 
>promises must not be cancellable.

My current updated proposal allows cancellation only for promises created by 
`Promise.cancelable()` call. In this case, simple `return 
Promise.resolve(cancelablePromise)` will disallow cancellation for other 
consumers. But yes, this may be an opt-out rather than opt-in for APIs 
returning cancelable promises.

>I don't see the major difference between these "chain" objects and "tokens" 
>from the other proposals. Can you expand on that, please?

“Chain”s do not need to be passed manually. A chain will store cancelable 
promises and will `[@@cancel]()` them after cancellation request. Each promise 
will have its own chain which will again propagate cancellations.

>You should never pass an async function to the new Promise constructor, have a 
>look here. Fortunately, the code in your actual proposal seems more reasonable 
>here.

I agree that the constructor approach is not good and would break easily. Thus, 
my updated proposal now uses `Promise.cancelable(async (chain) => {})` rather 
than the constructor itself.

>If I understood correctly, your chain keyword could be used like await? What 
>is the difference between them?

`await` will not be automatically canceled when `chain` will:

```
cancelable function saya() {
  // This is theoretically cancelable but user somehow want it to be ‘atomic’.
  await cancelableSubWork();
  chain.throwIfCanceled();
}
```

Sincerely,
Kagami Sascha Rosylight
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Alternative way to achieve cancelable promise

2016-10-19 Thread Bergi

Kagami Rosylight wrote:

I want to find a way to replace cancellation token in the current [stage 1 
cancelable promise 
proposal](https://github.com/tc39/proposal-cancelable-promises) with an 
alternative way which does not require passing an additional parameter.


You're not the only one who is unsatisfied with the current proposal :-)
Also have a look at
* https://github.com/stefanpenner/random/tree/master/cancellation
* https://github.com/rtm/cancelable-promise
* https://github.com/bergus/promise-cancellation (mine)


Here is a short representation of [my current 
thought](https://github.com/SaschaNaz/cancelable):

```ts
// A cancelable object supports new `Symbol.cancel`.
// `object[Symbol.cancel]()` will cancel any tasks related to the object.
interface Cancelable {
  [@@cancel](): void;
}

interface Promise extends Cancelable {}
```


That's not going to happen. Promises are result values that can be 
passed to multiple consumers, and not every consumer should be allowed 
to cancel the computation. So by default, promises must not be cancellable.
There could be such promises that can be cancelled by whomever gets a 
hold on them - they are known as `Task`s iirc - but that needs to be an 
opt-in.



// Here, a new `chain` object from promise constructor callback will
// help chaining cancelable tasks and provide cancellation related
// helper functions.


I don't see the major difference between these "chain" objects and 
"tokens" from the other proposals. Can you expand on that, please?



function foo() {
  return new Promise(async (resolve, reject, chain) => {
await nonCancelableSubWork1();
chain.throwIfCanceled(); // This line will throw `Cancel` object if the 
promise got a cancellation request
await nonCancelableSubWork2();
resolve();
 });
}


That's not going to work. You should never pass an `async function` to 
the `new Promise` constructor, have a look 
[here](http://stackoverflow.com/a/39409757/1048572).

Fortunately, the code in your actual proposal seems more reasonable here.


And with some syntax sugar for readability:

```js
cancelable function foo() {
  // `chain` is a keyword inside cancelable function blocks
  await nonCancelableSubWork1();
  chain.throwIfCanceled(); // similar form like `new.target`
  await nonCancelableSubWork2();
}

cancelable function bar() {
  chain foo();
  chain baz();
}

const promise = bar();
promise.cancel();
```


If I understood correctly, your `chain` keyword could be used like 
`await`? What is the difference between them?


But I really like the idea of `cancelable function` sugar that does the 
housekeeping implicitly and returns cancellable promises automatically.
This very much reminds me of my own ideas 
https://github.com/bergus/promise-cancellation/blob/master/enhancements.md 
:-)


kind regards,
 Bergi
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


RE: Alternative way to achieve cancelable promise

2016-10-18 Thread Kagami Rosylight
Thank you for your interest in my proposal. :D

I also thought so and I posted [an older version of my proposal on 
June](https://github.com/tc39/proposal-cancelable-promises/issues/22) there. I 
got this answer:

>This is a separate proposal, and not an issue with the proposal being 
>developed in this repo. So, I'll close this issue. You're welcome to continue 
>using it as a discussion thread for your proposal, but in general there are 
>better places to do that, such as es-discuss or your own GitHub repo you 
>created for your proposal.

Thus I’m posting this here separately to gain attention and discuss.

From: Marky Mark<mailto:m...@heyimmark.com>
Sent: Wednesday, October 19, 2016 11:20 AM
To: Kagami Rosylight<mailto:sascha...@outlook.com>; 
es-discuss@mozilla.org<mailto:es-discuss@mozilla.org>
Subject: Re: Alternative way to achieve cancelable promise

I must admit that I do like this approach, however I'm not too familiar with 
the proposed spec to definitively comment on this. Have you tried proposing 
this in the https://github.com/tc39/proposal-cancelable-promises repository? 
That may be a better avenue for your suggestions.

On Sat, Oct 15, 2016 at 3:15 AM Kagami Rosylight 
<sascha...@outlook.com<mailto:sascha...@outlook.com>> wrote:
I want to find a way to replace cancellation token in the current [stage 1 
cancelable promise 
proposal](https://github.com/tc39/proposal-cancelable-promises) with an 
alternative way which does not require passing an additional parameter.

Here is a short representation of [my current 
thought](https://github.com/SaschaNaz/cancelable):

```ts
// A cancelable object supports new `Symbol.cancel`.
// `object[Symbol.cancel]()` will cancel any tasks related to the object.
interface Cancelable {
  [@@cancel](): void;
}

interface Promise extends Cancelable {}
```

```js
// Here, a new `chain` object from promise constructor callback will
// help chaining cancelable tasks and provide cancellation related
// helper functions.

function foo() {
  return new Promise(async (resolve, reject, chain) => {
await nonCancelableSubWork1();
chain.throwIfCanceled(); // This line will throw `Cancel` object if the 
promise got a cancellation request
await nonCancelableSubWork2();
resolve();
 });
}

function bar() {
  return new Promise(async (resolve, reject, chain) => {
 // This `chain()` call will register foo() to the cancellation chain of a 
promise instance
 // and will propagate cancellation to the chained tasks.
 // The chain can receive any object that supports `Symbol.cancel`.
 await chain(foo());
 await chain(baz());
 });
}

const promise =  bar();
promise.cancel(); // This will cancel `bar` call and the cancellation will 
propagate to `foo` and `baz`
```

And with some syntax sugar for readability:

```js
cancelable function foo() {
  // `chain` is a keyword inside cancelable function blocks
  await nonCancelableSubWork1();
  chain.throwIfCanceled(); // similar form like `new.target`
  await nonCancelableSubWork2();
}

cancelable function bar() {
  chain foo();
  chain baz();
}

const promise = bar();
promise.cancel();

cancelable function baz() {
  try {
chain baw();
  }
  else {
// try-else block will catch cancellation, as the current existing proposal 
does
  }
}
```

I think this will achieve easier and more readable flow of cancelable tasks, 
what do you think?
___
es-discuss mailing list
es-discuss@mozilla.org<mailto:es-discuss@mozilla.org>
https://mail.mozilla.org/listinfo/es-discuss
--

mark

Sent while riding a hoverboard...
heyimmark.com<http://heyimmark.com> :)

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Alternative way to achieve cancelable promise

2016-10-18 Thread Marky Mark
I must admit that I do like this approach, however I'm not too familiar
with the proposed spec to definitively comment on this. Have you tried
proposing this in the
https://github.com/tc39/proposal-cancelable-promises repository?
That may be a better avenue for your suggestions.

On Sat, Oct 15, 2016 at 3:15 AM Kagami Rosylight 
wrote:

> I want to find a way to replace cancellation token in the current [stage 1
> cancelable promise proposal](
> https://github.com/tc39/proposal-cancelable-promises) with an alternative
> way which does not require passing an additional parameter.
>
>
>
> Here is a short representation of [my current thought](
> https://github.com/SaschaNaz/cancelable):
>
>
>
> ```ts
>
> // A cancelable object supports new `Symbol.cancel`.
>
> // `object[Symbol.cancel]()` will cancel any tasks related to the object.
>
> interface Cancelable {
>
>   [@@cancel](): void;
>
> }
>
>
>
> interface Promise extends Cancelable {}
>
> ```
>
>
>
> ```js
>
> // Here, a new `chain` object from promise constructor callback will
>
> // help chaining cancelable tasks and provide cancellation related
>
> // helper functions.
>
>
>
> function foo() {
>
>   return new Promise(async (resolve, reject, chain) => {
>
> await nonCancelableSubWork1();
>
> chain.throwIfCanceled(); // This line will throw `Cancel` object if
> the promise got a cancellation request
>
> await nonCancelableSubWork2();
>
> resolve();
>
>  });
>
> }
>
>
>
> function bar() {
>
>   return new Promise(async (resolve, reject, chain) => {
>
>  // This `chain()` call will register foo() to the cancellation chain
> of a promise instance
>
>  // and will propagate cancellation to the chained tasks.
>
>  // The chain can receive any object that supports `Symbol.cancel`.
>
>  await chain(foo());
>
>  await chain(baz());
>
>  });
>
> }
>
>
>
> const promise =  bar();
>
> promise.cancel(); // This will cancel `bar` call and the cancellation will
> propagate to `foo` and `baz`
>
> ```
>
>
>
> And with some syntax sugar for readability:
>
>
>
> ```js
>
> cancelable function foo() {
>
>   // `chain` is a keyword inside cancelable function blocks
>
>   await nonCancelableSubWork1();
>
>   chain.throwIfCanceled(); // similar form like `new.target`
>
>   await nonCancelableSubWork2();
>
> }
>
>
>
> cancelable function bar() {
>
>   chain foo();
>
>   chain baz();
>
> }
>
>
>
> const promise = bar();
>
> promise.cancel();
>
>
>
> cancelable function baz() {
>
>   try {
>
> chain baw();
>
>   }
>
>   else {
>
> // try-else block will catch cancellation, as the current existing
> proposal does
>
>   }
>
> }
>
> ```
>
>
>
> I think this will achieve easier and more readable flow of cancelable
> tasks, what do you think?
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
-- 

mark

Sent while riding a hoverboard...
heyimmark.com :)
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss