Hi Rowan, > Hi Tyson, > > I'm on the fence on this one: I've certainly had occasions when it would > be useful, but mostly in quick prototypes and demo code, and just as > often in HTML context (where I'd want it to add '<br>') as plain text > context. > > I am not keen, however, on the proposed implementation details, and > would prefer it to much more closely match either print or echo. > > > - Until reading this RFC, I would not have guessed that printf() > returned the number of bytes written; I guess it's useful in C, where > you're managing string buffers, but in PHP it feels very arbitrary. I > would also not particularly associate this new function with printf() so > my immediate guess would be the same return value as print (even though > that return value, int(1), is equally arbitrary).
There's also the alias fputs of https://www.php.net/manual/en/function.fwrite.php which also returns the byte count. I'd considered just returning void, but then you'd have a mix of standard library functions that did/didn't return void and users would need to remember which did what. If someone actually had a need to use the result of println, it would likely be to count bytes, rather than to get a hardcoded constant such as 1/null. (or expression chaining, but `println('Starting') or die(2); // somehow failed to output` also has a use case) > - You explicitly state that this function would depend on strict_types > mode, but echo and print do not. I can't see any particular advantage to > doing so, and 'println((string)$foo)' would be longer than 'print > $foo,"\n"' rather defeating the purpose. I could change it to accept `mixed` and convert it to a string inside of the function. (or `object|string|float|int|bool|null` and throw or return false if an object could not be converted to a string). Throwing/warning for bool/null in strict mode may be worth it but may be more convenient to detect with external static analyzers) It initially seemed consistent with the behavior of https://www.php.net/fwrite to only accept a string and forcing callers to do so would catch unexpected edge cases with bool/null (''/'1'), floats, etc. in strict mode. Surprisingly, some output functions in PHP do accept `mixed`. https://www.php.net/file_put_contents accepts `mixed` and casts non-resources and non-arrays to strings (php-src/ext/standard/file.c) (handling of arrays/resources is different) ``` case IS_NULL: case IS_LONG: case IS_DOUBLE: case IS_FALSE: case IS_TRUE: convert_to_string(data); case IS_STRING: ``` Annoyingly, any decision I make would be inconsistent with something, e.g. file_put_contents currently doesn't even emit a notice for a failure to convert to string. ``` php > var_dump(file_put_contents('test.txt', new stdClass())); bool(false) ``` It definitely would be longer to use `println((string)$foo)`, but there may be cases where that would be done, e.g. if you are writing a script that would be reviewed/modified/used by programmers that are more familiar with languages that aren't PHP. (It'd be more readable using 1 output method than 3) There's also `println("$foo");` > - Most importantly, I accept your points about a function being more > forward- and backward-compatible, but worry that not making it a keyword > will lead to further confusion about how parentheses interact with echo > and print. There is a common misconception that they have some kind of > "optional parentheses", because they are usually used with a single > expression, so wrapping it in parentheses usually doesn't change the > outcome; but this is not the case, and it does sometimes matter. > > > As currently proposed, I can see people getting nasty surprises from > these inconsistencies. For instance: > > print (1+2)*3; // prints "9" > println (1+2)*3; // prints "3\n"; unless strict_types=1 is in effect, in > which case TypeError > print ($foo ?? 'Foo') . ($bar ?? 'Bar'); // prints "FooBar" if both vars > are null > println ($foo ?? 'Foo') . ($bar ?? 'Bar'); // never prints $bar or > "Bar", because they are not passed to println() Static analyzers for PHP such as Phan warn about the unused result of multiplication to catch cases like this, and other analyzers can easily add this check if they don't already check for it. https://github.com/phan/phan/wiki/Issue-Types-Caught-by-Phan#phannoopbinaryoperator > if ( something() && println($foo) && somethingElse() ) // does what it > looks like, if println is a normal function > if ( something() && print($foo) && somethingElse() ) // does not print > $foo, because the expression passed is actually ($foo)&&somethingElse() The fact that `print` doesn't require parenthesis is something that surprised me initially, though changing it to force it to use function syntax would be a much larger bc break more suitable for a major version, that I don't expect to pass. It may be possible to start deprecating `print` if the expression didn't contain a parenthesis (like the change in precedence of `+` and `-` did), but I'm not planning to work on that. (Python converted `print` from a statement in Python 2 to a call in Python 3) Regards, Tyson -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php