Re: Change yield interpolation beha viour

From: Date: Fri, 08 Oct 2021 10:57:43 +0000
Subject: Re: Change yield interpolation beha viour
References: 1 2  Groups: php.internals 
Request: Send a blank email to internals+get-116250@lists.php.net to get a copy of this message
Yes you are right. The same thing happens if you put a function there. ``` function hi(): string {     return ‘World’; }   echo <<<MSG     Hello ${hi()} MSG; // Warning: Undefined variable $World! ```   For some reason, I did not take this case into account.   Although it seems to me such semantics are old and require removal from the language, I admit that there is code that uses it and changing the behavior will break a lot. Ideally, I would like to see a similar behavior: ``` echo "Hello ${ $var }"; // Hello World echo "Hello ${ 'Wo' . 'rld' }"; // same echo "Foo ${ some_foo(42) }"; echo "Foo ${ 23 + 42 }";  echo "Some ${ ClassName::method() >> 2 ?? $any }"; // etc ```     > >Пятница, 8 октября 2021, 12:22 +03:00 от Nikita Popov ><nikita.ppv@gmail.com>: >  >On Fri, Oct 8, 2021 at 10:55 AM Nesmeyanov Kirill < nesk@xakep.ru > wrote: >  >> Hello Internals! >> >> >> At the moment, there is a feature/bug in the PHP that allows to use >> interpolation of generators. >> >> ``` >> >> $code = <<<EXAMPLE >> >> Hello ${yield} >> >> EXAMPLE; >> >> ``` >> >> I suspect that initially this functionality was not thought out, but it >> partially works, which allows you to implement useful functionality. >> >> ``` >> >> [$query, $params] = sql(fn() => <<<SQL >> >> SELECT * FROM users WHERE id = ${yield 42} OR id = ${yield 0xDEADBEEF} >> >> SQL); >> >> // Expected >> // $query = "SELECT * FROM users WHERE id = ? OR id = ?" >> // $params = [ 42, 0xDEADBEEF ] >> >> ``` >> >> When I say that the functionality was not thought out initially, I mean >> the behavior of generators within strings. For example, the following >> code, which should (seemingly) implement this functionality: >> >> ``` >> >> function sql(\Closure $expr) >> >> { >> >> [$generator, $params] = [$expr(), $params]; >> >> while ($generator->valid()) { >> >> $params[] = $generator->current(); // Get the value from "yield" >> >> $generator->send('?'); // Insert placeholder >> >> } >> >> return [$generator->getReturn()]; >> >> } >> >> ``` >> >> Causes an error: >> >> ``` >> >> Warning: Undefined variable $? >> >> ``` >> >> >> That is, the expression "${yield 42}" expects back not the result of >> this expression, but the name of the variable. Therefore, a complete and >> workable implementation of such a functionality is as follows: >> >> https://gist.github.com/SerafimArts/2e7702620480fbce6c24bc87bfb9cb0e >> >> >> I think it makes sense to do something about it. I have two suggestions: >> >> 1) Forbid using "yield" inside strings >> >> 2) Expect not a variable name as a result of this expression, but a >> substitution value. >> >This doesn't really have anything to do with yield. ${expr} is PHP's >general variable-variable syntax, which looks up the variable with name >returned by expr. The syntax also works inside strings in the form of >"${expr}". Using "${yield $v}" is just a specific instance of the general >pattern following the same rules. (This syntax has a special case that >should be deprecated: "${label}" will be interpreted the same as "$label" >instead, which is inconsistent with how it works everywhere else. This is >also why ${yield} without argument will not perform a yield and instead >look for a variable called $yield.) > >PHP unfortunately doesn't have a general expression interpolation syntax, >you can only interpolate variables and certain variable-like constructs. > >Regards, >Nikita     -- Kirill Nesmeyanov  

« previous php.internals (#116250) next »