Skip to content
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

Enforce always passing promise to race function #207

Open
wants to merge 1 commit into
base: 3.x
Choose a base branch
from

Conversation

WyriHaximus
Copy link
Member

The race function has always supported passing an empty array of promises/values into it. And then defaulted to the behavior of returning an ever waiting promise. While this makes sense from a mathematical perspective, it doesn't from a developers' perspective.

To enforce always having to pass in a promise, the first argument is now required, and any following promises are accepted using a variadic function argument.

The race function has always supported passing an empty array of promises/values into it. And then defaulted to the behavior of returning an ever waiting promise. While this makes sense from a mathematical perspective, it doesn't from a developers' perspective.

To enforce always having to pass in a promise, the first argument is now required, and any following promises are accepted using a variadic function argument.
@WyriHaximus WyriHaximus added this to the v3.0.0 milestone Jan 17, 2022
@jsor
Copy link
Member

jsor commented Jan 17, 2022

FTR: this has been introduced later intentionally to be consistent with the JavaScript implementation, see #83.

return new Promise(function ($resolve, $reject) use ($promisesOrValues, $cancellationQueue): void {
foreach ($promisesOrValues as $promiseOrValue) {
return new Promise(function ($resolve, $reject) use ($promises, $cancellationQueue): void {
foreach ($promises as $promiseOrValue) {
$cancellationQueue->enqueue($promiseOrValue);

resolve($promiseOrValue)
Copy link
Member

@jsor jsor Jan 17, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
resolve($promiseOrValue)
$promiseOrValue

Passing throught resolve can be removed as the function signature now declares PromiseInterface.

@WyriHaximus
Copy link
Member Author

FTR: this has been introduced later intentionally to be consistent with the JavaScript implementation, see #83.

Ah cool thanks, this came up during a call @clue, @SimonFrings and I had a few days ago. So figured I'd PR it and we see if we want to change it or keep it as is.

@SimonFrings
Copy link
Member

@WyriHaximus good catch, looks very "promising" to me (sorry I'm not sorry) ^^

I talked with @clue about this one and it's a bit inconsistent to the other methods if we're getting rid of the array (cause they're all using it). The solution to this could be the non-empty-array<Type> annotation by PHPStan (Example Link).

What are your thoughts on this?

@WyriHaximus
Copy link
Member Author

@SimonFrings So that would result in this, correct?:

/**
 * Initiates a competitive race that allows one winner. Returns a promise which is
 * resolved in the same way the first settled promise resolves.
 *
 * The returned promise will become **infinitely pending** if  `$promisesOrValues`
 * contains 0 items.
 *
 * @param non-empty-array<PromiseInterface> $promisesOrValues
 * @return PromiseInterface
 */
function race(array $promisesOrValues): PromiseInterface

it's a bit inconsistent to the other methods if we're getting rid of the array

What if we change all methods to use variadic arguments?

@clue
Copy link
Member

clue commented Jan 23, 2022

@SimonFrings So that would result in this, correct?:

/**
 * Initiates a competitive race that allows one winner. Returns a promise which is
 * resolved in the same way the first settled promise resolves.
 *
 * The returned promise will become **infinitely pending** if  `$promisesOrValues`
 * contains 0 items.
 *
 * @param non-empty-array<PromiseInterface> $promisesOrValues
 * @return PromiseInterface
 */
function race(array $promisesOrValues): PromiseInterface

The $promiseOrValue is essentially still PromiseInterface|mixed, so the type hint would probably have to be non-empty-array<mixed>.

it's a bit inconsistent to the other methods if we're getting rid of the array

What if we change all methods to use variadic arguments?

Agree this makes it more consistent again, but not sure how I feel about this then being inconsistent with ES6 promises, introducing a noticeable BC break for promise v3, and also how this affects our plans to switch from array to iterable in the future.

I still have to admit I like the approach of using a single fixed promise and a variadic list of promises to move this requirement to the type system instead of making it a runtime check.

An empty race() is certainly not very useful, but at this point makes me wonder if there's much we can do about it without introducing more problems down the line?

@WyriHaximus
Copy link
Member Author

@SimonFrings So that would result in this, correct?:

/**
 * Initiates a competitive race that allows one winner. Returns a promise which is
 * resolved in the same way the first settled promise resolves.
 *
 * The returned promise will become **infinitely pending** if  `$promisesOrValues`
 * contains 0 items.
 *
 * @param non-empty-array<PromiseInterface> $promisesOrValues
 * @return PromiseInterface
 */
function race(array $promisesOrValues): PromiseInterface

The $promiseOrValue is essentially still PromiseInterface|mixed, so the type hint would probably have to be non-empty-array<mixed>.

non-empty-array<PromiseInterface|mixed>?

it's a bit inconsistent to the other methods if we're getting rid of the array

What if we change all methods to use variadic arguments?

Agree this makes it more consistent again, but not sure how I feel about this then being inconsistent with ES6 promises, introducing a noticeable BC break for promise v3, and also how this affects our plans to switch from array to iterable in the future.

Been looking into that one as well. And the various counts in several functions make it harder than it looks initially.

I still have to admit I like the approach of using a single fixed promise and a variadic list of promises to move this requirement to the type system instead of making it a runtime check.

And that is the reason I wanted to at least try this and see how we all feel about it 😃 .

An empty race() is certainly not very useful, but at this point makes me wonder if there's much we can do about it without introducing more problems down the line?

Alternatively, we can drop the first argument and only keep variadic argument in?

For me this is low hanging fruit but I wanted to at least have a look at it.

@WyriHaximus WyriHaximus removed this from the v3.0.0 milestone Jul 11, 2023
@WyriHaximus
Copy link
Member Author

Taking the milestone of this PR as we discussed this yesterday and are unsure about it's future and if it makes sense to do this or not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants