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: 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. 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