Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:114926 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 42039 invoked from network); 17 Jun 2021 10:13:23 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 17 Jun 2021 10:13:23 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id CE2B9180502 for ; Thu, 17 Jun 2021 03:30:22 -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=-1.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,FREEMAIL_REPLY, 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 mail-lj1-f181.google.com (mail-lj1-f181.google.com [209.85.208.181]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Thu, 17 Jun 2021 03:30:22 -0700 (PDT) Received: by mail-lj1-f181.google.com with SMTP id l4so8330059ljg.0 for ; Thu, 17 Jun 2021 03:30:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=P1eQaFNoY5fH0LVcbACyTLKNhHKXNobYvEhrhoDSNcI=; b=QPsgqiR0jVFNleAIm7qtf2rV3o4YFnRkco3rf8e8sr30EIlTeXa/Ca6VJS1nBTf1ag s1TnDygRxj7BvrhSNIn/8ItdlA2Tc8rdpq+v1GMjmRbK3haKqGeO4cHMAES9ke805XB4 VbpOS10G267cu9GT8DPbRkheGC8uxE3kBWSE5WeZ5ExMr1wfkKUXkEVZWi4W8oPso8SK UQAccwGDkO0QVM+dQi+3icbBohjZoGA8JjydhlYTtoVsckmllp1Bt+Yk5+llNndomTDb JEr9ipUAp8qSHPPZOYzp99DZ9Na6qsHd3Er7Od6o7zG+MoDYcO1m9qzYMZeSOoeiTr2z 9mfA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=P1eQaFNoY5fH0LVcbACyTLKNhHKXNobYvEhrhoDSNcI=; b=YIT9u1FJ8O9+ShShDkymrvxY+YiQxu+da/rSSLQQbt288A23HgqEpDXQ8RAp5vT3A7 cq36kU2reoTAvskd+TwFxBVyCjvooQ5LciDniAaKiYFzND4NKI637IUz8NIBYQgnSuDZ lTKdnNgqqwPTW71Cueh8eAjD6GzijJXxZNKwZvFDOYi8Mtyo/Z6UAC5DRG5MjM6vJlZ5 bU75Wfos1zhTt4VnsSZpd6DhxC6fFJT2tSHwIHPwsVUXuHvnChD2H24PcZeB6WRNfWrJ 8ahPBQsykjzgqRYw5kwxhVWZtRxU35eU0EaH6dO/zSB9I5K/Lvt5F3waGjfDXlqZHYvD LP0w== X-Gm-Message-State: AOAM532Zvwy49KLjaiCJWocpIK0InXBeDPwj5DRI3XKDk5TIxJmqs4yZ yk9Q9hhEB+P7aHc14WDE+aqTMOxiUzMVel+FTqo= X-Google-Smtp-Source: ABdhPJziqZIh8uBgkWKHIZLWUcXiVM5OP45N5tm/LFlmudq67cyMRg0WVufgICDq7+oEbhMjK01A+jPYdYqcseh6Mq8= X-Received: by 2002:a05:651c:604:: with SMTP id k4mr4038253lje.244.1623925819835; Thu, 17 Jun 2021 03:30:19 -0700 (PDT) MIME-Version: 1.0 References: <88588b8f-5729-4458-90b1-c602f751e128@www.fastmail.com> <33fd3541-8518-4f98-a258-705f85180ed1@www.fastmail.com> <85f85e0e-a926-4b57-8509-72e9c852c78b@www.fastmail.com> In-Reply-To: Date: Thu, 17 Jun 2021 12:30:03 +0200 Message-ID: To: Nicolas Grekas Cc: Larry Garfield , php internals Content-Type: multipart/alternative; boundary="000000000000a208d805c4f3b123" Subject: Re: [PHP-DEV] [RFC] New in initializers From: nikita.ppv@gmail.com (Nikita Popov) --000000000000a208d805c4f3b123 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Thu, Jun 17, 2021 at 11:14 AM Nicolas Grekas < nicolas.grekas+php@gmail.com> wrote: > Le mer. 16 juin 2021 =C3=A0 13:47, Larry Garfield a > =C3=A9crit : > > > On Wed, Jun 16, 2021, at 3:16 AM, Nikita Popov wrote: > > > > > > Arguments and attributes are enough to justify this RFC on its own, > > but is > > > > there a way we can resolve the static property question? Right now > > the RFC > > > > says "these initializers are evaluated lazily the first time a clas= s > is > > > > used in a certain way." Can you be more specific about that certai= n > > way? > > > > Is there a certain way that would be minimally disruptive? > > > > > > > > > Well, here is a non-exhaustive description of current behavior: > > > > > > * If you access a class constant, only that constant is evaluated. > > > * If you access a static property, all initializers in the class and > > > parent classes are evaluated. > > > * If you instantiate a class, all initializers are evaluated. > > > * Inheriting from a class or calling a static method doesn't evaluat= e > > > anything. > > > > > > As you can see, the rules are rather ad-hoc. To the user, it's probab= ly > > not > > > obvious why instantiating an object of a class would require evaluati= ng > > > class constants at that point. The reason is that instantiation > requires > > > resolved property defaults, and we happen to evaluate all initializer= s > at > > > once. > > > > > > The options where static properties and class constants are concerned > > are: > > > > > > 1. Eagerly evaluate initializers on declaration. This is what I tried > in > > an > > > earlier revision of the RFC, and I don't think that approach works. I= t > > > breaks existing code and has various other unpleasant complications. > > > 2. Precisely specify the current behavior. I don't want to do this > > either, > > > because the exact places where evaluation happens are something of an > > > implementation detail. If in the future we find it convenient to > separate > > > evaluation of non-static properties on object instantiation from > > evaluation > > > of static properties and class constants (which are not strictly need= ed > > at > > > that point), I'd like to retain the liberty to make such a change. > > > 3. Do not specify an evaluation order, beyond that evaluation happens > at > > > certain uses of the class. Evaluation order may change across PHP > > versions. > > > If your code relies on any particular order, your code is broken. > > > > > > Unless I'm missing a fourth option here, option 3 is the only one I > would > > > be willing to go for at this time. > > > > Thanks. To clarify, the concern about evaluation order is only relevan= t > > if you are initializing a class whose constructor has some kind of side > > effect, right? Writing to disk or printing or something like that. > > Otherwise, at worst you may initialize a few more objects than you expe= ct > > there should be no behavioral change. > > > > Given that constructors that have side effects are arguably broken to > > begin with (modulo debugging), I'd be comfortable with explicitly sayin= g > > that the evaluation order is undefined, and nothing is guaranteed excep= t > > that the value will be there when you first access it. > > > > In the future, if function initializers or something like that are adde= d > > we can revisit that question, though I would be tempted to say the same > > thing in those cases; if you want to do some kind of DB read in a > function > > that is a default value for a property or a parameter, frankly odds are > > you're already doing something wrong to begin with. But that's a bridg= e > we > > can cross if and when we get to it. > > > > Would others be comfortable with that, if it allowed new-initializers f= or > > static properties and class constants? > > > > Honestly, I don't know. > > Instantiation might fail because of either a throwing constructor or > because of a throwing autoloader. > > Being able to know where to put the try/catch to recover from these might > be important when writing generic code. > > With the current state of the RFC, it's fine. With "undefined evaluation > time", it might make things fragile without any way to make them resilien= t > enough. > > We should think twice before going this way IMHO. I'm not sold yet this i= s > a compromise we should make. > Worth noting that static prop / class constant initializers can already throw, e.g. if you write something like "const Foo =3D [] + 1;". Of course, with constructors this may become more prevalent. Even if we went with evaluation during class declaration, the result would be pretty awkward, in that the only way to catch such an exception would be to wrap the whole class declaration: try { class X { const Foo =3D [] + 1; } } catch (Error) {} Regards, Nikita --000000000000a208d805c4f3b123--