Re: [PHP-DEV] RFC Proposal: Readonly Structs in PHP
On Fri, Sep 8, 2023, at 1: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 As I have stated in the past, I am firmly opposed to anemic structs. They offer no benefit, much confusion, and more work for future RFCs. The core concept -- that service objects and data objects are separate creatures that should not be comingled -- I fully agree with and advocate for. If I were writing PHP from scratch today, I would probably design it with separate constructs, or take a cue from Go/Rust and eliminate classes all together per se, as they just confuse matters. However, we are dealing with PHP as it exists today, and an entirely separate limited construct just doesn't make sense. I also want to make clear that I am 1000% in favor of structured, typed data. The use of associative arrays as a pseudo data structure is the weakest part of PHP, and the more we can move people away from that towards more formally typed data, the better. For that reason, making it trivial to cast between an associative array and a structured object (as a few others in the thread have suggested) is a *bad* feature, because it further reinforces the idea that an associative array is "just as good" as making a defined type. This is simply flat out false, and we should avoid language features that pretend that it is true. That said, as of PHP 8, we already have perfectly good struct-ish data structure: Classes with promoted properties and named arguments. As of PHP 8.2, the entire class can be declared readonly with a single keyword. For 95% of use cases, this is completely adequate as a struct-like structure: readonly class Person { public function __construct( public string $first, public Status $last, public
Re: [PHP-DEV] RFC Proposal: Readonly Structs in PHP
On Sat, Sep 9, 2023 at 1:09 AM David Gebler wrote: > > On Fri, Sep 8, 2023 at 2: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, > > ) {} > > } > > > > These as the most basic examples of what you're proposing are barely > different expressions in length, let alone anything else. I wouldn't say > the first example is particularly more helpful, more readable, more concise > or conceptually more expressive than the second. The rest of your examples > are similarly either very minor savings of a few characters shaved off here > and there, or just as verbose as instantiating a class with a constructor > anyway. > > I'm not convinced by the rationale that this would be a new feature > worthwhile for improved expression or concision. I can see a potential > benefit in these "structs" (not sure that's the term//keyword I'd choose, > given it has different meanings in other languages) though, as a kind of > template for properly structured arrays, with a built-in ability to cast > them to arrays or treat them as arrays/iterables. This would potentially > help give some of the power we're missing by not having generics. So it > wouldn't just be equivalent to a shorthand for a readonly class with a > constructor, but one which also satisfied a couple of interfaces with the > implementation automatically provided. > > That's my initial reaction/two cents. > > -Dave Indeed, When I first saw this, I saw them as typed-arrays, and it would be great if they were treated as such. Essentially, type-check, then stored in a regular array and as far as the engine is concerned, that's what they are (meaning they could be used when a library expects an array, or gradually added to legacy code that passes around opaque arrays). This could add a tremendous amount of expressibility to PHP. This would mean a struct with the same properties and values are equal. It'd be even awesome if you could cast between structs (and to arrays), as long as the struct/array being casted from contained all the right properties/values. For example: $myStruct1 = (MyStruct1) $myStruct2; // myStruct2 could even be an array, or another struct is the same as: $myStruct1 = new MyStruct1(...$myStruct2); except ignoring extra properties/values. Maybe the casting could even "hide" the extra properties in a private variable so that if it is casted to an array, or serialized as json, or casted to a different struct, the original data shows up. As far as being able to increase the expression of regular 'ole PHP, it would allow libraries to get rid of opaque arrays with hidden options (looking at you Guzzle), and essentially not change but a few lines of code, while making it easy for users to correctly use the library. Anyway, just thinking out loud. I have no idea if the original author has an intent for any of this, but it could be awesome. Robert Landers Software Engineer Utrecht NL -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] RFC Proposal: Readonly Structs in PHP
On Fri, Sep 8, 2023 at 2: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, > ) {} > } > These as the most basic examples of what you're proposing are barely different expressions in length, let alone anything else. I wouldn't say the first example is particularly more helpful, more readable, more concise or conceptually more expressive than the second. The rest of your examples are similarly either very minor savings of a few characters shaved off here and there, or just as verbose as instantiating a class with a constructor anyway. I'm not convinced by the rationale that this would be a new feature worthwhile for improved expression or concision. I can see a potential benefit in these "structs" (not sure that's the term//keyword I'd choose, given it has different meanings in other languages) though, as a kind of template for properly structured arrays, with a built-in ability to cast them to arrays or treat them as arrays/iterables. This would potentially help give some of the power we're missing by not having generics. So it wouldn't just be equivalent to a shorthand for a readonly class with a constructor, but one which also satisfied a couple of interfaces with the implementation automatically provided. That's my initial reaction/two cents. -Dave
Re: [PHP-DEV] RFC Proposal: Readonly Structs in PHP
On Fri, 8 Sept 2023 at 14:12, 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 > > I'm all data only for structures, but I really dont think they should be readonly. This type of modifier should be down to the developer to decide. If a developer only needs a data struct, they can just `struct {}` but if they need a readonly struct, they should specify the struct as `readonly struct {}` Structs can have many uses, you will eliminate 99% of them by forcing structs to be readonly. No other languages force this on the developer, PHP shouldn't either. This type of limitation would make structs DOA for most developers.
Re: [PHP-DEV] RFC Proposal: Readonly Structs in PHP
Hi internals! I think it can be useful for structured data obtained from decoding JSONs or from a relational database. However, maybe there is an even better idea, which combines the best of two worlds: the world of your structs RFC, and native PHP arrays - something like "array shapes". For instance, taking the syntax from your proposed RFC (but perhaps the keyword changed to `shape`, or perhaps `array class` to reuse keywords - let's not bikeshed here) to define a shape, and adding a function like `array_shape_coerce($array, $shapeType)` which internally marks an array to be of a defined shape if it matches its definition (throws an exception otherwise, or perhaps returns true/false value or an enum for success/failure) and allows it to be passed where a certain shape type is expected. I think this could be a better approach than pure structs because it leaves all array-based PHP machinery available to such "structs", like `array_map()`, `array_filter()` etc. There is an open question of whether array coerced to shapes can be modified, and if yes, how to react to modifications. Perhaps the easiest solution is to have another function along the lines `array_shape_seal($array, $shapeType)` which not only marks array to be of shape (if the given array matches given shape), but also permits only such modifications which keep the array to be of this shape. And if the regular `array_shape_coerce` is used, then any modifications are permitted, but the array "loses" its shape. Regards, Illia / someniatko
Re: [PHP-DEV] RFC Proposal: Readonly Structs in PHP
I really like the idea of making structs opaque in that sense, definitely going to put it to vote in the RFC. I agree with the decision to exclude methods from structs, as they are intended to be pure data types and If methods are required, classes can be used instead. I guess based on the response from this list i might not need to put it up to a vote. On 2023-09-08 8:58 a.m., Matthew Weier O'Phinney wrote: On Fri, Sep 8, 2023, 9:15 AM Lanre Waju wrote: 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. At that point, a struct would be no different from a readonly class with public properties, meaning we'd have two ways to accomplish the same thing. Considering that a readonly class can already implement interfaces such as JsonSerializable, Iterator, and ArrayAccess, they already solve the bulk of the issues that have been raised in this thread. The main thing of interest that I could see from your proposal was the ability to nest a struct in another struct or a class definition, as that could provide some interesting type safety without the need to declare new classes. This could be even more interesting if it allowed _any_ struct that fulfilled the same definitions: class Post { public function __construct( public readonly struct $author { string $name; UriInterface $uri; UriInterface $avatarUri; }, public readonly string $title, public readonly string $content, public readonly DateTimeInterface $publicationDate, ) { } // ... } struct User { string $name; UriInterface $uri; UriInterface $avatarUri; string $email; } $post = new Post(new User(...), ...); The idea here is that User fulfills the $author struct definition in the Post class; it just has _additional_ properties. If the proposal would allow that, this could be pretty powerful. I would personally stay away from solving the conversion to and from arrays and allowing methods. If users need those, they can either use de/serialization libraries or readonly classes, respectively. Not including them in the initial proposal keeps it more targeted, and demonstrates a language feature that does not currently exist. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] RFC Proposal: Readonly Structs in PHP
On Fri, Sep 8, 2023, 9:15 AM Lanre Waju wrote: > 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. > At that point, a struct would be no different from a readonly class with public properties, meaning we'd have two ways to accomplish the same thing. Considering that a readonly class can already implement interfaces such as JsonSerializable, Iterator, and ArrayAccess, they already solve the bulk of the issues that have been raised in this thread. The main thing of interest that I could see from your proposal was the ability to nest a struct in another struct or a class definition, as that could provide some interesting type safety without the need to declare new classes. This could be even more interesting if it allowed _any_ struct that fulfilled the same definitions: class Post { public function __construct( public readonly struct $author { string $name; UriInterface $uri; UriInterface $avatarUri; }, public readonly string $title, public readonly string $content, public readonly DateTimeInterface $publicationDate, ) { } // ... } struct User { string $name; UriInterface $uri; UriInterface $avatarUri; string $email; } $post = new Post(new User(...), ...); The idea here is that User fulfills the $author struct definition in the Post class; it just has _additional_ properties. If the proposal would allow that, this could be pretty powerful. I would personally stay away from solving the conversion to and from arrays and allowing methods. If users need those, they can either use de/serialization libraries or readonly classes, respectively. Not including them in the initial proposal keeps it more targeted, and demonstrates a language feature that does not currently exist.
Re: [PHP-DEV] RFC Proposal: Readonly Structs in PHP
2023-09-08 15:12 GMT+02:00, Lanre Waju : > 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 Aren't structs value objects in C#? Might be some semantic confusion there, in choice of words. https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/struct "Structure types have value semantics". Java uses the "record" keyword. Worth taking a look at, maybe? Olle -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] RFC Proposal: Readonly Structs in PHP
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
Re: [PHP-DEV] RFC Proposal: Readonly Structs in PHP
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? -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
[PHP-DEV] RFC Proposal: Readonly Structs in PHP
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