Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:123518 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 A0CEA1A009C for ; Wed, 5 Jun 2024 15:25:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1717601203; bh=Hd5TRRVsPynsxuZk0VdA7I4pNUOuwuJJo+PHROYmU8E=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=mQ0FG7/RsUS8IBypGpju+R2tsET38aes3WvlbwE4lqllGFBG78zTBCpeZYbWWyt4L NuYYtxmKQaUnKj7v9TY4HJ8iFPE2FZ3rRe08B9HmJZUtxRuGGi+ndjTkVUrijVkS4o q9alcYoWoY/JVQpSS6Ir6QPybLxFI8kiIUiT8c8B/noDrfUiNGSnHXnNsWO2D82puH 4rDYBqo7D8C0hTlxddvcKY4OZp3VBayYnsDs/iEPhluSbC9xWs1XFv+/TD2VNBbT3e oE6d84tZiGOQEPKcxBDl0fa1xgOyvx/l5BKiPMGPnULnHcSMLsHoG60H0lJS4j7q7z rYYEu9C8jD/nA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 154CA18006E for ; Wed, 5 Jun 2024 15:26:42 +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-f42.google.com (mail-lf1-f42.google.com [209.85.167.42]) (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 ; Wed, 5 Jun 2024 15:26:41 +0000 (UTC) Received: by mail-lf1-f42.google.com with SMTP id 2adb3069b0e04-5295e488248so7297053e87.2 for ; Wed, 05 Jun 2024 08:25:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1717601135; x=1718205935; 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=55b9V6tV/Hj+pYneTKRPxA2QjrMRz32UcoI+UfIJ4UI=; b=H7mKA2oR5klb+2Y9I4n1lnlR6wkBhj6wFuSBoDj3+/LGyU5uL2DjnP2ZULLLNHoc78 Zv3g5r6rBI3DlzKWMZeDa+qAk+CqaFMGqIon/WDwbP37EIZ3nMq7rIOZ/DYZLWG/1A6/ OXCFBS8grR6PVlnxFqIZS4/DifDql4/3cA7NPIOSzR08OjVUnztI7dku6eYL6P02p27E oKju9lXnrQWg/1bq3yjF4bkvqWP837fPXzBKBnjb1pKrO0SbwEvyLax/xgNv5j0teJLT bpHYmZV2nMGYQQA8q9/uwe3BUiKl5amvry327j3GrATqG0a+MjKVZMBdWlZBuFncy1p2 0Cxg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1717601135; x=1718205935; 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=55b9V6tV/Hj+pYneTKRPxA2QjrMRz32UcoI+UfIJ4UI=; b=QQ004IgJ7+WMcJ1uzSBly+srA4km7/9c2wof2AxN7/QPotPVtTryiB6cqC671mY18b qIHKMCxiEQjmBRIYhTGKtrgtiktlnBypN77tWUMUpsGCiTdDNwXaVT2AvqbEb7yO2k6O BwFOOIXPIQBVImzKTXT2QKKsFBuDY9xZ0//TbNKZ1VQWGEUeX/5Ib6IfcIUSSSSbYbIy 1Qit71LEqxphMncWAN5enqlWZy8FezfTEv3gfLH0Lci7V0dVZXsQ9a8t1SrzktSBZQ3/ OBYvUwxKagJFIUjUv5OiiX16n/SAtdN6gK3SzV9TErfmJvzfvoG7w9hMTX0oDKRtal0Y mbtg== X-Gm-Message-State: AOJu0YymgwOM6S3BI3jkRMWXviIbcm19r+azmYLDCr5yuPCJNy7T5Kif YbJTeevc3zQ0Lp0ojCsRtEPx9dR3G57HEjqEMjk/9neYiKLwf2xYP4qKWerU5c4boGoTbbryrVD ZVEuH23TtgbA/8bywWyasvk1XxtXshXfruNw= X-Google-Smtp-Source: AGHT+IGyysi8SBlu7flgLE3gM0RxUWx8+0WaRkXg2Fct8FaNZG/EIqqVGhVxFGTi6TUTKB+KWX8o9BkLikfjTmlC/V4= X-Received: by 2002:a05:6512:2245:b0:52b:74c4:2731 with SMTP id 2adb3069b0e04-52bab276836mr2399582e87.0.1717601134767; Wed, 05 Jun 2024 08:25:34 -0700 (PDT) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net MIME-Version: 1.0 References: In-Reply-To: Date: Wed, 5 Jun 2024 17:25:21 +0200 Message-ID: Subject: Re: [PHP-DEV] [RFC] Lazy Objects To: =?UTF-8?Q?Tim_D=C3=BCsterhus?= , Valentin Udaltsov Cc: PHP Internals List , Arnaud Le Blanc Content-Type: multipart/alternative; boundary="00000000000080f784061a262d42" From: nicolas.grekas+php@gmail.com (Nicolas Grekas) --00000000000080f784061a262d42 Content-Type: text/plain; charset="UTF-8" Hi Tim, Thanks for the detailed feedback. Arnaud already answered most of your questions, here is the remaining one: On 6/4/24 14:28, Nicolas Grekas wrote: > > Please find all the details here: > > https://wiki.php.net/rfc/lazy-objects > > > > We look forward to your thoughts and feedback. > > I've gave the RFC three or four passes and I'm not quite sure if I > follow everything, here's a list of some questions / remarks that came > to mind, roughly ordered by the order of things appearing in the RFC. > > - "been tested successfully on the Doctrine and on the Symfony projects" > > Is there a PoC patch showcasing how the code would change / be > simplified for those pre-existing codebases? > Yes! See https://github.com/nicolas-grekas/symfony/pull/44 for Symfony. All the complex code is gone \o/ And if anyone is wondering: No, we're not moving this complexity into the engine. As Arnaud wrote somewhere: Implementation in core is simple compared to userland as we are at the right level of abstraction. No code gen, no edge cases with relative type hints, visibility, readonly, hooks, etc. We get more consistent and transparent behavior as well compared to userland impl. For Doctrine, the URL is https://github.com/nicolas-grekas/doctrine-orm/pull/6 for now, with the most important line being the removal of the symfony/var-exporter dependency. After yours and Valentin's feedback, we're considering an updated API that would provide the same capabilities but that might be more consensual. The RFC isn't updated but below is what we have in our drafts. Let me know what you think already if you want (otherwise, let us work on the updated implementation/RFC and we'll let you know about them ASAP). Nicolas PS: I understand that the concepts in the RFC might be difficult to grasp. They were certainly challenging for me to summarize. I would happily accept any help to improve the wording if anyone is willing. class ReflectionLazyClass extends ReflectionClass { public int const SKIP_INITIALIZATION_ON_SERIALIZE = 1; public int const SKIP_DESTRUCTOR = 2; public function __construct(object|string $objectOrClass); public function newLazyGhostInstance(callable $initializer, int $options = 0 ): object; public function newLazyProxyInstance(callable $initializer, int $options = 0 ): object; public function makeInstanceLazyGhost(object $object, callable $initializer, int $options = 0): void; public function makeInstanceLazyProxy(object $object, callable $initializer, int $options = 0): void; public static function isInitialized(object $instance): bool; /** * Initializes a lazy object (no-op if the object is already initialized.) * * The backing object is returned, which can be another instance than the lazy object when the virtual strategy is used. */ public function initialize(object $object, bool $skipInitializer = false): object; /** * Marks a property as *not* triggering initialization when being accessed. * * This method is useful to bypass initialization when setting a property. */ public function skipInitializerForProperty(object $object, string $name, string $class = null): void; /** * Sets a property *without* triggering initialization while skipping hooks if any. */ public function setRawPropertyValue(object $object, string $name, mixed $ value, string $class = null): void; } --00000000000080f784061a262d42 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi Tim,

Tha= nks for the detailed feedback. Arnaud already answered most of your questio= ns, here is the remaining one:

On 6/4/24 14:28, Nicolas Grekas wrote:
> Please find all the details here:
> https://wiki.php.net/rfc/lazy-objects
>
> We look forward to your thoughts and feedback.

I've gave the RFC three or four passes and I'm not quite sure if I =
follow everything, here's a list of some questions / remarks that came =
to mind, roughly ordered by the order of things appearing in the RFC.

- "been tested successfully on the Doctrine and on the Symfony project= s"

Is there a PoC patch showcasing how the code would change / be
simplified for those pre-existing codebases?

Yes!
See https://github.com/nicolas-grekas/symfony/pull/44 for Symfo= ny. All the complex code is gone \o/
And if anyone is wondering: No, we&= #39;re not moving this complexity into the engine. As Arnaud wrote somewher= e: Implementation in core is simple compared to userland as we are at the r= ight level of abstraction. No code gen, no edge cases with relative type hi= nts, visibility, readonly, hooks, etc. We get more consistent and transpare= nt behavior as well compared to userland impl.

For= Doctrine, the URL is https://github.com/nicolas-grekas/doctrine-orm/pull/6 for = now, with the most important line being the removal of the symfony/var-expo= rter dependency.
=C2=A0
After yours and Valentin= 9;s feedback, we're considering an updated API that would provide the s= ame capabilities but that might be more consensual.

The RFC isn't updated but below is what we have in our drafts. Let me= know what you think already if you want (otherwise, let us work on the upd= ated implementation/RFC and we'll let you know about them ASAP).
<= div>
Nicolas
PS: I understand that the concepts in the R= FC might be difficult to grasp. They were certainly challenging for me to s= ummarize. I would happily accept any help to improve the wording if anyone = is willing.


class ReflectionLazyClass extends ReflectionClass
{
public int const SKIP_INITIALIZATION_ON_SERIALIZE =3D 1;=
public int const SK= IP_DESTRUCTOR =3D 2;

p= ublic function __construct= (object|string $objectOrClass);

public= function newLazyGhostInst= ance(callable = $initializer, <= /span>int $options =3D 0): object;
<= /span>public<= span style=3D"color:rgb(101,123,131)"> function newLazyProxyInstance(callable <= span style=3D"color:rgb(133,153,0)">$initializer, int $options =3D 0): object;

public function makeInstanceLazyGhost(object $object, callable $initializer, int $options =3D 0): <= /span>void;
public function makeInstanceLazyPr= oxy(object $object, callable $initializer, int $options = =3D 0)= : void;
= public static functi= on isInitialized(object $instance): bool;
/**
* Initializes a lazy object (no-op if the obje= ct is already initialized.)
*
* The backing object is returned, whi= ch can be another instance than the lazy object when the virtual strategy i= s used.
*/
= public= function initialize(object $obj= ect, bool $skipInitializer =3D false): object;
/**
* Marks a property as *not*= triggering initialization when being accessed.
*
* This method is = useful to bypass initialization when setting a property.
<= span style=3D"color:rgb(147,161,161);font-style:italic"> */
public function skipInitializerForProperty(object= $object= , string $name, string $class =3D null): void;
/**
* Sets a property *without* trigge= ring initialization while skipping hooks if any.
*/
public functio= n setRawPropertyValue(object = $object, string= $name, mixed $= value, string = $class <= span style=3D"color:rgb(133,153,0)">=3D null)= : void;=
}
--00000000000080f784061a262d42--