Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:119547 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 78278 invoked from network); 13 Feb 2023 19:35:15 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 13 Feb 2023 19:35:15 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 9B964180504 for ; Mon, 13 Feb 2023 11:35:14 -0800 (PST) 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.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS15169 209.85.128.0/17 X-Spam-Virus: No X-Envelope-From: Received: from mail-qt1-f174.google.com (mail-qt1-f174.google.com [209.85.160.174]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Mon, 13 Feb 2023 11:35:13 -0800 (PST) Received: by mail-qt1-f174.google.com with SMTP id ch10so13930313qtb.11 for ; Mon, 13 Feb 2023 11:35:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=newclarity-net.20210112.gappssmtp.com; s=20210112; h=to:references:message-id:content-transfer-encoding:cc:date :in-reply-to:from:subject:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=TpjYxSl+Go7Ga1KhfFzV2oqk1J6tV+riLfmC8+4fRZo=; b=b1qLFPhcEvxVwrYDZJpQUHTNJENTYKcCrhQNZ2wbdasQpPD5pQ+r9drAksz6KWudrM j/t77nwt+7yALDHd1S+3UUHkA31zTtoqWC7pF/+qRe4irh5kkcuRiXbdoKCtWfqy89bt GgbzB7mWEo8HCR/+LyyCGLuVY4m3Xa7JSFqY532n1g5J7NrU7/1tKbTe5RYkxNlkmJBc BB39Uk6VfTDt1Cfi2SC7IsuCh6LKQ2ODpH6jXMLv1vZiMXexnMLVzx8wdjkGNs/r2nh/ vqGKKNqtAYyRd5YYciMXUEL1G7RW1ZjkJLww3XUUmEpGCRIhRE9Tz3ynqHt+Td5QJqlS LJRg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=to:references:message-id:content-transfer-encoding:cc:date :in-reply-to:from:subject:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=TpjYxSl+Go7Ga1KhfFzV2oqk1J6tV+riLfmC8+4fRZo=; b=qGe8kUiehYJrzx+yC1XPiAGGbyYV46Mkk1cfLlaISjU1PAYbs7IYUunig2P6HAgrAb /OC9bkTKLPoKWWRYHUInZkqddk1BByVpg4yw83rxx8Qya7k05aFnlpFACAmSKmZH2p5p xHn0SeIxvX0yAtIyPf1qldydeyYlCmM37UmmrFgn+hQWYWjlpEmmDJllTu1ydcIKoGc1 SPxtHYlJh1Zyss5+VMaka36bhRC6GjFYjRrbjhoSCkc/j18m+crgXTxu5hEdx1PVSbBP Uw+szzLWe7dcEEmnrr+IpkInjYrWqyqrScJNSkzKB0mCSC5cqUBFmTokpydX2OOTIR6t ivGA== X-Gm-Message-State: AO0yUKU1u36a9zkhCSkzT6T8bbd3Gc1Xqn2ckY47OayEDKl7mNxvJZhP FmsjhmMOP9a8HF3PSkhUWmEH2g== X-Google-Smtp-Source: AK7set/0TMHsAqoowHn/wQQ489vFHBUwyuuMatniwvq4jLKG7fJDBe8rAnzQkPY2nOINv28KIsaNiw== X-Received: by 2002:ac8:5c50:0:b0:3b8:2d45:4760 with SMTP id j16-20020ac85c50000000b003b82d454760mr45898917qtj.61.1676316913285; Mon, 13 Feb 2023 11:35:13 -0800 (PST) Received: from smtpclient.apple (c-98-252-216-111.hsd1.ga.comcast.net. [98.252.216.111]) by smtp.gmail.com with ESMTPSA id x16-20020ac87ed0000000b003b82489d8acsm9789154qtj.21.2023.02.13.11.35.12 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Feb 2023 11:35:12 -0800 (PST) Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3696.120.41.1.2\)) In-Reply-To: Date: Mon, 13 Feb 2023 14:35:11 -0500 Cc: internals@lists.php.net Content-Transfer-Encoding: quoted-printable Message-ID: <51CBD72F-2089-4B29-9F4D-C46E5DA11939@newclarity.net> References: To: Lydia de Jongh X-Mailer: Apple Mail (2.3696.120.41.1.2) Subject: Re: [PHP-DEV] 'Uninitialized' creates a lot of cluttering From: mike@newclarity.net (Mike Schinkel) > On Feb 8, 2023, at 9:22 AM, Lydia de Jongh wrote: >=20 > Hi, >=20 > After posting this in the issues list > , I was asked to mail it = here. > This is my first time here, so I hope I do it the right way. >=20 > ------------------------------- >=20 > At last I have the opportunity to start using php8, I am very happy = with it > and how mature it has become; implementing all kinds of code quality. >=20 > But this new *uninitialized state* is really a pain. > When you set a property in a class, I consider it as set into the = class; it > is part of that class, that object. > Whether it is undefined or not. You could access it with an easy if or > ternary operator. >=20 > And you got a *clean overview* of all your properties and how they are > initialized. >=20 > class Test { >=20 > protected string $name; >=20 > protected string $type =3D 'mytype'; >=20 > protected ?array $arrLog; >=20 > protected ?string $optionalVar; >=20 > protected string $table =3D 'category'; >=20 > protected bool $isOk =3D false; > } >=20 > *This looks clean and gives clear, easy insight* to the purpose of = each > property. > But since php8, you have to use isset() or empty() to check whether a > property is initialized. >=20 > Also php is offering more and more shorthand alternatives like = nullsafe > operator, ternary operator etc. Which I was not in favor of, but it = seems > to be the standard nowadays, so I let phpstorm do its thing and use = the > shorthands. >=20 > But when you start using the (very necessary!!!) typed properties this = is > not working anymore unless you 'initialize' the property with at least = an > empty or dummy value or null. > I read the RFC trying to understand..... >=20 > Maybe it is technically difficult or it is against high-standard rules > (which I love!), but this is really unpractical and gives to much = overhead > and clutter. > I love good quality in coding, I endured years of being called crazy = by > colleagues who learned php by google and stackoverflow and loved it = because > it allowed all the bad coding. (Good is good enough) >=20 > But now it seems to go over the top, making php less practical. >=20 > For this uninitialized-thing we can choose one the following solutions = at > the moment: >=20 > - leave properties untyped, which is really bad > - set many properties to null or other empty values, which clutters = your > property list > - add those empty values inside the constructor, which creates = useless > extra lines of code > - use isset or empty to check if it is set or not, and not be able = to > use shorthands >=20 > To use typed properties and profit from all the new shorthands and = nice new > feature of php 8, my class has to be something like: >=20 > class Test { >=20 > protected string $name =3D ''; >=20 > protected string $type =3D 'mytype'; >=20 > protected ?array $arrLog =3D []; >=20 > protected ?string $optionalVar =3D null; >=20 > protected string $table =3D 'category'; >=20 > protected bool $isOk =3D false; > } >=20 > This looks cluttered. And I do not understand that we get all those = nice > shorthands, but for typed properties, we need to type more.... >=20 > Why does a nullable type not automaticly default to null, or even to = the > empty variant of the type (by giving it not an question-mark but the > exclamation mark, maybe...) like: >=20 > class Test { >=20 > protected !string $name; // defaults to '' >=20 > protected string $type =3D 'mytype'; >=20 > protected !array $arrLog; // defaults to [] >=20 > protected ?string $optionalVar; // defaults to null >=20 > protected string $table =3D 'category'; >=20 > protected !bool $isOk; // defaults to false >=20 > protected !float $someNumber; // default to 0 >=20 > protected ?myObject $oObject; // no default for objects... to > complicated and risky, or not??, so only nullable > } >=20 > I hope this can be considered again. Hi Lydia, I personally appreciate your concern. I program mostly in GoLang these = days, its variables and struct properties are initialized to a "zero" = value by default, and that works extremely well and cuts down on an = entire class of errors. However, I know this is not what you wanted =E2=80=94 and it is likely = you already know how to do this =E2=80=94 but in case this workaround = had not already occurred to you the following is a proof-of-concept that = might reduce the annoyance of having to initialize all your typed = properties, at least somewhat, given that the list does not appear keen = to address your concerns. This workaround uses a base `AutoInit` class with a constructor that = uses reflection to inspect the properties and if they are uninitialized = and without a default get their type and then initialize them to an = appropriate "zero" value.=20 Yes it uses reflection which is a bit slow, but you may or may not find = that the performance drain a concern, given your use-cases.=20 Also, it is just a proof-of-concept, so you may end up needing to fix = edge-case bugs or tweak for your use-cases. Hope this helps. -Mike P.S. This workaround is also a great use-case for a feature I have = always wanted in PHP which is the ability for a parent constructor to = always be called if not explicitly specified otherwise. Too bad for this = workaround that that feature does not already exist. getProperties() as $prop) { if ($prop->isInitialized($this)) { continue; } if ($prop->hasDefaultValue()) { continue; } $type =3D $prop->getType(); if ($type->allowsNull()) { $type =3D "null"; } else { $type =3D $type->getName(); } switch ($type){ case "string": $value =3D ""; break; case "array": $value =3D []; break; case "bool": $value =3D false; break; case "float": $value =3D 0.0; break; case "int": $value =3D 0; break; case "null": $value =3D NULL; break; default: continue 2; } $prop->setAccessible(true); $prop->setValue($this,$value); } } } class Test extends AutoInit { protected string $name; protected int $age; protected float $latitude; protected float $longitude; protected string $type =3D 'unknown'; protected ?array $arrLog; protected ?string $optionalVar; protected string $table; protected bool $isOk; protected array $labels; function __construct() { parent::__construct(); } } $t =3D new Test(); var_export($t); // END=