Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:98427 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 26016 invoked from network); 8 Mar 2017 15:13:22 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 8 Mar 2017 15:13:22 -0000 Authentication-Results: pb1.pair.com smtp.mail=larry@garfieldtech.com; spf=permerror; sender-id=unknown Authentication-Results: pb1.pair.com header.from=larry@garfieldtech.com; sender-id=unknown Received-SPF: error (pb1.pair.com: domain garfieldtech.com from 66.111.4.25 cause and error) X-PHP-List-Original-Sender: larry@garfieldtech.com X-Host-Fingerprint: 66.111.4.25 out1-smtp.messagingengine.com Received: from [66.111.4.25] ([66.111.4.25:60736] helo=out1-smtp.messagingengine.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 26/56-06022-09F10C85 for ; Wed, 08 Mar 2017 10:13:22 -0500 Received: from compute7.internal (compute7.nyi.internal [10.202.2.47]) by mailout.nyi.internal (Postfix) with ESMTP id E94AA206AC for ; Wed, 8 Mar 2017 10:13:17 -0500 (EST) Received: from frontend2 ([10.202.2.161]) by compute7.internal (MEProxy); Wed, 08 Mar 2017 10:13:17 -0500 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d= messagingengine.com; h=content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-sender:x-me-sender:x-sasl-enc:x-sasl-enc; s= smtpout; bh=VISdL9PkP+tkRIGX+5Q7R3udjJQ=; b=bp4SLEYEIqEZ4slHMD5E BkoUakf8PLgKXfkj4Tlao1Oo0FkQK4HpCrv/vN7CP07/P3zr6mHT0U4MZq2VH1pt 58LKtALDk77N2VBLfh4piMIZCyRkH/pMSI5p03JNuM8euHH+ZObeYko0as0/x+xv SLnAPwX5yt6Ax8mAcr2s1x8= X-ME-Sender: X-Sasl-enc: 3oHvqs/GRasYF2Q1VymPIwO/b6nwpFxWm3NmR/5UaD3a 1488985997 Received: from [192.168.42.5] (c-50-178-40-84.hsd1.il.comcast.net [50.178.40.84]) by mail.messagingengine.com (Postfix) with ESMTPA id A6687246BB for ; Wed, 8 Mar 2017 10:13:17 -0500 (EST) To: internals@lists.php.net References: Message-ID: Date: Wed, 8 Mar 2017 09:13:17 -0600 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.7.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: larry@garfieldtech.com (Larry Garfield) 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