On Fri, Mar 15, 2019 at 10:54 AM Nikita Popov <nikita....@gmail.com> wrote:
> On Fri, Mar 15, 2019 at 4:49 AM Kenneth Ellis McCall <xell...@gmail.com> > wrote: > > > Hey all, > > > > I'm looking to get feedback on a RFC I want to propose. > > > > PHP RFC: Addition of the 'struct' data type. > > > > Introduction: > > PHP has many data types, but does not offer something that is the > > equivalent to the C struct data type. > > > > The purpose of this RFC is to propose a data type of 'struct', which > > would be a strictly typed, immutable data structure that resembles a mix > > of a class and an array. > > > > Pros: > > Provides a data type which would immutable and self-validating by > > mandatory type hinting. > > > > Cons: > > ? > > > > Possible future considerations: > > Advanced Type Validators. > > > > Use cases: > > Configurations, DTOs, anything that needs a strict schema. > > > > Proposed usage / syntax: > > struct MyStuct > > { > > boolean|bool 'prop01'; > > integer|int 'prop02'; > > double 'prop03'; > > string 'prop04'; > > array 'prop05'; > > object 'prop06'; > > resource 'prop07'; > > callable 'prop08'; > > iterable 'prop09'; > > Acme\MyClass 'prop10'; > > Acme\ConfStruct 'prop11'; > > array Acme\AnotherStruct 'prop12'; > > ?boolean|bool 'prop13'; > > ?integer|int 'prop14'; > > ?double 'prop15'; > > ?string 'prop16'; > > ?array 'prop17'; > > ?object 'prop18'; > > ?resource 'prop19'; > > ?callable 'prop20'; > > ?iterable 'prop21'; > > ?Acme\MyClass 'prop22'; > > ?Acme\ConfStruct 'prop23'; > > ?array Acme\AnotherStruct 'prop24'; > > } > > OR? > > > > struct MyStuct > > { > > 'prop01': boolean|bool; > > 'prop02': integer|int; > > 'prop03': float; > > 'prop04': string; > > 'prop05': array; > > 'prop06': object; > > 'prop07': resource; > > 'prop08': callable; > > 'prop09': iterable; > > 'prop10': Acme\MyClass; > > 'prop11': Acme\ConfStruct; > > 'prop12': array Acme\AnotherStruct; > > 'prop13': ?boolean|bool; > > 'prop14': ?integer|int; > > 'prop15': ?float; > > 'prop16': ?string; > > 'prop17': ?array; > > 'prop18': ?object; > > 'prop19': ?resource; > > 'prop20': ?callable; > > 'prop21': ?iterable; > > 'prop22': ?Acme\MyClass; > > 'prop23': ?Acme\ConfStruct; > > 'prop24': ?array Acme\AnotherStruct; > > } > > > > struct Acme\ConfStruct > > { > > string 'host'; > > ?int 'port'; > > } > > > > struct Acme\AnotherStruct > > { > > string 'firstName'; > > string 'lastName'; > > ?integer 'age'; > > } > > > > Acme\ConfStruct $a = { > > 'host' => '127.0.0.1', > > 'port' => 8088 > > } > > > > Acme\MyStruct $myStruct = { > > 'prop01' => true, > > 'prop02' => 1, > > 'prop03' => 1.01, > > 'prop04' => 'Hello', > > 'prop05' => ['a', 'b', 'c'], > > 'prop06' => new stdClass(), > > 'prop07' => fopen('xyz.txt', 'wb'), > > 'prop08' => function() { > > return 1 + 1; > > }, > > 'prop09' => [ > > [1, 2, 3], > > [4, 5, 6], > > [7, 8, 9] > > ], > > 'prop10' => new Acme\MyClass, > > 'prop11' => $a, > > 'prop12' => [ > > Acme\AnotherStruct [ > > 'firstName' => 'Bob', > > 'lastName' => 'Walker' > > ], > > Acme\AnotherStruct [ > > 'firstName' => 'Little', > > 'lastName' => 'Johnny', > > 'age' => 5 > > ], > > ], > > 'prop13' => null, > > 'prop14' => null, > > 'prop15' => null, > > 'prop16' => null, > > 'prop17' => null, > > 'prop18' => null, > > 'prop19' => null, > > 'prop20' => null, > > 'prop21' => null, > > 'prop22' => null, > > 'prop23' => null, > > 'prop24' => null > > }; > > > > $x = new Some\Other\Class($myStruct); > > > > echo $myStruct['prop02']; > > OR? > > > > echo $myStruct->prop02; > > Warning / Errors / Exceptions: > > Acme\MyStruct $a = { > > 'prop01' => 5, > > ... > > } > > // Should: throw new TypeError("'prop01' should be set as a boolean > > type, integer type was attempted.") > > > > echo $a['xyz']; // or echo $a->xyz (which ever is the preferred syntax > > after comments). > > // Should: trigger_error("<b>Notice</b>: Undefined property: > > Acme\MyStruct::xyz"); > > > > > > https://github.com/ellisgl/PHP-RFC-Struct-Data-Type > > > > I think this a worthwhile topic to pursue -- immutable value objects are > certainly seeing increased use, and it would be great to increase support > for them. What I mainly wonder in regard to this RFC is: Do we really need > a new struct type with a new syntax, or can we get this as a combination of > multiple features for existing class types? In particular, I think your > struct type proposal can be split into these three parts: > I guess needing a new datatype depends if the struct should be passed by value instead of by reference. > 1. Property types. As of PHP 7.4 these are already available, yay! Your > example also make use of some types (e.g. union types) that are not > currently supported, but likely will be in the future. > > 2. Readonly properties: Without requiring an entire object to be immutable, > we can add support for readonly properties. This may be either a standalone > feature, or part of / based on a more general property accessors proposal. > Read Only types would be a good idea, DOM already uses readonly as a pseudo keyword to describe their custom property handlers. A lot of internal classes could benefit from exposing this explicitly. > 3. Object construction syntax: The last part is a syntax to construct > objects without a constructor, using a syntax where property names are > specified, and which ensures that all non-default properties are > initialized. > > Your example > > // declaration > struct AnotherStruct > { > string 'firstName'; > string 'lastName'; > ?int 'age'; > } > // initialization > AnotherStruct [ > 'firstName' => 'Little', > 'lastName' => 'Johnny', > 'age' => 5 > ] > > could then become something like > > // declaration > class AnotherStruct { > readonly string $firstName; > readonly string $lastName; > readonly ?int $age = null; > } > // initialization (syntax up to bikeshedding) > new AnotherStruct { > $firstName => 'Little', > $lastName => 'Johnny', > $age => 5, > } > > I'd generally prefer a solution that is based on the existing class system. > Especially as it means that other use-cases can also benefit: Sometimes you > might only want some of your properties to be readonly, etc. > > Nikita >