Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:128022 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 lists.php.net (Postfix) with ESMTPS id 683FD1A00BC for ; Sun, 13 Jul 2025 18:15:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1752430431; bh=5nnip2VacY4SuLJ4TopYzY62AZ1FDVmCFCxwPMgn5Bg=; h=References:In-Reply-To:Reply-To:From:Date:Subject:To:Cc:From; b=lTl28ZbeH1Z8d7EaTiYv3R8tIMvri2XLvXqQsScaF1zCgLJtYLeb88A9ji/2Mp8sx Zka+LBbCC/be3F8rA90VTfcT5ElgQKPwnZgteG9CYOYcVdSN/Su1JQYCTCxs5o3pwW YLxdvAdI7vfrtxAK74BDB+jdijkbac7cPM5zVsE8qy+g9J/I8EyMn3zrWQ3qdaeFBY yRMlxqqXNX1ESTwLt1r8PQGqNjmw3Iy+c4nYGmvn75P5999Jk96zoWw0DHqBv0zh6P Rkm1ucZr9JhsvpAsDkqEitrOobE5Kyr13wwNbQJ798hRtWTrcQdbH7LjAfvl4IaxE6 ncxZMzBrtwXFw== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id B44D318005D for ; Sun, 13 Jul 2025 18:13:50 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) 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, FREEMAIL_REPLYTO,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: Error (Cannot connect to unix socket '/var/run/clamav/clamd.ctl': connect: Connection refused) X-Envelope-From: Received: from mail-io1-f49.google.com (mail-io1-f49.google.com [209.85.166.49]) (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 ; Sun, 13 Jul 2025 18:13:50 +0000 (UTC) Received: by mail-io1-f49.google.com with SMTP id ca18e2360f4ac-86d1131551eso138122739f.3 for ; Sun, 13 Jul 2025 11:15:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1752430538; x=1753035338; darn=lists.php.net; h=content-transfer-encoding:cc:to:subject:message-id:date:from :reply-to:in-reply-to:references:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=5nnip2VacY4SuLJ4TopYzY62AZ1FDVmCFCxwPMgn5Bg=; b=Hp8LCZet4ttl7iXJu7/IGXLLqrEQDvohJ6S4sWZvml5VgRqmBUcW5Bq+17x86KZ6Ab Kcps6xGV9ctSG55F8Wdd0p+frXdsILgunoFVUTKWEXuXrg9a7ntRUKyc2PbPyjtlUmTN IiosXA57ujcG3ZzvQLq/0gG3+ZtPJ/r8NYlbYqU1TMttims93CMKFhfanT4q6SIxdU8I 01cnPym+3sI+Uyip3rHsrRyjQws/oRWktqCJD1wPP2Ij/jcV+VUUFqTnBYpiqxwz3Clh ilALUEV6I/fsY/lu4WDs9v16xrrpzmjZNJZpQ/TnYvHH8P3uPt4a2DITGouWMIfeX2ZA 7IAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752430538; x=1753035338; h=content-transfer-encoding:cc:to:subject:message-id:date:from :reply-to:in-reply-to:references:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=5nnip2VacY4SuLJ4TopYzY62AZ1FDVmCFCxwPMgn5Bg=; b=QM9xAlgyXFamD2dL3/90McJ0+PQoE411C4aKnd2RH+my5FKiQw8YgwN1OSHmPNC5Y/ tDqRLltFW0NphC2+q3MlG1zjfFK0hlYY3JGfZwh298AiWqm63cNIl/wXETkFsH+k5W8T oC4VqzOgWtT1w6rVDL71H55A5frNsxUm+D9G4jlt0qZdGmtZO0r2XmmZOfB9LByYfl4u szVOWNHtF4/QAMVOdttX3oBVA2vO5J5yAYg6z5PHrhfS03ypk+QOwmgqwIJ2iT0d3poi oh1UTAqUBbU1r9XEgwfQ+8y7OWNMpT6pS1X/gP2ViEpxjkEZc9Ch3M1dfEThEdOE2vNJ 7eDg== X-Gm-Message-State: AOJu0Yzrydct9e1G6pkU8XdhP2ZU62g4KolL+Rs1WE3tztPYUo0bf2am gp1bn6nt8dahO7DUezDS/tVQ0Hyrx3uO+NrNMDCMeqrU2DFNZ1gTIuE2yp3Z5UKtyuDwptp0mgS L3CucxQqYAaCc5GepgW6aa4PGdnzNI0fiJw== X-Gm-Gg: ASbGncvHxe3vIRlEnNungDAH9fewQJzkowEXK3cebrmYJrKH3cJCzlxak+N2CEL8OnY IuA7W7wjlS0dkCxMf+8HTsPnK8cFAaZ1MTVdp80qdBW4OOc51yW1IOW5NKH0ztQOrv6s5ohhu+n yBGC7qdI4ELnB+CIcdwUOdGah41lDnARkItokOhcQcdlRXdZK7VVlKcWc3d487PYRs+cboBxbG5 qTCqccx X-Google-Smtp-Source: AGHT+IFQNjJ6RWf5rS+02CCiVmO5RE7VmK3NZLfWsj5FdEOmhZ9wGM4YgPuYqVuJH0Xj/PFRq7c6SsQo8XolUwtmoUQ= X-Received: by 2002:a05:6e02:4516:20b0:3df:2e87:7184 with SMTP id e9e14a558f8ab-3e25332e4e7mr84132905ab.20.1752430538116; Sun, 13 Jul 2025 11:15:38 -0700 (PDT) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 References: <1e8634d7-ac1a-4025-b4e2-1948aabf5251@app.fastmail.com> <9D5043B2-1589-4FD5-B289-6E98FB1177BE@nicksdot.dev> <16BD443D-A179-465D-84A0-6E3780F62D8E@gmail.com> <203C1BD7-E688-4E26-8EA6-EA5331525470@nicksdot.dev> <71E5E8FE-605D-4B32-8CCD-F7ECBD454E24@nicksdot.dev> In-Reply-To: Reply-To: erictnorris@gmail.com Date: Sun, 13 Jul 2025 14:15:21 -0400 X-Gm-Features: Ac12FXyUQgLHb4YiEJerDb2dpFOO2lcuz6SWpB4FYGkVrOBk0MIDCJ8QRvldFFk Message-ID: Subject: Re: [PHP-DEV] [RFC] Readonly property hooks To: Marc Bennewitz Cc: internals@lists.php.net, Nick Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable From: eric.t.norris@gmail.com (Eric Norris) On Sun, Jul 13, 2025 at 2:00=E2=80=AFPM Marc Bennewitz w= rote: > > > On 13.07.25 18:17, Nick wrote: > > > On 13. Jul 2025, at 20:38, Marc Bennewitz wrote: > > Hi Nick, Claude, > > Hey Marc, > > I think it's important to explicitly mark it as "this value will be store= d in memory", I mean just silently caching the get hook could quickly lead = to unexpected behavior. Like one would expect the value to be changed > > The most here made the argument that "a changing value from a readonly ge= t hook" would be the unexpected behaviour. > That=E2=80=99s why we ended up with the current =E2=80=9Calternative impl= ementation 2=E2=80=9D. Please see my last answer to Rob for a fair example = [1] . > > The current preferred alternative implementation covers both situations..= . > > If a property is `readonly`: > - you can set once > - on read you always get the same (once computed) value back > > This is exactly the behavior I mean which is somehow unexpected if not ma= rked explicitly as the result could be cached and the property value will n= ever change. > > Not being able to write to something doesn't generally mean reading the v= alue will never change. `get =3D> random_int(0, 100);` > > I don't want to say that the path we want to go with readonly being able = to assume the value will never change is wrong but I think it's not clear f= or the user and can be missed quickly - even with a test as you have to rea= d the property multiple time to notice the difference. > > > If a property is NOT `readonly`: > - you can set often > - on read you always get the fresh (often computed) value back > > I argue that this is a very easy mental model. > I hope that voters agree on =E2=80=9Ccached may be implied by readonly=E2= =80=9D, as Claude called it. > > All what I'm saying is that this behavior should be explicit and not appl= ied implicitly on a readonly get hook. I agree with Marc here, not surprisingly. > To have an `init` hook doesn=E2=80=99t solve the get hook issue. > > As far as I understood the init hook it would still disallow readonly+get= but allow readonly+init and init would be called once the first time the p= roperty gets read and the result would end up in the backing store. > > As a result you get the same behavior as `cached get` with the only diffe= rence that you write `init =3D> random_int();` instead of `cached get =3D> = random_int();` Agreed. Nick, I am not sure how the init hook doesn't "solve the get hook issue". As I understand it, the get hook issue is that get hooks are not allowed on readonly properties. The init hook would be identical to a "cached get" hook on a readonly property, so why doesn't it solve the issue? > Or did I misunderstand it? I share the same understanding as you, Marc. > The cached modifier I would expect to be an attribute applicable to any f= unction which uses another cache store similar to how it's possible in pyth= on to memorize function calls which would be a very different feature. > > As earlier answered to Claude [2], I seek to write less code. To introduc= e a `cached` modifier voids this for no strong reason (please see =E2=80=9C= mental model=E2=80=9D above). > > See above - and `init` is just once more character. I was going to respond to this point earlier, but Marc beat me to it. An "init" hook is one more character than a get hook, is explicit over a get hook that works differently only for readonly properties, *and* is far fewer characters than the explicit "cached" modifier get hook option. On top of that, as Claude mentioned an init hook provides the ability to differentiate between a null property and an uninitialized property - an init hook would only be called for uninitialized properties, so no need for $this->foo ??=3D "bar".