Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:121013 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 72873 invoked from network); 8 Sep 2023 14:15:51 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 8 Sep 2023 14:15:51 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 7BEB51804C6 for ; Fri, 8 Sep 2023 07:15:50 -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=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,NICE_REPLY_A,SPF_HELO_PASS, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS20473 216.128.176.0/20 X-Spam-Virus: No X-Envelope-From: Received: from mail.online-presence.ca (online-presence.ca [216.128.176.244]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature ECDSA (P-256) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Fri, 8 Sep 2023 07:15:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=online-presence.ca; s=default; t=1694182549; bh=ZpgowEbXFi+ZpEcE0APebfttXmAB/ZaTuQKLbt0kIsA=; h=Date:Subject:To:References:From:In-Reply-To:From; b=ikjPNJsbAQsCsNNHkBQu8zw0MFwbVdI4qh2d+oM/dnuXxNRx447ogMo4rcpfjEfWP d584sLe3lP+MwmgvYDIE2FgK46Q/Ci0MD7lCsFbSuzjU+Dkto1rTV/wjH93KDMmzi1 sdeh4pwkhTDW89L102fWg5odLNVHBm9CC9nB+IxAcYf6mCDOPNFg0U9diCioxFHlfw dBmARP809ie2NlWuqStWDxAb9v1vPcWMVAmu7pkb70Anl/OQ+vBTLMG9mknBb2GaXj 08r4BK8n7LspflqwHC/Wg27iBS4ApU89lZC5rhV9B1rsXuqliGbqbAn1Tj6nl/AzEA mTB7flsPYbmbw== Received: from [10.0.0.211] (S01064075c3d865eb.ed.shawcable.net [70.74.109.64]) (Authenticated sender: lanre@online-presence.ca) by mail.online-presence.ca (Postfix) with ESMTPSA id 47C191055A5 for ; Fri, 8 Sep 2023 14:15:49 +0000 (UTC) Message-ID: <9f0675b9-0474-52e7-1c0e-1186df15c5c5@online-presence.ca> Date: Fri, 8 Sep 2023 08:15:47 -0600 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Thunderbird/102.14.0 Content-Language: en-US To: internals@lists.php.net References: Organization: Online Presence In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Subject: Re: [PHP-DEV] RFC Proposal: Readonly Structs in PHP From: lanre@online-presence.ca (Lanre Waju) If you want a new data object with slightly different values struct Data2 extends Data { {string $t, array $meta} $title; // Overwrite parent type Status $status; {int $x, int $y} $inlineAnonymous = {x: 1, y: 2}; } Regarding array functions and serialization, there are two approaches: ArrayAccess: We can implement array functions similar to ArrayObject, making it possible to use array functions on readonly structs. Conversion to/from Indexed Array: Since these structs are restricted to a default constructor with named/positional arguments, we can easily convert to and from indexed arrays. JSON serialization can also be supported with the property names as keys. For example: foreach (Data as ($propertyName =>)? $property) {} //not real syntax, but you get the idea However, it's important to note that readonly structs are not meant to replace arrays or lists and, ultimately, are not arrays. Allowing Methods in Structs: Initially, I suggested that readonly structs have no methods besides the constructor. However, upon further consideration, I believe it may be beneficial to allow methods in structs. Even PHP enums allow methods, and considering this, I am open to discussing and potentially having a vote on allowing methods within structs as part of the RFC discussion. Cheers, Lanre On 2023-09-08 7:35 a.m., Robert Landers wrote: > On Fri, Sep 8, 2023 at 3:12 PM Lanre Waju wrote: >> Dear PHP Internals, >> >> I am writing to propose a new feature for PHP that introduces the >> concept of structs. This feature aims to provide a more concise and >> expressive way to define and work with immutable data structures. Below >> is a detailed description of the proposed syntax, usage, and behavior. >> >> Syntax >> >> struct Data >> { >> string $title; >> Status $status; >> ?DateTimeImmutable $publishedAt = null; >> } >> The Data struct is essentially represented as a readonly class with a >> constructor as follows: >> >> >> readonly class Data >> { >> public function __construct( >> public string $title, >> public Status $status, >> public ?DateTimeImmutable $publishedAt = null, >> ) {} >> } >> Assertions >> The Data struct will always be readonly. >> It has no methods besides the constructor. >> Constructors >> The Data struct can be constructed in three different ways, each of >> which allows for named or positional arguments, which can be mixed: >> >> 1.1 Class like >> $data = new Data('title', Status::PUBLISHED, new DateTimeImmutable()); >> >> 1.2 Class like (Named Syntax) >> $data = new Data(title: 'title', status: Status::PUBLISHED, publishedAt: >> new DateTimeImmutable()); >> >> 2.1 Proposed struct initialization syntax (Positional Arguments) >> $data = Data{'title', Status::PUBLISHED, new DateTimeImmutable()}; >> >> 2.2 Proposed struct initialization syntax (Named Syntax) >> $data = Data{title: 'title', status: Status::PUBLISHED, publishedAt: new >> DateTimeImmutable()}; >> >> 3.1 Anonymous Struct (Named Arguments) >> >> $data = struct { >> string $title; >> Status $status; >> ?DateTimeImmutable $publishedAt = null; >> }('title', Status::PUBLISHED, new DateTimeImmutable()); >> 3.2 Anonymous Struct (Named Arguments - Named Syntax) >> >> $data = struct { >> string $title; >> Status $status; >> ?DateTimeImmutable $publishedAt = null; >> }(title: 'title', status: Status::PUBLISHED, publishedAt: new >> DateTimeImmutable()); >> Nesting >> The proposed feature also supports nesting of structs. For example: >> >> >> final class HasNestedStruct >> { >> NestedStruct { >> string $title; >> Status $status; >> ?DateTimeImmutable $publishedAt = null; >> }; >> >> public function __construct( >> public string $string, >> public Data $normalStruct, >> public NestedStruct $nestedStruct = NestedStruct{'title', >> Status::PUBLISHED, new DateTimeImmutable()}, >> public struct InlineNamed { int $x} $inlineNamed = {x: 1}, >> public { int $x, int $y} $inlineAnonymous = {x: 1, y: 2}, >> ) {} >> } >> This proposal aims to enhance the readability and maintainability of >> code by providing a more concise and expressive way to work with >> immutable data structures in PHP. >> I believe this feature will be a valuable addition to the language as it >> not only opens the door for future enhancements (eg. typed json >> deserialization, etc.), but should also help reduce reliance on arrays >> by providing a more expressive alternative. >> >> Your feedback and suggestions are highly appreciated, and we look >> forward to discussing this proposal further within the PHP internals >> community. >> >> Sincerely >> Lanre >> >> -- >> PHP Internals - PHP Runtime Development Mailing List >> To unsubscribe, visit: https://www.php.net/unsub.php >> > FWIW (and it isn't worth much), I'm not a fan of the braces styles > (2.1, 2.2) as it is very non-php-ish. > > It'd be great to still have methods, e.g., $data->isAfter($date) or > something. Otherwise, it isn't very useful except as typed arrays, > without any of the usefulness of the array functions. > > Also, what if I want a new $data object but with slightly different > property values? >