Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:98449 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 75110 invoked from network); 8 Mar 2017 23:50:07 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 8 Mar 2017 23:50:07 -0000 Authentication-Results: pb1.pair.com smtp.mail=php@fleshgrinder.com; spf=permerror; sender-id=unknown Authentication-Results: pb1.pair.com header.from=php@fleshgrinder.com; sender-id=unknown Received-SPF: error (pb1.pair.com: domain fleshgrinder.com from 212.232.28.122 cause and error) X-PHP-List-Original-Sender: php@fleshgrinder.com X-Host-Fingerprint: 212.232.28.122 mx201.easyname.com Received: from [212.232.28.122] ([212.232.28.122:49934] helo=mx201.easyname.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 31/8E-06022-BA890C85 for ; Wed, 08 Mar 2017 18:50:06 -0500 Received: from cable-81-173-135-7.netcologne.de ([81.173.135.7] helo=[192.168.178.20]) by mx.easyname.com with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1cllLE-0004Jy-Do; Wed, 08 Mar 2017 23:50:00 +0000 Reply-To: internals@lists.php.net References: <24efb0e7-b0e3-68ed-5f42-2d5481f8f291@gmail.com> To: Andrey Andreev , Rowan Collins Cc: "internals@lists.php.net" Message-ID: <44add374-6c4b-399a-c542-8d7f100dfaa3@fleshgrinder.com> Date: Thu, 9 Mar 2017 00:49:56 +0100 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-DNSBL-PBLSPAMHAUS: YES Subject: Re: [PHP-DEV] [Discussion] is_string(), string type and objects implementing __toString() From: php@fleshgrinder.com (Fleshgrinder) 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