[PHP-DEV] UGLY Benchmark Results for PHP Master 2017-03-08
Results for project PHP master, build date 2017-03-08 20:14:30-08:00 commit: 2ba2b76 previous commit:c698299 revision date: 2017-03-07 12:11:31-08:00 environment:Haswell-EP cpu:Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem:128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release php-7.0.0, with hash 60fffd2 from 2015-12-01 04:16:47+00:00 --- benchmark relative change since change since current rev run std_dev* last run baseline with PGO --- :-| Wordpress 4.2.2 cgi -T1 0.38% -0.70% -0.39% 7.80% :-| Drupal 7.36 cgi -T1 0.18% 0.14% 0.32% 4.76% :-| MediaWiki 1.23.9 cgi -T5000 0.20% 0.50% 1.51% 3.07% :-( bench.php cgi -T100 0.00% -2.46% 36.39% -0.63% :-( micro_bench.php cgi -T10 0.09% -5.44% 10.03% 6.21% :-) mandelbrot.php cgi -T100 0.01% 11.62% 34.05% 2.98% --- * Relative Standard Deviation (Standard Deviation/Average) If this is not displayed properly please visit our results page here: http://languagesperformance.intel.com/ugly-benchmark-results-for-php-master-2017-03-08/ Note: Benchmark results for Wordpress, Drupal, MediaWiki are measured in fetches/second while all others are measured in seconds. More details on measurements methodology at: https://01.org/lp/documentation/php-environment-setup. Subject Label Legend: Attributes are determined based on the performance evolution of the workloads compared to the previous measurement iteration. NEUTRAL: performance did not change by more than 1% for any workload GOOD: performance improved by more than 1% for at least one workload and there is no regression greater than 1% BAD: performance dropped by more than 1% for at least one workload and there is no improvement greater than 1% UGLY: performance improved by more than 1% for at least one workload and also dropped by more than 1% for at least one workload Our lab does a nightly source pull and build of the PHP project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [Discussion] is_string(), string type and objects implementing __toString()
Hi! > I submitted a GitHub PR* to allow objects implementing __toString() to > *optionally* pass is_string() validation. More verbose wording of my > motivation can be seen in the PR description, but here are the main > points: I don't think it's right approach. is_* functions check the current type of the value, not whether it can be converted to another type. If we need ones that express the latter, we should have different functions. Also, as already noted, having __toString doesn't mean it returns something useful. -- Stas Malyshev smalys...@gmail.com -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [Discussion] is_string(), string type and objects implementing __toString()
On 3/9/2017 12:32 AM, Andrey Andreev wrote: > On Thu, Mar 9, 2017 at 12:42 AM, Rowan Collins> wrote: >> >> I still don't understand what you're using this check for that means you >> want to exclude integers. If you're passing on the value to anything that >> actually needs a string, you're doing a string cast, either explicitly or >> implicitly, so there's no difference between me passing you (string)'42', >> (int)42, or new class { function __toString() { return '42'; } } >> > > This goes all the way back to the heated discussion about scalar type > hints ... Being explicit is the entire point, and why many people > wanted strict typing. > Stringable seems very explicit and strict to me, since it is opt-in. Currently there is no way to have the ergonomics of coercion if strict mode is active for a file. This could be a very explicit way to enable it for portions. On 3/9/2017 12:32 AM, Andrey Andreev wrote: > On Thu, Mar 9, 2017 at 12:43 AM, Fleshgrinder wrote: >> >> What is the use case where every other scalar (and null) type is not >> acceptable? I defended that stringable should bridge only string and >> objects with __toString too first, but after thinking more about it, >> there is no real world reason why one would need that. Almost all use >> cases I can think about evolve around strict mode and some function that >> simply does not care what it was. Hence, stringable would truly act like >> the into trait in Rust. >> > > Think of value objects. Perhaps you'd have a few methods on a value > object, but mostly use it to give context to a scalar type value. > > For example, a Cookie object may have the cookie attributes (domain, > path, etc.) as value objects, but they can easily be created from raw > strings, while other types would be ambiguous. > A similar effect could be desirable for HTTP headers. > All of these can work with any other scalar value that was coerced to a string. I actually think that most examples given will have dedicated strictly typed methods to ensure that the value is correct for their domain. Don't forget that a string in PHP is a binary buffer and may contain pretty much every kind of malicious stuff that you never wanted or expected. Validation is absolutely necessary at all times when dealing with strings. Having an integer that is converted to a string does not make strings more evil than they already are. You actually already need to deal with all kinds of data that gets coerced, since you have no control over the strict mode of the caller. ;) On 3/9/2017 12:32 AM, Andrey Andreev wrote: > Also, we're talking about strings here only because we don't have > __toInteger(), __toFloat(), etc. I'm not saying we should, but if we > did - similar use cases would be present for other scalar types too. > Even easier to imagine - a DateTime object would probably have > __toInteger() returning a UNIX timestamp. > I actually consider the existence of almost all magic methods as a hindrance for evolving the language, and definitely do not desire to get more of them into core. Having a `DateTime::toTimestamp()` is much more valuable than a `DateTime::__toInteger()`. These magic methods are a result of the incoherent type system. Treating the symptoms instead of the root cause. The story would be different if a `Timestamp` could extend `Integer` which would directly allow it to be passed to all functions that are capable of dealing with an `Integer`. (Or any other possible constellation of a more sophisticated type system.) -- Richard "Fleshgrinder" Fussenegger -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [Discussion] is_string(), string type and objects implementing __toString()
On Thu, Mar 9, 2017 at 12:42 AM, Rowan Collinswrote: > > I still don't understand what you're using this check for that means you > want to exclude integers. If you're passing on the value to anything that > actually needs a string, you're doing a string cast, either explicitly or > implicitly, so there's no difference between me passing you (string)'42', > (int)42, or new class { function __toString() { return '42'; } } > This goes all the way back to the heated discussion about scalar type hints ... Being explicit is the entire point, and why many people wanted strict typing. On Thu, Mar 9, 2017 at 12:43 AM, Fleshgrinder wrote: > > What is the use case where every other scalar (and null) type is not > acceptable? I defended that stringable should bridge only string and > objects with __toString too first, but after thinking more about it, > there is no real world reason why one would need that. Almost all use > cases I can think about evolve around strict mode and some function that > simply does not care what it was. Hence, stringable would truly act like > the into trait in Rust. > Think of value objects. Perhaps you'd have a few methods on a value object, but mostly use it to give context to a scalar type value. For example, a Cookie object may have the cookie attributes (domain, path, etc.) as value objects, but they can easily be created from raw strings, while other types would be ambiguous. A similar effect could be desirable for HTTP headers. Also, we're talking about strings here only because we don't have __toInteger(), __toFloat(), etc. I'm not saying we should, but if we did - similar use cases would be present for other scalar types too. Even easier to imagine - a DateTime object would probably have __toInteger() returning a UNIX timestamp. Cheers, Andrey. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] [VOTE] Extended String Types For PDO
Hi, I'd like to open the vote on this RFC: https://wiki.php.net/rfc/extended-string-types-for-pdo Previous discussion: https://externals.io/thread/715 Voting will end on the 17th at 0:00 UTC. Thanks, Adam
Re: [PHP-DEV] [Discussion] is_string(), string type and objects implementing __toString()
On 3/8/2017 11:24 PM, Andrey Andreev wrote: > Hi again, > > On Wed, Mar 8, 2017 at 9:39 PM, Rowan Collinswrote: >> >> I think it comes down to what you're trying to achieve: the language can't >> have pseudo-types for every possible combination of types, so if you want to >> detect integers as one case, and other things that can be converted to >> string as another, just perform your checks in the right order: >> >> if ( is_int($foo) ) { >> // ... >> } elseif ( is_stringable($foo) ) { >> // ... >> } >> > > This is why I was concerned about the discussion becoming too broad - > it brings us (or me anyway) back to square 1, if not even out of > bounds. I wanted the ability to do "string or string object" checks > without multiple function calls, and now the suggested solution > doesn't do that. > > I do agree that we can't have pseudo-types for everything, but can we > at least have meaningful ones? How would "stringable" be different to > "string", and what's the point of either of them if they accept every > other scalar type? We're having this discussion because outside of the > so called "strict mode", PHP's string type is just as meaningful as > "scalar", which makes it useless IMO. > > Cheers, > Andrey. > What is the use case where every other scalar (and null) type is not acceptable? I defended that stringable should bridge only string and objects with __toString too first, but after thinking more about it, there is no real world reason why one would need that. Almost all use cases I can think about evolve around strict mode and some function that simply does not care what it was. Hence, stringable would truly act like the into trait in Rust. Although, to be fair, Rust does not provide Into nor Into<&'a str> for numeric types. I actually don't know why, since fmt::Display is implemented for all of them. Then again, Rust is very, very different to PHP. -- Richard "Fleshgrinder" Fussenegger -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [Discussion] is_string(), string type andobjectsimplementing __toString()
Hi Andrea, On Wed, Mar 8, 2017 at 8:44 PM, Andrea Fauldswrote: > Fleshgrinder wrote: >> >> On 3/8/2017 7:36 PM, Andrea Faulds wrote: >>> >>> Hi, >>> >>> Andrey Andreev wrote: The question is rather "is this value a string?", only with the added assumption that __toString() objects are treated as "string objects" and thus fulfill the condition (another reason why I went for an is_string() parameter). >>> >>> >>> This is a faulty assumption. The presence of __toString() doesn't mean >>> the object is a string, or intended to be used like one. >>> >> >> What is it then in your book? >> > > It means the object can be converted to a string. But such a conversion may > entail a loss of information and not be equivalent to the object itself. It > might be a “human-readable” form, for instance. > There will be loss of information most of the time, indeed. That's not the point; broadly speaking, you'd have to alias __toString() to serialize() in order to avoid that. If it has an explicitly declared string representation, I want to have the option to use that easily, without writing boilerplate code to filter-out every other type. Cheers, Andrey. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [Discussion] is_string(), string type and objects implementing __toString()
On 08/03/2017 22:24, Andrey Andreev wrote: This is why I was concerned about the discussion becoming too broad - it brings us (or me anyway) back to square 1, if not even out of bounds. Sorry :( I do agree that we can't have pseudo-types for everything, but can we at least have meaningful ones? Sure, but you need to justify why your particular choice of pseudo-type is more meaningful than any of the other combinations. I still don't understand what you're using this check for that means you want to exclude integers. If you're passing on the value to anything that actually needs a string, you're doing a string cast, either explicitly or implicitly, so there's no difference between me passing you (string)'42', (int)42, or new class { function __toString() { return '42'; } } My best guess was that you wanted to do something *different* if it was an integer, but as I showed in my last example that doesn't actually need you to exclude them from the new function. Regards, -- Rowan Collins [IMSoP] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [Discussion] is_string(), string type and objects implementing __toString()
Hi again, On Wed, Mar 8, 2017 at 9:39 PM, Rowan Collinswrote: > > I think it comes down to what you're trying to achieve: the language can't > have pseudo-types for every possible combination of types, so if you want to > detect integers as one case, and other things that can be converted to > string as another, just perform your checks in the right order: > > if ( is_int($foo) ) { > // ... > } elseif ( is_stringable($foo) ) { > // ... > } > This is why I was concerned about the discussion becoming too broad - it brings us (or me anyway) back to square 1, if not even out of bounds. I wanted the ability to do "string or string object" checks without multiple function calls, and now the suggested solution doesn't do that. I do agree that we can't have pseudo-types for everything, but can we at least have meaningful ones? How would "stringable" be different to "string", and what's the point of either of them if they accept every other scalar type? We're having this discussion because outside of the so called "strict mode", PHP's string type is just as meaningful as "scalar", which makes it useless IMO. Cheers, Andrey. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] [RFC][VOTE] Deprecate and Remove Bareword (Unquoted) Strings
Hi all, As there has been no further feedback since my last update, and it is 5 weeks since I first placed it Under Discussion, I would like to move ahead with voting on my RFC to Deprecate and Remove Bareword (Unquoted) Strings. Voting will close on 2017-03-22, at 22:00 UTC, i.e. two weeks from now. Please read and vote on the RFC at https://wiki.php.net/rfc/deprecate-bareword-strings In particular, note the reasoning for using an E_WARNING, as I suspect this is the most controversial aspect. If you do have any queries or concerns that weren't already raised, please do let me know. Regards, -- Rowan Collins [IMSoP] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [Discussion] is_string(), string type and objects implementing __toString()
Hi Richard, Please note that I had drafted this before I saw your last e-mail, so I think some of its points are now redundant. I'm sending it anyway, in case it helps with further thoughts. On 08/03/2017 15:44, Fleshgrinder wrote: We can coerce an integer to a string but an integer is not a string. The situation is different for an object that implements the __toString method, since this object officially opted-in to the contract that it can safely be used as a string. The problem is in the definition of "safely convert". If "safely" means "reversably", i.e. the cast is non-lossy, then an integer can be "safely" converted to a string, but (for example) an Exception object (which hasn't ) cannot: $a = 42; $b = (string)$a; $c = (int)$b; assert($a === $c); $a = new Exception; $b = (string)$a; # Cannot convert back to Exception To conclude: integers are not stringable because they are not part of any of the two types (string + Stringable objects), just like stdClass instances are not part of any of the two types that iterable covers. This comes back to the same point I made to Ryan earlier: you have to define this contract in terms of its implementation, not its purpose. What is it that strings and Stringable objects have in common *other than* their ability to cast to string? And since an integer can *always* be cast to a string *and back again*, what makes it not stringable? Going with the thought experiment of "Stringable" as an interface, remember that interfaces implement a form of multiple inheritance. So we don't need an ancestral relationship which links strings to ints, we can just say that "int implements stringable". This seems perfectly reasonable to me. To conclude: integers are not stringable because they are not part of any of the two types (string + Stringable objects), just like stdClass instances are not part of any of the two types that iterable covers. I don't think this is the same case at all; the problem with "iterable" is that stdClass should never have been usable with foreach in the first place. The relevant comparison is not to integers, but to objects which don't implement __toString(). Until PHP 5.2, "$foo = new stdClass; $bar = (string)$foo;" would actually give you a string [https://3v4l.org/XDWTh]; not a very useful one, admittedly, but by pure logic, any object in those PHP versions was "stringable". I think it comes down to what you're trying to achieve: the language can't have pseudo-types for every possible combination of types, so if you want to detect integers as one case, and other things that can be converted to string as another, just perform your checks in the right order: if ( is_int($foo) ) { // ... } elseif ( is_stringable($foo) ) { // ... } Regards, -- Rowan Collins [IMSoP] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [Discussion] is_string(), string type andobjectsimplementing __toString()
On 3/8/2017 7:50 PM, Nikita Popov wrote: > On Wed, Mar 8, 2017 at 7:44 PM, Andrea Fauldswrote: > >> Fleshgrinder wrote: >> >>> On 3/8/2017 7:36 PM, Andrea Faulds wrote: >>> Hi, Andrey Andreev wrote: > The question is rather "is this value a string?", only with the added > assumption that __toString() objects are treated as "string objects" > and thus fulfill the condition (another reason why I went for an > is_string() parameter). > This is a faulty assumption. The presence of __toString() doesn't mean the object is a string, or intended to be used like one. >>> What is it then in your book? >>> >>> >> It means the object can be converted to a string. But such a conversion >> may entail a loss of information and not be equivalent to the object >> itself. It might be a “human-readable” form, for instance. >> Sure, and? The to-be-called function does not require that all information must be preserved, it requires that the to-be-passed argument is convertible into a string. Most probably because it wants to perform some actions on the string value, but the reasons are not of interest. As a matter of fact, any function that requests a string only asks for a string and is not aware of its contents, hence, it is also not aware of whether the to-be-passed argument might suffer from loss of information. The same is true for instance if we pass a traversable of some sort to a function that requires an iterable. We loose information! The only difference here would be that we can use feature detection to gather that information again, whereas in the Stringable implementation I envision we cannot. This is because I would convert the object to a primitive string before handing it in to the to-be-called function. This is a controlled conversion, from the sender and receiver side which is very handy in many situations. That being said, it is just sugar topping, and not having it is not a deal breaker either (since explicit casts or dedicated `toString` methods are always there). However, it would avoid certain situations of explicit casts where one might needlessly cast primitive strings, whereas with the stringable data type the runtime could take care of it. It should also be possible to generate more efficient code, since the runtime knows better what situations are possible. Something that is unclear with an explicit cast. On 3/8/2017 7:50 PM, Nikita Popov wrote: > > To give an example: Exceptions implement __toString(), which contains the > exception message, location information and backtrace. Of course, > exceptions are rather different from strings and treating an exceptions as > a string is usually incorrect. > > Nikita > For the receiver its a string and not an exception, and it does not care that it was one. Now, after thinking more about this, I actually think that it should cover other scalar types too. It might be very strict, which is nice, but at the same time this strictness does not truly add a lot of value. After all, bool, int, float, and null can always be converted to a string too. In the end the use-case is to have a type constraint in strict mode that allows more types to pass through than string only. Like a formatter (think printf). -- Richard "Fleshgrinder" Fussenegger -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [Discussion] is_string(), string type andobjectsimplementing __toString()
On Wed, Mar 8, 2017 at 7:44 PM, Andrea Fauldswrote: > Fleshgrinder wrote: > >> On 3/8/2017 7:36 PM, Andrea Faulds wrote: >> >>> Hi, >>> >>> Andrey Andreev wrote: >>> The question is rather "is this value a string?", only with the added assumption that __toString() objects are treated as "string objects" and thus fulfill the condition (another reason why I went for an is_string() parameter). >>> >>> This is a faulty assumption. The presence of __toString() doesn't mean >>> the object is a string, or intended to be used like one. >>> >>> >> What is it then in your book? >> >> > It means the object can be converted to a string. But such a conversion > may entail a loss of information and not be equivalent to the object > itself. It might be a “human-readable” form, for instance. > To give an example: Exceptions implement __toString(), which contains the exception message, location information and backtrace. Of course, exceptions are rather different from strings and treating an exceptions as a string is usually incorrect. Nikita
Re: [PHP-DEV] [Discussion] is_string(), string type andobjectsimplementing __toString()
Fleshgrinder wrote: On 3/8/2017 7:36 PM, Andrea Faulds wrote: Hi, Andrey Andreev wrote: The question is rather "is this value a string?", only with the added assumption that __toString() objects are treated as "string objects" and thus fulfill the condition (another reason why I went for an is_string() parameter). This is a faulty assumption. The presence of __toString() doesn't mean the object is a string, or intended to be used like one. What is it then in your book? It means the object can be converted to a string. But such a conversion may entail a loss of information and not be equivalent to the object itself. It might be a “human-readable” form, for instance. -- Andrea Faulds https://ajf.me/ -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [Discussion] is_string(), string type and objectsimplementing __toString()
On 3/8/2017 7:36 PM, Andrea Faulds wrote: > Hi, > > Andrey Andreev wrote: >> The question is rather "is this value a string?", only with the added >> assumption that __toString() objects are treated as "string objects" >> and thus fulfill the condition (another reason why I went for an >> is_string() parameter). > > This is a faulty assumption. The presence of __toString() doesn't mean > the object is a string, or intended to be used like one. > What is it then in your book? -- Richard "Fleshgrinder" Fussenegger -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [Discussion] is_string(), string type and objectsimplementing __toString()
Hi, Andrey Andreev wrote: The question is rather "is this value a string?", only with the added assumption that __toString() objects are treated as "string objects" and thus fulfill the condition (another reason why I went for an is_string() parameter). This is a faulty assumption. The presence of __toString() doesn't mean the object is a string, or intended to be used like one. -- Andrea Faulds https://ajf.me/ -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [Discussion] is_string(), string type and objects implementing __toString()
On 3/8/2017 5:50 PM, Ryan Pallas wrote: > On Wed, Mar 8, 2017 at 9:50 AM, Ryan Pallaswrote: > >> >> >> On Wed, Mar 8, 2017 at 8:51 AM, Fleshgrinder wrote: >> >>> Hey! :) >>> >>> The reference is actually not a problem for a Stringable because you >>> would get the "Only variables can be passed by reference" error with an >>> object if `strict_types` is enabled. >>> >>> Simply because the object **MUST** be converted into a string. The >>> object itself does not satisfy the constraint, but the object clearly >>> states that it can be converted into a string at any point. >>> >> >> This is the part I disagree with. The object clearly states that it can be >> turned into a string when you are done using it as a object. If it gets >> turned into a string, you can no longer use it as a object. >> >> There is a difference between changing an int to string and an object to >> string, in that afterwards the int->string can continue to be treated as an >> int afterwards, thanks to loose typing (otherwise it wouldn't have become a >> string in the first place). However with an object->string afterwards it >> can ONLY be treated as a string, it can no longer be treated as an object. >> Meaning >> >> $int = 3; >> foo(3); >> > Sorry this should have been: > foo($int); > >> var_dump(++$int); // 4, success, no errors >> >> $obj = new Foo('a'); >> foo($obj); >> var_dump($obj->method()); // Fatal error: call to member function method >> on string. >> >> To me, this doesn't make sense. >> >>> >>> Not doing so would violate what `strict_types` actually promise us. ;) >>> >>> -- >>> Richard "Fleshgrinder" Fussenegger >>> >> >> > function foo(string &$s) { $s = 'foo'; } final class Stringable { public function __toString() { return 'stringable'; } } $stringable = new Stringable; foo($stringable); // Fatal error: Only variables can be passed by reference in ... $string = (string) $stringable; foo($string); // Heureka! Why is that? At the point where we reach the call `foo($stringable)` we need to perform various checks, which will lead to the conclusion that we require a string and that the value of `$stringable` is an object that can be converted to a string. That is exactly what we do. Hence, the call is not `foo($stringable)` but rather `foo('stringable')`, the value that we received from the conversion. The conversion is in place, just like a cast would be, hence ... foo((string) $stringable); ... is equivalent to ... foo($stringable); ... with a type constraint of string for that particular argument. Obviously we should yield another error message in such cases, to ensure that people are not confused. However, this is only about the logic. This means by implication that a ... function foo(stringable &$s) { } ... is impossible. Something we encounter a lot lately with many features that we would like to have. This is also one of the reasons why many higher languages do not support pointers in their type systems. -- Richard "Fleshgrinder" Fussenegger -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [Discussion] is_string(), string type and objects implementing __toString()
On Wed, Mar 8, 2017 at 9:50 AM, Ryan Pallaswrote: > > > On Wed, Mar 8, 2017 at 8:51 AM, Fleshgrinder wrote: > >> Hey! :) >> >> The reference is actually not a problem for a Stringable because you >> would get the "Only variables can be passed by reference" error with an >> object if `strict_types` is enabled. >> >> Simply because the object **MUST** be converted into a string. The >> object itself does not satisfy the constraint, but the object clearly >> states that it can be converted into a string at any point. >> > > This is the part I disagree with. The object clearly states that it can be > turned into a string when you are done using it as a object. If it gets > turned into a string, you can no longer use it as a object. > > There is a difference between changing an int to string and an object to > string, in that afterwards the int->string can continue to be treated as an > int afterwards, thanks to loose typing (otherwise it wouldn't have become a > string in the first place). However with an object->string afterwards it > can ONLY be treated as a string, it can no longer be treated as an object. > Meaning > > $int = 3; > foo(3); > Sorry this should have been: foo($int); > var_dump(++$int); // 4, success, no errors > > $obj = new Foo('a'); > foo($obj); > var_dump($obj->method()); // Fatal error: call to member function method > on string. > > To me, this doesn't make sense. > >> >> Not doing so would violate what `strict_types` actually promise us. ;) >> >> -- >> Richard "Fleshgrinder" Fussenegger >> > >
Re: [PHP-DEV] [Discussion] is_string(), string type and objects implementing __toString()
On Wed, Mar 8, 2017 at 8:51 AM, Fleshgrinderwrote: > Hey! :) > > The reference is actually not a problem for a Stringable because you > would get the "Only variables can be passed by reference" error with an > object if `strict_types` is enabled. > > Simply because the object **MUST** be converted into a string. The > object itself does not satisfy the constraint, but the object clearly > states that it can be converted into a string at any point. > This is the part I disagree with. The object clearly states that it can be turned into a string when you are done using it as a object. If it gets turned into a string, you can no longer use it as a object. There is a difference between changing an int to string and an object to string, in that afterwards the int->string can continue to be treated as an int afterwards, thanks to loose typing (otherwise it wouldn't have become a string in the first place). However with an object->string afterwards it can ONLY be treated as a string, it can no longer be treated as an object. Meaning $int = 3; foo(3); var_dump(++$int); // 4, success, no errors $obj = new Foo('a'); foo($obj); var_dump($obj->method()); // Fatal error: call to member function method on string. To me, this doesn't make sense. > > Not doing so would violate what `strict_types` actually promise us. ;) > > -- > Richard "Fleshgrinder" Fussenegger >
Re: [PHP-DEV] [Discussion] is_string(), string type and objects implementing __toString()
Hey! :) The reference is actually not a problem for a Stringable because you would get the "Only variables can be passed by reference" error with an object if `strict_types` is enabled. Simply because the object **MUST** be converted into a string. The object itself does not satisfy the constraint, but the object clearly states that it can be converted into a string at any point. Not doing so would violate what `strict_types` actually promise us. ;) -- Richard "Fleshgrinder" Fussenegger -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [Discussion] is_string(), string type and objects implementing __toString()
Hey guys! The question if an integer is a stringable is pretty much the same as the question if an stdClass is an iterable. Sure, you can iterate an stdClass instance with a foreach, but does it qualify as an iterable? Definitely not, and luckily it was not implemented as such. We can coerce an integer to a string but an integer is not a string. The situation is different for an object that implements the __toString method, since this object officially opted-in to the contract that it can safely be used as a string. In other words: in a coherent type system any object that is stringable would extend the string class and thus would go through any string type constraint. This is something that we cannot implement anymore at this point because we have no coherent type system. mixed (super type) | |- array is_array |- bool is_bool |- float is_float |- intis_int |- iterable is_iterable |- null is_null |- object is_object || instanceof |- resource is_resource |- closed resourceget_resource_type === 'Unknown' |- scalar is_scalar |- string is_string | void (bottom type) We have a single root node, but we directly branch into many types without any relation to each other, a relation always requires hard coding. Iterable is the very first of those hard coded types which was added to the runtime to bridge a gab, namely the gab between array and any object that implements the Traversable interface. Stringable would be the same as Traversable---hence the -able suffix (and I would love it if it would be possible to simply have a String interface but that is impossible)---and bridge the gab between string and any object that implements the Stringable interface. Now comes the next specialty that we need to deal with: magic methods. Any object that provides a magic __toString method automatically implements the Stringable interface, hence, there is none. I do not like this, and I would never do something like this if I would design a programming language or a type system, but here we are. (Note that Go works like this everywhere, _urgs_.) To conclude: integers are not stringable because they are not part of any of the two types (string + Stringable objects), just like stdClass instances are not part of any of the two types that iterable covers. I am open to other names, but I cannot come up with any that clearly states its purpose: `CharBuffer`? At this point we could also argue that any object with the magic __toString method actually is a string. However, I believe that this would be a crass change, which would definitely break code, e.g.: if (is_string($v) && $v !== '') echo $v{0}; We need a pseudo-type here! We most definitely require more pseudo-types to bridge more of our root leaves. Number comes naturally (the union of float and int which does not coerce to any of the two), an making scalar available to userland might be handy too. A possible pseudo-type to cover everything that can safely be converted to a string could be str (like in Rust). But note that safely would cover many of our types (namely bool, float, int, null, stringable objects, resources, closed resources, and strings). However, I definitely see use cases for all these types to be honest (think of a message formatter). -- Richard "Fleshgrinder" Fussenegger -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [Discussion] is_string(), string type and objects implementing __toString()
Hi Ryan, On Wed, Mar 8, 2017 at 5:15 PM, Ryan Pallaswrote: > Sorry, accidently sent in the middle of typing that... > > On Wed, Mar 8, 2017 at 7:42 AM, Ryan Pallas wrote: >> >> >> >> On Wed, Mar 8, 2017 at 5:25 AM, Andrey Andreev wrote: >>> >>> Hi all, >>> >>> I submitted a GitHub PR* to allow objects implementing __toString() to >>> *optionally* pass is_string() validation. More verbose wording of my >>> motivation can be seen in the PR description, but here are the main >>> points: >>> >>> - Simpler way to do checks like: is_string($var) || >>> method_exists($var, '__toString') >>> - Can be used for stricter string parameter validation in >>> strict_types=0 mode (otherwise any scalar type is accepted) >>> >>> - Can be used for looser string parameter validation in strict_types=1 >>> mode (__toString() objects aren't accepted there) >>> - Regardless of the last 2 points, it is intentionally not limited to >>> parameter types >> >> >> If I understand correctly, you want the following to work: >> > declare(strict_type = 0); > function foo(string $bar) { > return $bar.'foo'; > } > > class Foo { > private $val; > public function __construct(string $val) { > $this->val = $val; > } > public function __toString() { > return $this->$val; > } > } > > echo foo(new Foo('this is ')); // this is foo > > But what happens if I change the foo function like: > function foo(string &$bar) { > $bar .= 'foo'; > } > > $foo = new Foo('object'); > foo($foo); > var_dump($foo); // will this be an instance of Foo, or the string > "objectfoo"?? > > If $foo remains an object in this scope, then the function is not modifying > its value. If it becomes a string, it's an unexpected change IMO. It is > probably fine in this case, but not in the case of a more complex object. This already works and while the reference thing is indeed ugly, the problems I have with it are different: 1) It also accepts every other scalar type. 2) It will not work with strict_types=1. 3) I want to do it mid-runtime, not just on function parameters. Cheers, Andrey. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [Discussion] is_string(), string type and objects implementing __toString()
Sorry, accidently sent in the middle of typing that... On Wed, Mar 8, 2017 at 7:42 AM, Ryan Pallaswrote: > > > On Wed, Mar 8, 2017 at 5:25 AM, Andrey Andreev wrote: > >> Hi all, >> >> I submitted a GitHub PR* to allow objects implementing __toString() to >> *optionally* pass is_string() validation. More verbose wording of my >> motivation can be seen in the PR description, but here are the main >> points: >> >> - Simpler way to do checks like: is_string($var) || >> method_exists($var, '__toString') >> - Can be used for stricter string parameter validation in >> strict_types=0 mode (otherwise any scalar type is accepted) > > - Can be used for looser string parameter validation in strict_types=1 >> mode (__toString() objects aren't accepted there) >> - Regardless of the last 2 points, it is intentionally not limited to >> parameter types >> > > If I understand correctly, you want the following to work: > > declare(strict_type = 0); function foo(string $bar) { return $bar.'foo'; } class Foo { private $val; public function __construct(string $val) { $this->val = $val; } public function __toString() { return $this->$val; } } echo foo(new Foo('this is ')); // this is foo But what happens if I change the foo function like: function foo(string &$bar) { $bar .= 'foo'; } $foo = new Foo('object'); foo($foo); var_dump($foo); // will this be an instance of Foo, or the string "objectfoo"?? If $foo remains an object in this scope, then the function is not modifying its value. If it becomes a string, it's an unexpected change IMO. It is probably fine in this case, but not in the case of a more complex object. > > > >> >> * https://github.com/php/php-src/pull/2408 >> >> --- >> >> I didn't have time to write this email right after submitting the >> patch, and in the meantime got some feedback from Fleshgrinder on >> GitHub, which I'll quote and address here: >> >> > Thanks for your effort and initiative. >> > >> > However, I strongly believe that this is the wrong approach. Adding a >> flag to a function directly results in the fact that the function violates >> the single responsibility principle. What we actually need to make this >> work is a "stringable" pseudo-type like the iterable type that was >> introduced in PHP 7.1. This "stringable" pseudo-type is the union of the >> scalar primitive string and any class that implements the __toString method. >> > >> > This has the advantage that we are actually able to use it together >> with strict_types, plus we have separate dedicated functions like >> "is_stringable" that adhere to the single responsibility principle. I >> actually wanted to create an RFC for that along with an implementation >> since iterable was accepted, but did not find the time yet. >> > >> > Closing note: these pseudo-types are necessary in PHP because it has no >> coherent type system, and there is nothing we can do about this in short >> term. Hence, adding such pseudo-types is the only short term solution that >> we actually have. >> >> I ultimately wouldn't care if it's a separate function and did in fact >> think of an is_stringable() function, but wasn't happy with the naming >> - who's to say that e.g. integers aren't stringable? Bar >> horribly-verbose names like >> "string_or_objects_implementing__toString", I don't think there's a >> way to avoid that ambiguity. :/ >> If we want a "stringable" type though, I guess we'll have to live with >> that. >> >> I feel that debating the actual type system is way broader than I >> intended this to be, so I'll refrain from going further on that for >> now, as I've got some more radical ideas about it. >> >> --- >> >> Thoughts? >> >> Cheers, >> Andrey. >> >> -- >> PHP Internals - PHP Runtime Development Mailing List >> To unsubscribe, visit: http://www.php.net/unsub.php >> >> >
Re: [PHP-DEV] [Discussion] is_string(), string type and objects implementing __toString()
Hi Rowan, On Wed, Mar 8, 2017 at 4:29 PM, Rowan Collinswrote: > Hi Andrey, > > I think this is an interesting area to explore, but do think the scope needs > to be widened slightly. > > > On 8 March 2017 12:25:54 GMT+00:00, Andrey Andreev wrote: >>I ultimately wouldn't care if it's a separate function and did in fact >>think of an is_stringable() function, but wasn't happy with the naming >>- who's to say that e.g. integers aren't stringable? Bar >>horribly-verbose names like >>"string_or_objects_implementing__toString", I don't think there's a >>way to avoid that ambiguity. :/ >>If we want a "stringable" type though > > Sometimes, the fact that you can't think of a good name for a function is a > clue that the function isn't solving a well-defined problem. > > In this case, why *wouldn't* the function return true for integers? If the > question the function is asking is "can this value be cast to string?" then > the answer for any integer should be "yes". If the question is "will it pass > a strict type check as a string", then the answer for objects would always be > "no". Am I missing a situation where casting an object would be safe, but > casting an integer wouldn't? > Well, it may be confusing and/or a bit inconsistent since what __toString() does is casting (and the idea will probably be ridiculed because of this), but putting that aside - it's not about casting at all. The question is rather "is this value a string?", only with the added assumption that __toString() objects are treated as "string objects" and thus fulfill the condition (another reason why I went for an is_string() parameter). It's not so much about whether casting would result in loss of data, which is what I assume you mean by "safe", but about whether the value was ever intended to be used as a string - an object implementing __toString() obviously is, while the same cannot be certainly said for integers. An integer can be a bit flag, or a key from an id => name pair, etc. Cheers, Andrey. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [Discussion] is_string(), string type and objects implementing __toString()
On 03/08/2017 06:25 AM, Andrey Andreev wrote: Hi all, I submitted a GitHub PR* to allow objects implementing __toString() to *optionally* pass is_string() validation. More verbose wording of my motivation can be seen in the PR description, but here are the main points: - Simpler way to do checks like: is_string($var) || method_exists($var, '__toString') - Can be used for stricter string parameter validation in strict_types=0 mode (otherwise any scalar type is accepted) - Can be used for looser string parameter validation in strict_types=1 mode (__toString() objects aren't accepted there) - Regardless of the last 2 points, it is intentionally not limited to parameter types * https://github.com/php/php-src/pull/2408 --- I didn't have time to write this email right after submitting the patch, and in the meantime got some feedback from Fleshgrinder on GitHub, which I'll quote and address here: Thanks for your effort and initiative. However, I strongly believe that this is the wrong approach. Adding a flag to a function directly results in the fact that the function violates the single responsibility principle. What we actually need to make this work is a "stringable" pseudo-type like the iterable type that was introduced in PHP 7.1. This "stringable" pseudo-type is the union of the scalar primitive string and any class that implements the __toString method. This has the advantage that we are actually able to use it together with strict_types, plus we have separate dedicated functions like "is_stringable" that adhere to the single responsibility principle. I actually wanted to create an RFC for that along with an implementation since iterable was accepted, but did not find the time yet. Closing note: these pseudo-types are necessary in PHP because it has no coherent type system, and there is nothing we can do about this in short term. Hence, adding such pseudo-types is the only short term solution that we actually have. I ultimately wouldn't care if it's a separate function and did in fact think of an is_stringable() function, but wasn't happy with the naming - who's to say that e.g. integers aren't stringable? Bar horribly-verbose names like "string_or_objects_implementing__toString", I don't think there's a way to avoid that ambiguity. :/ If we want a "stringable" type though, I guess we'll have to live with that. I feel that debating the actual type system is way broader than I intended this to be, so I'll refrain from going further on that for now, as I've got some more radical ideas about it. --- Thoughts? Cheers, Andrey. I would concur with Fleshgrinder. Given the type system we have to work with, a stringable pseudo-type that translates to is_string() (subject to the type mode) || method_exists($var, '__toString') (not subject to type mode) would be cleaner and more flexible than yet another flag. Flags on method signatures are almost always a code smell. (I suppose there's a debate to be had if an int is stringable in strict mode; I'm not sure there myself.) --Larry Garfield -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] [Discussion] is_string(), string type and objects implementing __toString()
On Wed, Mar 8, 2017 at 5:25 AM, Andrey Andreevwrote: > Hi all, > > I submitted a GitHub PR* to allow objects implementing __toString() to > *optionally* pass is_string() validation. More verbose wording of my > motivation can be seen in the PR description, but here are the main > points: > > - Simpler way to do checks like: is_string($var) || > method_exists($var, '__toString') > - Can be used for stricter string parameter validation in > strict_types=0 mode (otherwise any scalar type is accepted) - Can be used for looser string parameter validation in strict_types=1 > mode (__toString() objects aren't accepted there) > - Regardless of the last 2 points, it is intentionally not limited to > parameter types > If I understand correctly, you want the following to work: declare(strict_type = 0); function foo(string $bar) { > > * https://github.com/php/php-src/pull/2408 > > --- > > I didn't have time to write this email right after submitting the > patch, and in the meantime got some feedback from Fleshgrinder on > GitHub, which I'll quote and address here: > > > Thanks for your effort and initiative. > > > > However, I strongly believe that this is the wrong approach. Adding a > flag to a function directly results in the fact that the function violates > the single responsibility principle. What we actually need to make this > work is a "stringable" pseudo-type like the iterable type that was > introduced in PHP 7.1. This "stringable" pseudo-type is the union of the > scalar primitive string and any class that implements the __toString method. > > > > This has the advantage that we are actually able to use it together with > strict_types, plus we have separate dedicated functions like > "is_stringable" that adhere to the single responsibility principle. I > actually wanted to create an RFC for that along with an implementation > since iterable was accepted, but did not find the time yet. > > > > Closing note: these pseudo-types are necessary in PHP because it has no > coherent type system, and there is nothing we can do about this in short > term. Hence, adding such pseudo-types is the only short term solution that > we actually have. > > I ultimately wouldn't care if it's a separate function and did in fact > think of an is_stringable() function, but wasn't happy with the naming > - who's to say that e.g. integers aren't stringable? Bar > horribly-verbose names like > "string_or_objects_implementing__toString", I don't think there's a > way to avoid that ambiguity. :/ > If we want a "stringable" type though, I guess we'll have to live with > that. > > I feel that debating the actual type system is way broader than I > intended this to be, so I'll refrain from going further on that for > now, as I've got some more radical ideas about it. > > --- > > Thoughts? > > Cheers, > Andrey. > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >
Re: [PHP-DEV] [Discussion] is_string(), string type and objects implementing __toString()
Hi Andrey, I think this is an interesting area to explore, but do think the scope needs to be widened slightly. On 8 March 2017 12:25:54 GMT+00:00, Andrey Andreevwrote: >I ultimately wouldn't care if it's a separate function and did in fact >think of an is_stringable() function, but wasn't happy with the naming >- who's to say that e.g. integers aren't stringable? Bar >horribly-verbose names like >"string_or_objects_implementing__toString", I don't think there's a >way to avoid that ambiguity. :/ >If we want a "stringable" type though Sometimes, the fact that you can't think of a good name for a function is a clue that the function isn't solving a well-defined problem. In this case, why *wouldn't* the function return true for integers? If the question the function is asking is "can this value be cast to string?" then the answer for any integer should be "yes". If the question is "will it pass a strict type check as a string", then the answer for objects would always be "no". Am I missing a situation where casting an object would be safe, but casting an integer wouldn't? My own thought, mentioned somewhere in the long debate about scalar type hints, was to have a "can be cast to" function, which basically predicts if a *weak* type hint would accept the value without errors or warnings. This would work for stringable objects, but also for numeric strings, etc. Regards, -- Rowan Collins [IMSoP] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] [Discussion] is_string(), string type and objects implementing __toString()
Hi all, I submitted a GitHub PR* to allow objects implementing __toString() to *optionally* pass is_string() validation. More verbose wording of my motivation can be seen in the PR description, but here are the main points: - Simpler way to do checks like: is_string($var) || method_exists($var, '__toString') - Can be used for stricter string parameter validation in strict_types=0 mode (otherwise any scalar type is accepted) - Can be used for looser string parameter validation in strict_types=1 mode (__toString() objects aren't accepted there) - Regardless of the last 2 points, it is intentionally not limited to parameter types * https://github.com/php/php-src/pull/2408 --- I didn't have time to write this email right after submitting the patch, and in the meantime got some feedback from Fleshgrinder on GitHub, which I'll quote and address here: > Thanks for your effort and initiative. > > However, I strongly believe that this is the wrong approach. Adding a flag to > a function directly results in the fact that the function violates the single > responsibility principle. What we actually need to make this work is a > "stringable" pseudo-type like the iterable type that was introduced in PHP > 7.1. This "stringable" pseudo-type is the union of the scalar primitive > string and any class that implements the __toString method. > > This has the advantage that we are actually able to use it together with > strict_types, plus we have separate dedicated functions like "is_stringable" > that adhere to the single responsibility principle. I actually wanted to > create an RFC for that along with an implementation since iterable was > accepted, but did not find the time yet. > > Closing note: these pseudo-types are necessary in PHP because it has no > coherent type system, and there is nothing we can do about this in short > term. Hence, adding such pseudo-types is the only short term solution that we > actually have. I ultimately wouldn't care if it's a separate function and did in fact think of an is_stringable() function, but wasn't happy with the naming - who's to say that e.g. integers aren't stringable? Bar horribly-verbose names like "string_or_objects_implementing__toString", I don't think there's a way to avoid that ambiguity. :/ If we want a "stringable" type though, I guess we'll have to live with that. I feel that debating the actual type system is way broader than I intended this to be, so I'll refrain from going further on that for now, as I've got some more radical ideas about it. --- Thoughts? Cheers, Andrey. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] generating code from AST
> On 8 Mar 2017, at 08:49, Sebastian Bergmannwrote: > > Am 07.03.2017 um 11:33 schrieb Derick Rethans: >> Because installing an extension is too hard? > > No. To ensure that userland functionality that is based on compiler > internals (token stream, abstract syntax tree, bytecode) does not fall out > of sync with the compiler. > > We already have an extension that is built-in and enabled-by-default for > the token stream. Why not have one for the abstract syntax tree and > bytecode representations? To be honest, that’s exactly what we might want to avoid. Last time someone wanted to do actual improvements to our lexing they were stopped because changing tokens would mean breaking code that relies on `token_get_all()` which is a core extension user land function. It might be though that it’s only the problem with lexing and it should not be a problem for AST because it is, ahem, abstract. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] ZipArchive::addGlob with remove_path option overcuts filepath
Hi internals, I created a bug report ( https://bugs.php.net/bug.php?id=72374 ) and PR( https://github.com/php/php-src/pull/1939 ) that will change the behavior of ZipArchive::addGlob method. Currently, this method cuts the file path more than the length given by remove_path option and strips the first char of filename. This PR aims to make this method not cut too much file path. I would like to hear your feedbacks and if this change needs an RFC. Best regards, tyage
Re: [PHP-DEV] generating code from AST
Am 07.03.2017 um 11:33 schrieb Derick Rethans: > Because installing an extension is too hard? No. To ensure that userland functionality that is based on compiler internals (token stream, abstract syntax tree, bytecode) does not fall out of sync with the compiler. We already have an extension that is built-in and enabled-by-default for the token stream. Why not have one for the abstract syntax tree and bytecode representations? -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php