Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:98441 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 56340 invoked from network); 8 Mar 2017 19:39:32 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 8 Mar 2017 19:39:32 -0000 Authentication-Results: pb1.pair.com header.from=rowan.collins@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=rowan.collins@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 74.125.82.44 as permitted sender) X-PHP-List-Original-Sender: rowan.collins@gmail.com X-Host-Fingerprint: 74.125.82.44 mail-wm0-f44.google.com Received: from [74.125.82.44] ([74.125.82.44:38002] helo=mail-wm0-f44.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 6B/8B-06022-3FD50C85 for ; Wed, 08 Mar 2017 14:39:31 -0500 Received: by mail-wm0-f44.google.com with SMTP id t189so39516921wmt.1 for ; Wed, 08 Mar 2017 11:39:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-transfer-encoding; bh=e2MQ1YZYB4Ee3F+A37QCrXcR/sXZdpVha69D1TmIvEE=; b=ZUZqfnL4wM2YEqmVdk8MPjiaSH5HVmb0I1lwS3EL690+/Qb9HQfUiSIXF4fSY7LYvt M1aRNOmKVaWlt7/GIKzLzJ8p/O4yOrFLbbkOaTCklxulI1vc7XXD0lCyGKPvZzDo5OGk T5ggYfEtaFPT/1zmjNpnaA+gDuwpnlVN4QNwRE0W75T4rzZ0l0pKUNNBKId8NdGtdtYq ZSfRiLIhMgBQedFxIoyHvgdK5BdtlDp+jQPM1W2FtzucxkOpoUuz8vMR9SuCY1SFv8NK FDown/j5n/ppVYjSbAvvNsYB8TJY1+505K0qh40SDBOnV1+zvCiG3KAcWybkvOCo+faK CeHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-transfer-encoding; bh=e2MQ1YZYB4Ee3F+A37QCrXcR/sXZdpVha69D1TmIvEE=; b=JyAPpoKniy68tguP6NIdF/Lij22Wc8Sq1AjnixO7FEXBrlsL65ND0QmmzSX/X/n9dq oxtMm2Gc/kgc5HtFnVzah0jjBamsx97Xa97zI9bvOeguEMe04std1iOWTcsl+oki5Dx9 RPmnejWzFlIspc3lZDvOWwgi9keXYDRXHK72WJXdZe9dRVGD+Lyv3o9flrKexQAWmvAu K/hrhFm3ZKLamIi7PjqC1pYlNC0KBb6lVxbUcmHWqv7ZWdP5g68vYyGqScONLLS9e8iX rgpRbA2KYxa3DDPeCY9b/Q/U0BR0SyemuRmZSwBwg+/x5lTERS9u9Dj51rRFw5zyYVG5 itSw== X-Gm-Message-State: AMke39lhvmBUKSjGk11HKxjnJD4PyX3CKvW+ZZyV69HJEWGAo4+oC+bJRMsDugPLkirNgw== X-Received: by 10.28.169.199 with SMTP id s190mr24305955wme.2.1489001967915; Wed, 08 Mar 2017 11:39:27 -0800 (PST) Received: from ?IPv6:2a00:23c4:4bd2:6e00:a4c4:59ab:eee3:d540? ([2a00:23c4:4bd2:6e00:a4c4:59ab:eee3:d540]) by smtp.googlemail.com with ESMTPSA id j74sm5417588wrj.21.2017.03.08.11.39.26 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 08 Mar 2017 11:39:26 -0800 (PST) To: internals@lists.php.net References: Message-ID: Date: Wed, 8 Mar 2017 19:39:22 +0000 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; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [PHP-DEV] [Discussion] is_string(), string type and objects implementing __toString() From: rowan.collins@gmail.com (Rowan Collins) 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]