Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:98454 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 11477 invoked from network); 9 Mar 2017 11:47:34 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 9 Mar 2017 11:47:34 -0000 Authentication-Results: pb1.pair.com header.from=narf@devilix.net; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=narf@devilix.net; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain devilix.net designates 74.125.82.173 as permitted sender) X-PHP-List-Original-Sender: narf@devilix.net X-Host-Fingerprint: 74.125.82.173 mail-ot0-f173.google.com Received: from [74.125.82.173] ([74.125.82.173:34288] helo=mail-ot0-f173.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 2F/81-06022-5D041C85 for ; Thu, 09 Mar 2017 06:47:34 -0500 Received: by mail-ot0-f173.google.com with SMTP id o24so54361213otb.1 for ; Thu, 09 Mar 2017 03:47:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=devilix.net; s=google; h=mime-version:in-reply-to:references:from:date:message-id:subject:to; bh=PB5txje/Z+eelYovJgV1Tdzpl9KbAvAosvE84BmXfXM=; b=qe4b4kEijqvQSBFdcO5h1665yHml4VXi9pZSrIyxdXYng0dsfhRAMXXXMSU8k8sig6 wZMMnLIknUI0/Ypi3laUIzXeVR45RHNMfmwyWV3wIvmvgrSFfsgJ1CrkcjnpSZd0au/w y4fWZeQsAI0QSgXdsKXKfOHSI5ziDc4B+u3tU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to; bh=PB5txje/Z+eelYovJgV1Tdzpl9KbAvAosvE84BmXfXM=; b=MyGKJ3UmsRm5xfbOVCeqXUmndVzC7Y+GMzQY/cHkAzT4xWzv2DS1K2WgsfWaTMKuUw zDM6X7ZE7xN9Y3b+8/vQT7wIu+vhc3/m9CZpWqj6awOSBYpuRtDFSJtXuO40tnTi+OUU V14bp62IzB3zFj13e+JLZBzR1bqDsbjDVbMDt2vM3u6WSUzCAZbrTjDEobWir6E5dUAW J/WsfFxpX693VkR29EKFINLti0mk95RJjuicUDZVrKAVTZ8ycW/1G9o3SKu5pzXERwvk eVjVS0yIbQBX13YNvzE/X6j9gmNwm07Rj4Iv9gfjpP45xIIxFBz+jJ7RFjsWuGjI9Dqu Fp9g== X-Gm-Message-State: AFeK/H3fCrhQBmtOQUTIsr0pUDsnFbwzc0wsNy5bLGX8dYcRgNv5cN2oCCfZL8ZUuR5IXgtID1VoAhOJdtkPgQ== X-Received: by 10.157.17.147 with SMTP id v19mr6055436otf.117.1489060051035; Thu, 09 Mar 2017 03:47:31 -0800 (PST) MIME-Version: 1.0 Received: by 10.182.242.83 with HTTP; Thu, 9 Mar 2017 03:47:30 -0800 (PST) In-Reply-To: <44add374-6c4b-399a-c542-8d7f100dfaa3@fleshgrinder.com> References: <24efb0e7-b0e3-68ed-5f42-2d5481f8f291@gmail.com> <44add374-6c4b-399a-c542-8d7f100dfaa3@fleshgrinder.com> Date: Thu, 9 Mar 2017 13:47:30 +0200 Message-ID: To: "internals@lists.php.net" Content-Type: text/plain; charset=UTF-8 Subject: Re: [PHP-DEV] [Discussion] is_string(), string type and objects implementing __toString() From: narf@devilix.net (Andrey Andreev) Hi, On Thu, Mar 9, 2017 at 1:49 AM, Fleshgrinder wrote: > 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. > I don't understand what you're trying to say here, or rather what you mean by "stringable" at this point ... Is it a compound type for string and __toString() objects only, or not? Your last comments suggest that it isn't. > 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. > How can "any other scalar value" work? Using the cookie and headers examples: - booleans can be used as On/Off flags for the secure and httpOnly cookie attributes, but aren't valid literal values for any of the attributes, or any HTTP header. - integers are valid as a few headers' values - that is true, but certainly in a minority of cases - floats may be used for the q(uality) attribute in content negotiation (and nothing else AFAIK), but that is a very, very narrow domain - null is obviously invalid ... who sends an empty header? And if you have a use case where you do want to use them, we can already make anything nullable Of course the string values should be validated, unless you want to allow setting arbitrary headers, e.g.: abstract function setHeader(stringable $name, stringable $value); ... but filtering out the known to be invalid types *is* validation. And just that much better if it happens at compile time. > 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. ;) > Yes, and I hate that, which is why I want something that doesn't silently accept every single scalar type. Here's the radical idea I mentioned in my initial email: make strict mode enforceable and/or add dedicated syntax for strict type hints. But that goes way beyond my current proposal ... if anybody wants to talk about this, please start a separate discussion. > 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.) > I explicitly noted that I'm NOT suggesting we should be adding more magic, but simply using that for a hypothetical example. Cheers, Andrey.