>
> If you await a value, everything works, but then someone somewhere else 
> awaits the same Awaitable that wasn't actually a "one-shot" Awaitable,
> so now everything breaks sometimes, and other times not -- depending on which 
> one awaits first.
>

There is a function:

```php
function my(mixed $i)
{
    return $x + 5;
}
```

Someone called it like this somewhere: my("string"), and the code broke.
The question is: what should be done?

Do we really have to get rid of the mixed type just to prevent someone
from breaking something?
If a programmer explicitly violates the contracts in the code and then
blames the programming language for it. So the programmer is the one
at fault.
If someone uses a contract that promises non-idempotent behavior, it’s
logical to rely on that.

> 2. memoization becomes an issue

The same question: why should the code work correctly if the
agreements are violated at the contract level?
There’s no element of randomness here.
1. A person deliberately found the Awaitable interface and inserted it
into the code.
2. They deliberately wrote that function.

So what exactly is the problem with the interface itself?

> With a "multi-shot" Awaitable, this is not practical or even a good idea. You 
> can't write general-purpose helpers, at all.
In what way are generalized types a problem?
Why not just use the contracts correctly?

```php
function getOnce(Awaitable $some) {

  if($some instanceof FutureLike === false) {
     return await($some);
  }

  static $cache = [];
  $id = spl_object_id($some);
  return $cache[$id] ??= await($some);
}
```

> 3. static analysis
I really don’t see how static analysis could help here. What exactly
would it be checking?

> 4. violation of algebraic laws with awaitAll/awaitAny

And the fact that awaitAll/awaitAny are designed to correctly handle
Awaitable objects?
I’m not aware of any such violations.

> 5. violation of own invariants in the RFC
Can you show which statement of the RFC is being violated here?
What invariants?

> 6. common patterns aren't guaranteed anymore

So JavaScript yes?

```js
class NonIdempotentThenable {
  constructor() {
    this.count = 0;
  }
  then(resolve, reject) {
    this.count++;
    resolve(this.count);
  }
}

async function demo() {
  const obj = new NonIdempotentThenable();
  console.log(await obj); // 1
  console.log(await obj); // 2
  console.log(await obj); // 3

  if (await obj) {
    console.log(await obj); // 5
  }
}

demo();
````

Other cases generally have the same problem — a violation of the agreement.

Reply via email to