Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:111935 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 31724 invoked from network); 26 Sep 2020 22:09:23 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 26 Sep 2020 22:09:23 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 304FB1804B7 for ; Sat, 26 Sep 2020 14:20:20 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,HTML_MESSAGE,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from eastern.birch.relay.mailchannels.net (eastern.birch.relay.mailchannels.net [23.83.209.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Sat, 26 Sep 2020 14:20:16 -0700 (PDT) X-Sender-Id: dreamhost|x-authsender|josh@joshbruce.dev Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id 492CC6413B6; Sat, 26 Sep 2020 21:20:15 +0000 (UTC) Received: from pdx1-sub0-mail-a93.g.dreamhost.com (100-100-138-6.trex.outbound.svc.cluster.local [100.100.138.6]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 9E2B4641397; Sat, 26 Sep 2020 21:20:13 +0000 (UTC) X-Sender-Id: dreamhost|x-authsender|josh@joshbruce.dev Received: from pdx1-sub0-mail-a93.g.dreamhost.com (pop.dreamhost.com [64.90.62.162]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384) by 0.0.0.0:2500 (trex/5.18.10); Sat, 26 Sep 2020 21:20:15 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|josh@joshbruce.dev X-MailChannels-Auth-Id: dreamhost X-Daffy-Battle: 481c046e0bb5d037_1601155214947_2496276890 X-MC-Loop-Signature: 1601155214947:3332834609 X-MC-Ingress-Time: 1601155214946 Received: from pdx1-sub0-mail-a93.g.dreamhost.com (localhost [127.0.0.1]) by pdx1-sub0-mail-a93.g.dreamhost.com (Postfix) with ESMTP id 4DC97BA45C; Sat, 26 Sep 2020 14:20:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=joshbruce.dev; h=from :message-id:content-type:mime-version:subject:date:in-reply-to :cc:to:references; s=joshbruce.dev; bh=ECh6Mn+YkXunVMQ6vHGhDYkie Bs=; b=bh22JWdoNqJFDNIIE7Jg4eR7OLI4WXF3A7LRQnkPwKZY63i+jxDSlGCGs EKDPCS9Xsj6oTJ+rqIJSQxn23eGcf3Fd1O/dG+90CGKSBGfIKYbA3xhxeOBvX1qD Gk8BzwrAxC3tOExBfr00M144jP9t4DQr0taY/LXyYAjiP6lwWg= Received: from joshs-mbp.lan (21.140.29.136.in-addr.arpa [136.29.140.21]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: josh@joshbruce.dev) by pdx1-sub0-mail-a93.g.dreamhost.com (Postfix) with ESMTPSA id 41B54BA45B; Sat, 26 Sep 2020 14:20:12 -0700 (PDT) X-DH-BACKEND: pdx1-sub0-mail-a93 Message-ID: <94DC0839-E43B-4F3A-9105-8F3CB9D7BBC1@joshbruce.dev> Content-Type: multipart/alternative; boundary="Apple-Mail=_973E0C66-3746-49E0-82CA-AF919492C589" Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.120.23.2.1\)) Date: Sat, 26 Sep 2020 16:20:11 -0500 In-Reply-To: Cc: Larry Garfield , php internals To: tyson andre References: <21C5073D-3F39-49DA-8686-E027AE780793@joshbruce.dev> <1bc7759a-63b8-4b96-bb69-97b50f851307@www.fastmail.com> X-Mailer: Apple Mail (2.3608.120.23.2.1) X-VR-OUT-STATUS: OK X-VR-OUT-SCORE: -100 X-VR-OUT-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedujedrvddvgdduieduucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuggftfghnshhusghstghrihgsvgdpffftgfetoffjqffuvfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffktgggufffjgfvfhfosegrtdhmrehhtdejnecuhfhrohhmpeflohhshhcuuehruhgtvgcuoehjohhshhesjhhoshhhsghruhgtvgdruggvvheqnecuggftrfgrthhtvghrnhepuedtffevudekffeifeefvddtveejueffkeduvdfgvdfhleelvdeiueeuleevuddunecuffhomhgrihhnpehgihhthhhusgdrtghomhdpshhtrggtkhhovhgvrhhflhhofidrtghomhdpphhhphdrnhgvthenucfkphepudefiedrvdelrddugedtrddvudenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhhouggvpehsmhhtphdphhgvlhhopehjohhshhhsqdhmsghprdhlrghnpdhinhgvthepudefiedrvdelrddugedtrddvuddprhgvthhurhhnqdhprghthheplfhoshhhuceurhhutggvuceojhhoshhhsehjohhshhgsrhhutggvrdguvghvqedpmhgrihhlfhhrohhmpehjohhshhesjhhoshhhsghruhgtvgdruggvvhdpnhhrtghpthhtohepihhnthgvrhhnrghlsheslhhishhtshdrphhhphdrnhgvth Subject: Re: [PHP-DEV] [RFC][Discussion] Objects can be declared falsifiable From: josh@joshbruce.dev (Josh Bruce) --Apple-Mail=_973E0C66-3746-49E0-82CA-AF919492C589 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 Hey Internals, So, I received a message that said of the mail I should have received = from internals bounced; so, this is part test and part update. I=E2=80=99ve started mapping out call paths in the project that brought = this concept to light. The project, Shoop, never uses is_bool() - instead it always uses empty, = then reverses that for: 1. Booleans 2. Numbers 3. Arrays 4. Strings 5. stdClass or data-only classes 6. Json strings, which it treats as #5 I essentially get standard SPL behavior when I do this. For the object definition I can define two interfaces: 1. Falsifiable 2. Emptiable The checks go like this: 1. if the object implements Falsifiable: the __toBool method would be = called and would return the result. (This check would be inside = is_bool() and could use the empty() implementation) 2. if the object implements Emptiable: the __isempty method would be = called and return the result. (This check would be inside empty()) 3. else: standard output from is_bool() or empty() would be used when = passing an instance to either of those SPL functions, depending on which = the user is using. Because the concepts of emptiness and falsiness are so tightly coupled, = I=E2=80=99m wondering if it would be better to implement both with this = RFC?? Otherwise, Emptiable would be a future enhancement consideration. I=E2=80=99d like to hear what the rest of Internals thinks. Next for me: I=E2=80=99m going to finish solidifying the Shoop project = and make sure my other projects can use latest and then continue going = through the tutorials from Nikita and others on doing development = Internals. Cheers, Josh > On Aug 30, 2020, at 9:32 AM, Josh Bruce wrote: >=20 > Hey Tyson, >=20 > This is great! Thank you so much, sincerely. >=20 > Still slow goings, which is fine, we have at least a year. lol >=20 > Static analyzers seem to be the biggest concern to date. >=20 > Haven=E2=80=99t been able to get one running locally - though I=E2=80=99= ve only spent a few minutes here and there; definitely on the list. >=20 > A use case for this sort of thing is also a concern or question. I = came across Pipeline from the PHP League and saw their interruptible = processor and was wondering if something like this would be helpful = there - for pipeline patterns in general: = https://github.com/thephpleague/pipeline/blob/master/src/InterruptibleProc= essor.php = >=20 > While working on another project, saw this line from the PHP = array_filter docs: >=20 > "If no callback is supplied, all entries of array equal to FALSE = (see converting to boolean) will be removed." >=20 > I=E2=80=99m still field testing the latest iteration of my base = project, but wanted to put a working (non-internals) implementation out = there (note this covers emptiness and falseness for the purposes of the = project): >=20 > Tests - = https://github.com/8fold/php-shoop/blob/master/tests/RfcObjectCanBeDeclare= dFalsifiableTest.php = >=20 > Interface - = https://github.com/8fold/php-shoop/blob/master/src/FilterContracts/Interfa= ces/Falsifiable.php = - for our purposes the efToBool would be __toBool >=20 > Default implementation - = https://github.com/8fold/php-shoop/blob/master/src/Shooped.php#L216 = >=20 > =E2=80=9CType system=E2=80=9D implementation - = https://github.com/8fold/php-shoop/blob/master/src/Filter/TypeAsBoolean.ph= p = >=20 > Cheers, > Josh >=20 >> On Aug 9, 2020, at 3:59 PM, tyson andre > wrote: >>=20 >> Hi Josh, >>=20 >> I'd recommend looking at https://github.com/php/php-src/pull/5156 = (linked to in your RFC's = reference) when implementing this PR. >> Additionally, I didn't see if this was brought up - PHP already has a = class which is falsifiable - SimpleXMLElement. >>=20 >> You can see the source of ext/simplexml/simplexml.c for `_IS_BOOL` >>=20 >> ``` >> static int sxe_object_cast_ex(zend_object *readobj, zval *writeobj, = int type) >> { >> php_sxe_object *sxe; >> xmlChar *contents =3D NULL; >> xmlNodePtr node; >> int rv; >>=20 >> sxe =3D php_sxe_fetch_object(readobj); >>=20 >> if (type =3D=3D _IS_BOOL) { >> node =3D php_sxe_get_first_node(sxe, NULL); >> if (node) { >> ZVAL_TRUE(writeobj); >> } else { >> ZVAL_BOOL(writeobj, = !sxe_prop_is_empty(readobj)); >> } >> return SUCCESS; >> } >> ``` >>=20 >> ``` >> static php_sxe_object* php_sxe_object_new(zend_class_entry *ce, = zend_function *fptr_count) >> intern->zo.handlers =3D &sxe_object_handlers; >> // ... elsewhere in ext/simplexml/simplexml.c >> sxe_object_handlers.cast_object =3D sxe_object_cast; >> ``` >>=20 >> The default handlers would be overridden, so this would probably need = to fall back to the original handlers for types other than bool. >> Also, this might need to copy all of the handlers from the parent = class entry's zend_object_handlers, >> to meet the expected behavior of other cast types and other magic = behaviors from SimpleXMLElement and other classes continuing to work. >>=20 >> =46rom the perspective of static analysis, a few things to note: >> - Static analyzers such as psalm/phan currently deliberately don't = bother handling the possibility that `object` can be false even after it = was checked for falsiness. >> There's hundreds of other things that could be implemented, and = adding the special casing and performance overhead checking for FFI = objects and SimpleXMLElement, subclasses of those is currently low = priority compared to those things. >>=20 >> Code using SimpleXMLElement/FFI is generally limited to a few files = in practice. >>=20 >> Definitely possible for analyzers to support this for known base = classes, though, and the priority would increase if the RFC passed. >>=20 >> I am a maintainer of Phan. >> - For BC reasons, internal data structures such as ArrayObject = probably wouldn't get changed in any php release >> (e.g. could break code using falsiness check instead of null = check). >> So this might lead to inconsistencies with newer extensions if half = of the data structures treat emptiness as false and half don't. >> - This feature may end up getting adopted in cases where it's = convenient but turns out prone to accidental bugs and later is = deprecated and removed. >> For example, = https://stackoverflow.com/questions/25031236/if-elem-vs-elem-is-not-none = = was seen in python >>=20 >> (e.g. `if (!$this->resultSetObject) { $this->resultSetObject =3D = slow_db_operation(); }` >> would not behave the way people would previously expect for most = objects (executed repeatedly instead of once)) >>=20 >> ``` >> > function test(SimpleXMLElement $e) { >> // False positive RedundantCondition in psalm >> if ($e) { >> } >> } >> ```=20 >>=20 >>> And I don=E2=80=99t know of a way to add an interface to new = stdClass() - but thought this might be a valid use case: >>=20 >> `stdClass` isn't a final class. I assume they meant this >>=20 >> ``` >> class EmptyStdClass extends stdClass implements Falsifiable { >> public function __toBool() { return false; } >> } >> function example(stdClass $s) { >> if (!$s) { throw new Exception("Previously impossible"); } >> } >> ``` >>=20 >> Thanks, >> - Tyson >> -- >> PHP Internals - PHP Runtime Development Mailing List >> To unsubscribe, visit: https://www.php.net/unsub.php = >>=20 >=20 --Apple-Mail=_973E0C66-3746-49E0-82CA-AF919492C589--