Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:104742 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 1391 invoked from network); 15 Mar 2019 16:28:41 -0000 Received: from unknown (HELO mail-lf1-f65.google.com) (209.85.167.65) by pb1.pair.com with SMTP; 15 Mar 2019 16:28:41 -0000 Received: by mail-lf1-f65.google.com with SMTP id a132so5402523lfa.13 for ; Fri, 15 Mar 2019 06:19:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=beberlei-de.20150623.gappssmtp.com; s=20150623; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=en3RUVOsbmhny1SaK6OwZzSiulXhMzFNR//xeS6LmsI=; b=goqcxI6uCnQJmCbg7o5LI04SnPmnn6KOUztUDGahylVM4luZavwPNNDzq+8FUQ8Cwp 7gJwYpR+v8adW0eVgxep2KmPFRBjFCce/rl4c6y1Dnoy/juEj+aaYM20Kqqi6YxhnMZ3 9RMsOAp1HskbW2GacNoZzJpPG2AK72ddDxlLFZOJ6u3Rn4Avfrj5czXRvQwPVWlkz+39 KGecoM0Bummxu+w/yoocC0UQ0T0RZVeRcDhMAgnyfuR1I0OrUdSwTDdPK2uWjprRVg87 ptR+z/ZYuxIv1XnIGJeb/hWpnjvvRlPvP6+6s/GtYR2QGiZP8Ah10Xx3JRe9s5CwnIqs 4QGw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=en3RUVOsbmhny1SaK6OwZzSiulXhMzFNR//xeS6LmsI=; b=E+nRL1PRBBsfC1LfSla5wQScvQ5heTDYmxYeCrTXxLaVYgi2aYG6K1W8wwMbRE7/6b IOOMI7VlwRi1AmjdHs+oKCA9X5xFZFjGu6O/H64XJrK3PEZdA9+EOQ9pAavta5ACT9Zw TmmH44X6rc+zXhPWVMfZIW5o8Eek/mp5LnlLOjYGlPuajw+1wf/aKgCoO+sNi95j8clU /4xtaYi7Ggk3AlpFnOL4ZbvwfbsCY81CbI7suCbC4CrsAUSZF7J7K0OzI0zQ7Yx8odCu Ehltr0XKOGkq8/ftqPijpCqetAKIGHhqqoz4GMenlahy7b4EefaeAspYESTgMTXRPIPn s2kg== X-Gm-Message-State: APjAAAVL3hWmmqvDLHEjgFL09/4TeglGsqagPggyxcPFjJiZ7vue+CO/ Sc0USUCb86gjjqQvN3eWYzxW57B+kajxq87HZTRjfg== X-Google-Smtp-Source: APXvYqy4cZ5LDxYzFmSZlYBEgQmEYnMDQedm8wrugCz1px5yTZ3yDQY4jqQab7Gf1tSY4nqfS5tDXTnG0t0icnRqyhs= X-Received: by 2002:ac2:5396:: with SMTP id g22mr2130092lfh.120.1552655959304; Fri, 15 Mar 2019 06:19:19 -0700 (PDT) MIME-Version: 1.0 References: <5c8b20b5.1c69fb81.d9f23.2cacSMTPIN_ADDED_MISSING@mx.google.com> In-Reply-To: Date: Fri, 15 Mar 2019 14:19:07 +0100 Message-ID: To: Nikita Popov Cc: Kenneth Ellis McCall , PHP internals Content-Type: multipart/alternative; boundary="000000000000e9c4a8058421e2da" Subject: Re: [PHP-DEV] [Proposal] Struct Data Types From: kontakt@beberlei.de (Benjamin Eberlei) --000000000000e9c4a8058421e2da Content-Type: text/plain; charset="UTF-8" On Fri, Mar 15, 2019 at 10:54 AM Nikita Popov wrote: > On Fri, Mar 15, 2019 at 4:49 AM Kenneth Ellis McCall > 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("Notice: 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 > --000000000000e9c4a8058421e2da--