Re: PHP True Async RFC - Stage 2

From: Date: Wed, 19 Mar 2025 11:27:11 +0000
Subject: Re: PHP True Async RFC - Stage 2
References: 1 2 3 4 5 6 7 8  Groups: php.internals 
Request: Send a blank email to [email protected] to get a copy of this message
>
> You're cheating again - you've put an extra pair of brackets around one
> expression and not the other, and assumed they'll work differently, but
that's
> not the grammar you proposed.
>

Why am I cheating?
> spawn (getClosure());
This is an honest statement, provided that the second parentheses are
optional. The full notation would be:
> spawn (getClosure())();

> Instead you'd have to write this:
> spawn (function() use(): string { return "string"; });

Exactly right, that's how it should be according to PHP syntax.
Therefore, if we want to get rid of double parentheses, we need a separate
rule for closures.

I would name these two cases as follows:
* spawn callable – the general usage case
* spawn closure – the special case for closures

I don't think these two rules make the language inconsistent because the
function keyword allows separating the first expression from the second
one.

spawn function means that a Closure definition follows.
Accordingly, there should be no additional parentheses () at the end.

The reverse meaning is that if spawn is not followed by the function
keyword, then it must be a valid expression that can be enclosed in
parentheses.
There are some doubts about whether all situations are correct, but so far,
this is how it works for me:

- call a standard PHP function

```php
spawn file_get_contents('file1.txt');
```

- call a user-defined function

```php
function example(string $name): void {
    echo "Hello, $name!";
}

spawn example('World');
```

- call a static method

```php
spawn Mailer::send($message);
```

- call a method of an object

```php
$object = new Mailer();
spawn $object->send($message);
```

- self, static or parent keyword:

```php
spawn self::send($message);
spawn static::send($message);
spawn parent::send($message);
```

- call $class method

```php
$className = 'Mailer';
spawn $className::send($message);
```

- expression

```php
// Use result of foo()
spawn (foo())();
// Use foo as a closure
spawn (foo(...))();
// Use ternary operator
spawn ($option ? foo() : bar())();
```

- call array dereference

```php
$array = [fn() => sleep(1)];
spawn $array[0]();
```

- new dereference

```php
class Test {
    public function wait(): void {
        sleep(1);
    }
}

spawn new Test->wait();
```

- call dereferenceable scalar:

```php
spawn "sleep"(5);
```

- call short closure

```php
spawn (fn() => sleep(1))();
```

> Sorry, what is exactly what we'd like to avoid?

Syntax ambiguities.
But it seems that avoiding them completely is impossible anyway because
I've already found an old case where a property and a method are used in
the same expression.


Thread (59 messages)

« previous php.internals (#126838) next »