Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:123507 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by qa.php.net (Postfix) with ESMTPS id 4A5ED1A009C for ; Tue, 4 Jun 2024 16:57:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1717520284; bh=9n7hg3mUKiCiGt9mTj2NuQfZr/R3XcuUr6yCnbdIoLE=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=TTn+TlOzCCd6qOdZNsSx6hN945A4REJZX+a0yBVEgICVIXLqH0e7rtn0N/dSMzP5R bEFGiCW1s9EUQxr+EMbjWnSqOMHJY6voSV520UdSRj6LRSH7Itqi8F2ybPUYtaEGq2 uuWT3gxQsgU46eInmn6x8ZnwmvKl+xABPFvH8fvXbSMUF/oXHDFzmoNxbqwaA9PTCX fU2++N0OQvZw8N8HBF90yZP3LtSFGDTqTQwFmMk8LmegWI46AMbBOjKnw6gyDxmCm9 q2STDJfYL47V3eevarrg4T+HWLg2yPHjN3bCouyICj0qhoeYCAaeuxbx1g/EQQG8nA wRmFdS70POfSQ== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id BE1AF1804B4 for ; Tue, 4 Jun 2024 16:58:02 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=0.6 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,FREEMAIL_FROM, HTML_MESSAGE,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: Error (Cannot connect to unix socket '/var/run/clamav/clamd.ctl': connect: Connection refused) X-Envelope-From: Received: from mail-lf1-f54.google.com (mail-lf1-f54.google.com [209.85.167.54]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Tue, 4 Jun 2024 16:58:02 +0000 (UTC) Received: by mail-lf1-f54.google.com with SMTP id 2adb3069b0e04-5295e488248so6125918e87.2 for ; Tue, 04 Jun 2024 09:56:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1717520217; x=1718125017; darn=lists.php.net; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=9n7hg3mUKiCiGt9mTj2NuQfZr/R3XcuUr6yCnbdIoLE=; b=PgnDiy2cAHh8uQ3WeR3+bMbLvP7zZyIx+8qB8cRc7ho+gyFbgHfQ6ooP05/6ZxpZfL 8KGqz/Fx+7JoR+Befhd62y1Rvv4HsCNMi3SQGPOPhEpKYOXV0hnvHXaNSeeTUGD1ICQC HX0UMu5Llr4085cWNYpS46cdlyHojheBS+PDYWdguC8IzapxCYlUVmSwdXZt2frD6YQM euZ5TBa/oB/FBNP3G0jjYFzZTcAAnqakLJwfOH9XcFbXxT/bBb9V+KmJHzgz+n9pTAKV B+Fym72EYylJZ5QVdtDW9cxilotGSiMbDO1AcmLbeMOSVDxN95hyOIs52DUMdX6bZbDR +Tqg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1717520217; x=1718125017; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=9n7hg3mUKiCiGt9mTj2NuQfZr/R3XcuUr6yCnbdIoLE=; b=h1AZRk4AeeutzFhvoStKfmRdsBAP+9G+nLzXpHPit7Gz6zrBN4yvqTzNY+p/z4fC7/ PxbAZG2ldEwnuPmg2163bR7ySHUTbGFUEZJCQYmi46EnRnCV7fBulfBitEG1STQ/3+Au 6/oUDwQ5R3TDU9PqUKTUjhQGe5JY1zr12Y8TSfSOH0cA95U6O1PHkhd++IGb6S9R0BpL ISE87OZMqHUffzL0R0LtGHxoCoRDTJVoDMoHnxynXajSH1JYxP95QztpsmCffpptYceZ KVa5im5UteYs/Pzq8Ky6HbkIxeOoSsEEFZFlAxEMGPAa14jG4xg8sEC4cpPeCvhbGtHZ mRTg== X-Gm-Message-State: AOJu0YwXCZD+e7pMH+KI8YcQmgf8kCXbEz68qSLqY9CBGJhDSPyyWueR UsyQyJNWdRQ5rhnMAMbU+aNh/eQt2EJs8fEhJ85cMsTsqGZQJStl/WDHYRGwDyR2iYnKzTWSpuk W9y7nd//Tzz4b7hCmDPFmCwHVIPU= X-Google-Smtp-Source: AGHT+IGFRdDS+/8GK8BRLp//57pYTluU/a0Jy+HJMvH+gYK426m4tQDmn8sely2ENRokR8v2gbP4HxvtK2g/IW0Jfo0= X-Received: by 2002:a05:6512:104b:b0:52b:88db:a554 with SMTP id 2adb3069b0e04-52bab4c92e9mr104319e87.8.1717520216242; Tue, 04 Jun 2024 09:56:56 -0700 (PDT) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net MIME-Version: 1.0 References: In-Reply-To: Date: Tue, 4 Jun 2024 18:56:43 +0200 Message-ID: Subject: Re: [PHP-DEV] [RFC] Lazy Objects To: Valentin Udaltsov Cc: PHP Internals List , Arnaud Le Blanc Content-Type: multipart/alternative; boundary="00000000000062425f061a13569c" From: nicolas.grekas+php@gmail.com (Nicolas Grekas) --00000000000062425f061a13569c Content-Type: text/plain; charset="UTF-8" Hello Valentin, Thanks for having a look. > Arnaud and I are pleased to share with you the RFC we've been shaping for >> over a year to add native support for lazy objects to PHP. >> >> Please find all the details here: >> https://wiki.php.net/rfc/lazy-objects >> >> We look forward to your thoughts and feedback. >> >> Cheers, >> Nicolas and Arnaud >> > Hi, Nicolas and Arnaud! > > I like the idea, thank you for the RFC! > > Here are some initial thoughts and questions: > > 1. It doesn't seem right that calling > `ReflectionLazyObject::makeLazyGhost` has an implicit side effect on > `$instance` and returns reflection. It does 2 things and thus breaks the > SRP. Having smth like `$lazyGhost = new > ReflectionClass(MyClass)->newLazyGhost($initializer)` and/or > `ReflectionLazyObject::makeLazy($object, $initializer): void` seems better. > About "new ReflectionClass(MyClass)->newLazyGhost", we could add this but it would provide a duplicate way to achieve what can be done with "makeLazy($object)" variants. As you might have read in the RFC, being able to make a pre-existing instance lazy is needed to cover all use cases. Then about "ReflectionLazyObject::makeLazy($object, $initializer): void", is the difference only to return void and not a ReflectionLazyObject instance? Then this might provide an underperforming API: creating a lazy object and immediately after setting some of its properties is an use case that can happen on the hot path (of e.g. Doctrine entities creation steps). Returning "void" would force an extra call to ReflectionLazyObject::fromInstance() that the proposed API prevents. > 2. If `ReflectionLazyObject extends ReflectionObject`, then how `new > ReflectionLazyObject($object)` will work for non-lazy objects? Will it > throw? > The constructor is private so this is not allowed (I should add this to the RFC). > 3. Is extending `ReflectionObject` really necessary? What about creating > `ReflectionLazyObject` as a standalone class without abusing inheritance? > Or simply adding methods to `ReflectionObject` / `ReflectionClass`? > I don't think extending ReflectionObject is necessary. I don't know if doing so is "abusing" inheritance. It might make sense either way. For the use cases I identified, it wouldn't harm to not extend anything. Does anyone else see a reason to go in one or the other direction? To me it just makes sense to have ReflectionLazyObject extend ReflectionObject. About adding methods to `ReflectionObject` / `ReflectionClass`, you mention SRP in your message; ReflectionClass/ReflectionObject is already crowded, and this lazy object topic is better separated to me. 4. The RFC says that Virtual state-proxies are necessary because of > circular references. It's difficult to accept this reasoning, because using > circular references is a bad practice and the given example is something I > try to avoid by all means in my code. > Yet circular references happen all the time in any non-trivial app, so this has to be supported. Nicolas --00000000000062425f061a13569c Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hello Valentin,

=
Thanks for having a look.

Arnaud and I are pleased to share with you the RFC we've been shaping for over a year to add native support= =20 for lazy objects to PHP.

Please find all the details here:
https://wiki.php.net/rfc/lazy-objects

We look forward to yo= ur thoughts and feedback.

Cheers,
Nicolas and Arnaud

Hi, Nicolas and Arnaud!

I like= the idea,=C2=A0thank you for the=C2=A0RFC!

Here are some= initial thoughts and questions:

1. It doesn't seem right that c= alling `ReflectionLazyObject::makeLazyGhost` has an implicit side effect on= `$instance` and returns reflection. It does 2 things and thus breaks the S= RP. Having smth like `$lazyGhost =3D new ReflectionClass(MyClass)->newLa= zyGhost($initializer)` and/or `ReflectionLazyObject::makeLazy($object, $ini= tializer): void` seems better.

<= div>About "new ReflectionClass(MyClass)->newLazyGhost", we cou= ld add this but it would provide a duplicate way to achieve what can be don= e with "makeLazy($object)" variants. As you might have read in th= e RFC, being able to make a pre-existing instance lazy is needed to cover a= ll use cases.

Then about "ReflectionLazyObjec= t::makeLazy($object, $initializer): void", is the difference only to r= eturn void and not a ReflectionLazyObject instance? Then this might provide= an underperforming API: creating a lazy object and immediately after setti= ng some of its properties is an use case that can happen on the hot path (o= f e.g. Doctrine entities creation steps). Returning "void" would = force an extra call to ReflectionLazyObject::fromInstance() that the propos= ed API prevents.
=C2=A0
2. If `ReflectionLazyObj= ect extends ReflectionObject`, then how `new ReflectionLazyObject($object)`= will work for non-lazy objects? Will it throw?

The constructor is private so this is not allowed (I s= hould add this to the RFC).
=C2=A0
3. Is extending=C2=A0`Re= flectionObject` really necessary? What about creating `ReflectionLazyObject= ` as a standalone class without abusing inheritance? Or simply adding metho= ds to `ReflectionObject` / `ReflectionClass`?
=
I don't think extending ReflectionObject is necessary. I= don't know if doing so is "abusing" inheritance. It might ma= ke sense either way. For the use cases I identified, it wouldn't harm t= o not extend anything. Does anyone else see a reason to go in one or the ot= her direction? To me it just makes sense to have ReflectionLazyObject exten= d ReflectionObject.
=C2=A0
About adding methods to `Ref= lectionObject` / `ReflectionClass`, you mention SRP in your message; Reflec= tionClass/ReflectionObject is already crowded, and this lazy object topic i= s better separated to me.

4. The RFC says that=C2=A0Virtua= l state-proxies are necessary because of circular references. It's=C2= =A0difficult to accept=C2=A0this reasoning, because using circular=C2=A0ref= erences is a bad=C2=A0practice and the given example is something=C2=A0I tr= y to avoid by all means in my code.

Yet circular references happen all the time in any non-trivial app= , so this has to be supported.

Nicolas
--00000000000062425f061a13569c--