Re: [PHP-DEV] [Early Feedback] Pattern matching
public string $lastName is @RE(GP::LENGTH_PTRN) & @RE(GP::FORBIDDEN_CHARS_PTRN) & @RE(GP::FORBIDDEN_WORDS_PTRN); // these are hard to maintain public string $firstName is /COMPLEX_NAME_PTRN/; public string $lastName is @RE(GP::COMPLEX_NAME_PTRN); } ``` 7. I noticed that ```as``` is tightly coupled with exception. Can we suppress this exception with ```??```? ``` // it is weird to see this statement (as show in the proposal) $value = $foo as Foo {$username, $password}; // these statements are more make sense $foo as Foo {$username, $password}; $foo is Foo {$username, $password} ?: throw new Exception(); // if it can be suppressed, "as" is more valuable than what people think. $newRect = $rect as Rectangle{width: <=10, height: <=5} ?? new Rectangle(width: 10, height: 5); ``` 8. Is there any type checking for object property pattern? ``` class Circle { public int $radius; } // this statement will always fails unless there is type checking $circle is Circle{radius: "10"}; ``` ~ 4 of the 8 points I discussed above are related to range pattern and regex pattern. Both are used daily. From my point of view, literal pattern is no more special than range pattern and regex pattern. IMO, both should be placed in Core patterns section, not in Possible patterns section. Regards, Hendra Gunawan.
Re: [PHP-DEV] [Early Feedback] Pattern matching
p; @RE(GP::FORBIDDEN_WORDS_PTRN); // these are hard to maintain public string $firstName is @RE(GP::COMPLEX_NAME_PTRN); public string $lastName is @RE(GP::COMPLEX_NAME_PTRN); } 7. I noticed that ```as``` is tightly coupled with exception. Can we suppress this exception with ```??```? ``` // it is weird to see this statement (as show in the proposal) $value = $foo as Foo {$username, $password}; // these statements are more make sense $foo as Foo {$username, $password}; $foo is Foo {$username, $password} ?: throw new Exception(); // if it can be suppressed, "as" is more valuable than what people think. $newRect = $rect as Rectangle{width: <=10, height: <=5} ?? new Rectangle(width: 10, height: 5); ``` 8. Is there any type checking for object property pattern? ``` class Circle { public int $radius; } // this statement will always fails unless there is type checking $circle is Circle{radius: "10"}; ``` ~ 4 of the 8 points I discussed above are related to range pattern and regex pattern. Both are used daily. From my point of view, literal pattern is no more special than range pattern and regex pattern. IMO, both should be placed in Core patterns section, not in Possible patterns section. Regards, Hendra Gunawan.
Re: [PHP-DEV] [RFC] Property hooks, nee accessors
> Secondary votes are generally discouraged. I can see the argument for > wanting a short-short version of set, given how common the validation use > case is, but => is almost universally the "evaluates to" symbol, so using > that for a set operation rather than get just feels weirdly inconsistent. If > there were a set-only shorthand, it should be something else. > > That said, the ideal for validation would probably be guard clauses, like > this, but that would be a completely different RFC for another time. > ``` > function foo(string $name where strlen($name) < 10) { ... } > > class Foo { > public function __construct( > public string $name where strlen($name) < 10; > ) {} > } > ``` ```guard``` seems a subset feature of ```hook```, although you want to expand its use case in parameter. Property and parameter are variable. If ```guard``` can be implemented in both case as you write above, theoretically ```hook``` can be either. I will choose ```hook``` rather than ```guard``` to anticipate future expansion. Isn't it better to choose one broad concept than many? I found a contradiction here. Previously you said that: > ... the problem with omitting the {} is that it creates yet another syntax > variant. That makes it harder for the parser, for static analyzers, for > user-space parsing tools like php-parser, etc. That's more work for everyone > for fairly little gain. And here, you introduce a syntax variant. Is it really significant if we introduce a new ```where``` keyword ```compared to the already used ```get``` keyword? I will clarify here in case there is misunderstanding: * If we have more than one hook per property, then the syntax will be the same as proposed by RFC. * If we have only one hook per property, than the syntax are: ``` public function __construct( public string $prop1 get => strtoupper($this->_prop1), ){} public function __construct( public string $prop2 set => $field = strtolower($value), ){} public function __construct( public string $prop3 get { $temp = strtoupper($this->_prop1); return substr($temp, 0, 10) . '...'; }, ){} public function __construct( public string $prop4 set { $temp = strtolower($value); $field = substr($temp, 0, 10); }, ){} ``` Note: Please ignore any error. The ending comma is actually part of the parameter list, not a hook. So it becomes optional if the param is only one or it is the last param. All the examples are constructor property promotion, because that is my only concern. Because the space is limited, the more consistent the code, the better. If I have to write hooks outside CPP, I don't mind using the other syntax. There's plenty of room to fill, and consistency is tolerable. Should we postpone the implementation of the shortest version? Hopefully we have enough time to decide which one will be implemented next. > > ... Ilija also noted to me off-list that you could also have a set hook that > throws an exception rather than just being null, which would also work to > prevent writes. Such a coincidence. I was going to revise my code: ``` // cache once and freeze, // and without additional hidden property // in case asymmetric visibility in not implemented yet public string $prop1 { get => $field ??= $this->heavyTask($this->propx, $prop->y); set => throw new Exception("prop1 is read only"); } ``` > I think an unset hook is a fine addition in the future. The way the code is > implemented it should be straightforward to add. However, it feels like > scope creep to include it right now, especially when there are workarounds > available. If there's a clear consensus from voters to include it, though, > we can consider that. (Meaning, anyone that would favor including an unset > hook now, speak up or we'll assume it's better to stick with just get/set for > now.) +1 for including ```unset``` as part of this RFC. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Property hooks, nee accessors
> (Also, when replying, please please remove duplicate names from the to/cc > line. I just got double copies of everything in this thread this morning. > I'm on the list, I don't need to be CCed.) Sorry about that. Not my habit before. > For the second, the problem with omitting the {} is that it creates yet > another syntax variant. That makes it harder for the parser, for static > analyzers, for user-space parsing tools like php-parser, etc. That's more > work for everyone for fairly little gain. Sad to read that. Making one of them as the shortest shorthand feels like a picky decision. Some people agree with ```get```. Some people will argue that ```set``` deserves more than ```get```. Personally, I choose ```set``` to be the shortest shorthand as it is more relevant with constructor property promotion and value object. Do we need a 2nd vote for this one? > Removing the {} entirely from all forms makes it harder to denote where the > list of hooks begins and ends. They would probably have to be > comma-separated, like this: > > public string $foo > get { return $this->bar; }, > set { $this->bar = $value; }; > > Which I'd argue is harder to read anyway, because you have to be careful of > the very small , and ; marks. The {} is just easier for humans to parse as > well as the machine. Looks like it's not more simple compared to the other one. > What we really would need here is asymmetric visibility. No set hook, but > make the property private(set) so that trying to write to it gives an error, > as it should. So if asymmetric visibility is implemented, will my code be this simple? ``` // cache once and freeze, // and without additional hidden property public private(set) string $prop1 { get => $field ??= $this->heavyTask($this->propx, $prop->y); } ``` > For cache clearing, the best way to do that is probably with an unset hook. > That's been omitted from the RFC for now for simplicity, but that sounds like > it would be an argument to introduce it later. I was going to write about this one. IMO, why do we need to provide additional hidden properties, when we are able to store the cache directly into it? Obviously we need a ```unset``` hook. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Property hooks, nee accessors
> If there is no forward compatibility consideration, can we simplify > interface definition to this one? > ``` > interface IFace > { > public string $readable; > public string $writeable; > public string $both; > } > ``` After carefully reading the proposal again, I think I know the answer for my own question. Short answer: no, we still need ```{ get; }``` to enforce the implemented class. There are two different things here: 1. enforcing the implemented class 2. enforcing the caller site If there are only ordinary properties, then ```{ get; }``` is truly useless at the moment. On the other hand, virtual properties need rules to be enforced, since there is no default hook given to it. Since PHP lacks method definition enforcement at the caller site, I assume that property would suffer the same. Since we don't know what type of property is in the caller site, static analysis tools can benefit from ```{ get; }``` to produce a warning that we should not assign value to the property. A more complex check should be performed to the implemented class because the property type can be determined directly (if i am not wrong). ``` interface IFace { public string $readable1 { get; } public string $readable2 { get; } } class CX implements IFace { private string $_propx; public string $readable1; public string $readable2 { get => $this->_propx; set => $this->_propx = $value; } public function consumeIt(IFace $par) { // these statements should trigger warning by SA tools $par->readable1 = "hello"; $par->readable2 = "world"; // OK $this->readable1 = "hello"; // this statement should trigger error by SA tools $this->readable2 = "hello"; } } ``` -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Property hooks, nee accessors
> ```php > class User { > private string $first; > private string $last; > public string $fullName { > get => $this->first . ' ' . $this->last; > set => [$this->first, $this->last] = explode(' ', $value, 2); > } > > public function __construct($this->fullName) {} > } > ``` Not entirely true, you created redundancy code for ```$fullName```. This is why we created constructor property promotion: to eliminate redundancy. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Property hooks, nee accessors
On Tue, May 9, 2023 at 4:38 AM Larry Garfield wrote: > > Ilija Tovilo and I would like to offer another RFC for your consideration. > It's been a while in coming, and we've evolved the design quite a bit just in > the last week so if you saw an earlier draft of it in the past few months, I > would encourage you to read it over again to make sure we're all on the same > page. I'm actually pretty happy with where it ended up, even if it's not the > original design. This approach eliminates several hard-to-implement edge > cases while still providing a lot of functionality in one package. > > https://wiki.php.net/rfc/property-hooks > > -- > Larry Garfield > la...@garfieldtech.com Hi Larry Can the engine detect these logical errors? ``` public string $fullName = "hendra gunawan" => $this->first . " " . $this->last; // or with my proposal: public string $fullName = "hendra gunawan" get => $this->first . " " . $this->last; // or even this one: public string $fullName = "hendra gunawan" { get => $this->first . " " . $this->last; set => [$this->first, $this->last] = explode(" ", $value); ``` Explanation: There is no automatic backing store value created to store the default value. Terima Kasih. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Property hooks, nee accessors
On Tue, May 9, 2023 at 4:38 AM Larry Garfield wrote: > > Ilija Tovilo and I would like to offer another RFC for your consideration. > It's been a while in coming, and we've evolved the design quite a bit just in > the last week so if you saw an earlier draft of it in the past few months, I > would encourage you to read it over again to make sure we're all on the same > page. I'm actually pretty happy with where it ended up, even if it's not the > original design. This approach eliminates several hard-to-implement edge > cases while still providing a lot of functionality in one package. > > https://wiki.php.net/rfc/property-hooks > > -- > Larry Garfield > la...@garfieldtech.com Hi, Larry ``` interface IFace { public string $readable { get; } public string $writeable { set; } public string $both { get; set; } } ``` How important is ```{ get; }``` statement (and friends) in the interface? Since PHP does not enforce method definition existence in caller site, this code is valid (at least at compile time): ``` interface IA { // ... } interface IB { public function doIt(IA $par1); } class CA1 implements IA { // makeIt is not part of IA public function makeIt() { echo " makeIt() is called"; } } class CA2 implements IA {} class CB implements IB { public function doit(IA $par1) { // makeIt is not enforced to be invalid $par1->makeit(); } } $a1 = new CA1; $a2 = new CA2; $b = new CB; $b->doIt($a1); // valid $b->doIt($a2); // invalid at runtime ``` IMO, ```{ get; }``` (and friends) only useful if there are: * definition existence enforcement or implemented asymmetric visibility * AND no default hook implementation provided. I assume that ```{ get; }``` do exist in the property accessors proposal because there is no default hook implementation. Whether there is already implemented property definition existence enforcement or not, i don't know. If yes, then all things are in the right place. If not, it feels like a half baked feature, just like the method was: the error will pop up at runtime. The only positive value is ```{ get; }``` can still be consumed by static analysis tools. ``` class CX { public function consumeIt(IFace $par) { // this statement should trigger error // produced by engine or SA tools $par->readable = "hello"; } } ``` Things will be different with property hooks. Without definition existence enforcement nor implemented asymmetric visibility, static analysis tools will give misconception about unlisted hooks if there is error/warning message. ``` class CX { public function consumeIt(IFace $par) { // default hook is provided by engine // any message is not relevant for this valid statement $par->readable = "hello"; } } ``` If there is no forward compatibility consideration, can we simplify interface definition to this one? ``` interface IFace { public string $readable; public string $writeable; public string $both; } ``` Thanks in advance. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Property hooks, nee accessors
On Tue, May 9, 2023 at 4:38 AM Larry Garfield wrote: > > Ilija Tovilo and I would like to offer another RFC for your consideration. > It's been a while in coming, and we've evolved the design quite a bit just in > the last week so if you saw an earlier draft of it in the past few months, I > would encourage you to read it over again to make sure we're all on the same > page. I'm actually pretty happy with where it ended up, even if it's not the > original design. This approach eliminates several hard-to-implement edge > cases while still providing a lot of functionality in one package. > > https://wiki.php.net/rfc/property-hooks > > -- > Larry Garfield > la...@garfieldtech.com > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > Hi Larry. Suppose that I just want to cache once and freeze, and I don't want to create additional hidden property. Please make a judgement on the validity of this syntax: ``` public string $prop1 { get => $field ??= $this->heavyTask($this->propx, $prop->y); set => null; } ``` Explanation: * Since the ```get``` hook uses ```$field```, the engine will create a backing store value with name ```$prop1```, and will be filled at the first call only. The later call will use the already stored value. * Since no new value is assigned to ```$field``` in the ```set``` hook, the value stored in ```$prop1``` is still the same as before. * Since any return statement will be discharged in ```set``` hook, the assignment chaining is safe to use and the value which is transferred is alway the rightmost value (not the value returned by the ```set``` hook). ``` $varx = $obj->prop1 = "hello"; // $varx value is "hello", and $obj->prop1 value is unchanged ``` But, this statement below is NOT ALWAYS correct for "cache once and freeze": ``` public string $prop1 { set => $field ??= $this->heavyTask($this->propx, $prop->y); } ``` Explanation: * Since default ```get``` hook can be called before ```set``` hook, backing store value with name ```$prop1``` will still be empty. * Otherwise, I have to duplicate the body of the ```set``` hook into ```get``` hook to prevent an emptiness backing store. Please give a comment. Thanks. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Property hooks, nee accessors
On Tue, May 9, 2023 at 4:38 AM Larry Garfield wrote: > > Ilija Tovilo and I would like to offer another RFC for your consideration. > It's been a while in coming, and we've evolved the design quite a bit just in > the last week so if you saw an earlier draft of it in the past few months, I > would encourage you to read it over again to make sure we're all on the same > page. I'm actually pretty happy with where it ended up, even if it's not the > original design. This approach eliminates several hard-to-implement edge > cases while still providing a lot of functionality in one package. > > https://wiki.php.net/rfc/property-hooks > > -- > Larry Garfield > la...@garfieldtech.com > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > Hi Larry. ``` public string $fullName => $this->first . " " . $this->last; ``` 1. Suppose that I forgot to declare ```$this->first```. Based on the "deprecate dynamic properties" proposal, will I get an error/warning? 2. The shorthand notations supported (the shortest one) creates impaired syntax, and not pretty to look at for constructor property promotion. ``` public function __construct( public string $prop1 => strtoupper($this->_prop1), public string $prop2 {set => $field = strtolower($value);}, ){} ``` My suggestion is: use get/set keyword immediately after property name/default value rather than "=>" or "{" without losing multiline statements. ``` public function __construct( public string $prop1 get => strtoupper($this->_prop1), public string $prop2 set => $field = strtolower($value), public string $prop3 get { $temp = strtoupper($this->_prop1); return substr($temp, 0, 10) . '...'; } public string $prop4 set { $temp = strtolower($value); $field = substr($temp, 0, 10); } ){} ``` This syntax is aligned with a single statement if/for/foreach. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] RFC [Discussion] array_column results grouping
> > And if you want to map, reduce, or filter without grouping? Then you can't > really use this function. And as noted, the order in which you apply those > operations may matter, and no order is necessarily more obvious or beneficial You can modify it slightly if you eager to: array_group( ... null|int|string|array $index_key, ... ): array If You provide `null`, it will operate on a bare array, no grouping involved. As a consequence, users have to provide `reducer` or `mapper`. So virtually, You design `array_group` to swallow `array_reduce` and `array_map`. Though, `array_map` is actually a different API compared to `array_reduce` or `array_group`. Interestingly, you will get a better quality of code if you include `reducer: ` and `mapper: ` consistently, whatever array level you work with. // `array_reduce` and `array_map` alternative array_group($array, null, reducer: $fnReducer); array_group($array, null, mapper: $fnMapper); array_group($array, "level1", reducer: $fnReducer); array_group($array, "level1", mapper: $fnMapper); array_group($array, ["level1", "level2"], reducer: $fnReducer); array_group($array, ["level1", "level2"], mapper: $fnMapper); I hope there is no bias between the proposed name (`array_group`) and its functionality. > > Either of these approaches would be superior to cramming more functionality > into a single-purpose function to turn it into a single-function swiss army > knife: Not a swiss army knife, just a penknife. AS i wrote before, it is just a shortcut. If you really mind about that, we can cancel `filter` and `sorter`, leaving only `reducer` and `mapper`. Thought, we can filtering and sorting before `array_group`, but i don't know whether it is as accurate as embedding them into `array_group` or not. If not, we have to iterate manually, do filtering and/or sorting, then reducing/mapping. > > https://wiki.php.net/rfc/comprehensions > https://wiki.php.net/rfc/pipe-operator-v2 Of course these are wonderful proposals. Yes, they are superior. To be honest, I really hope they are landed in PHP. I already imagine what part of my code will be replaced by them. Since I am not a C coder and totally blind about the engine, I don't have my own opinion whether we lost good things or not, by not adding them to PHP. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] RFC [Discussion] array_column results grouping
> > Better map/filter/reduce primitives in PHP would be dandy, but they have > nothing to do with array grouping. They're a separate operation that should > be composed with grouping. Packing them all into a single function sounds > like a terrible idea. > > If we wanted that... that's called list comprehensions, which I would > support and even tried to rally support for a few years ago, but got met > with a big shrug. :-) We can imagine that `array_group` is just a shortcut to: do grouping, and then do reducing. (common to me) OR: do filtering, then do grouping, and the last do reducing. (less common to me) OR: do sorting, then do filtering, then do grouping, and the last do reducing. Best Regards Hendra Gunawan. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] RFC [Discussion] array_column results grouping
> > Better map/filter/reduce primitives in PHP would be dandy, but they have > nothing to do with array grouping. They're a separate operation that should > be composed with grouping. Packing them all into a single function sounds > like a terrible idea. > > If we wanted that... that's called list comprehensions, which I would > support and even tried to rally support for a few years ago, but got met > with a big shrug. :-) `array_group` is just a simple handy tool which can manipulate a bunch of data without touching SQL, DQL, query builder, or any producer anymore just to align the output to the need. Of course we can code with whatever programming paradigm or style we want, especially if the algorithm is much more complex. Here, i offer you the very basic functionality and without external library. So my coworker does not have to dig into that library, or ask me. The original proposal is to offer grouping, and may be to avoid `foreach`. I think if the only purpose is to group an array, it is halfly baked function- ality. Previously, I had shown you that `foreach` is not too bad to use. Otherwise, I will suggest to the author don't bother with new function, you're wasting your time. With that original proposed functionality, We have to use an additional `foreach` or function call even though it is a basic operation. Moreover, the original purpose is preserved, if we do not give any optional params. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] RFC [Discussion] array_column results grouping
Revision to my recommendation are: 1. signature: array_group( array|object $array, int|string|array $index_key, callable $reducer = null, callable $mapper = null, callable $filter = null, callable $sorter = null, ): array 2. `sorter` should be executed before `filter`, because as far as I can think, there is no way to do this by yourself. So the sequence should be: `sorter` > `filter` > `mapper`|`reducer` > > Better map/filter/reduce primitives in PHP would be dandy, but they have > nothing to do with array grouping. They're a separate operation that should > be composed with grouping. Packing them all into a single function sounds > like a terrible idea. > > If we wanted that... that's called list comprehensions, which I would > support and even tried to rally support for a few years ago, but got met > with a big shrug. :-) Suppose that my boss order me to provide statistical data of students. He wants a brief data companied with zoom button on each row. This buttons displays all fields in which brief data has, plus another zoom button on it's own row. And so on to some level. Additionally He wants the data not just by area division, but also by gender as a whole. // These are reducer $fnAvg = fn() => {/*...*/} $fnQ1 = fn() => {/*...*/} $fnQ2 = fn() => {/*...*/} $fnQ3 = fn() => {/*...*/} $fnLowest = fn() => {/*...*/} $fnHighest = fn() => {/*...*/} $dAvg = array_group($data, "district", $fnAvg); $dQ1 = array_group($data, "district", $fnQ1); $dQ2 = array_group($data, "district", $fnQ2); // ... and 3 others $wAvg = array_group($data, ["district", "ward"], $fnAvg); $wQ1 = array_group($data, ["district", "ward"], $fnQ1); $wQ2 = array_group($data, ["district", "ward"], $fnQ2); // ... and 3 others $cAvg = array_group($data, ["district", "ward", "cluster"], $fnAvg); $cQ1 = array_group($data, ["district", "ward", "cluster"], $fnQ1); $cQ2 = array_group($data, ["district", "ward", "cluster"], $fnQ2); // ... and 3 others $sAvg = array_group($data, "sex", $fnAvg); $sQ1 = array_group($data, "sex", $fnQ1); $sQ2 = array_group($data, "sex", $fnQ2); // ... and 3 others output: $dAvg = [ "district1" => 123, "district2" => 234, ... ]; $dQ1 = [ "district1" => 123, "district2" => 234, ... ]; ... $wAvg = [ "district1" => [ "ward1" => 123, "ward2" => 234, ], "district2" => [ "ward3" => 123, "ward4" => 234, ], ... ]; $wQ1 = [ "district1" => [ "ward1" => 123, "ward2" => 234, ], "district2" => [ "ward3" => 123, "ward4" => 234, ], ... ]; ... $sAvg = [ "female" => 123, "male" => 234, ... ]; $sQ1 = [ "female" => 123, "male" => 234, ... ]; `array_group` is just a simple handy tool which can manipulate a bunch of data without touching SQL, DQL, query builder, or any producer anymore just to align the output to the need. Best Regards Hendra Gunawan. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] RFC [Discussion] array_column results grouping
> > Hello Folks, Thanks a lot for your feedback, as already mentioned in > the RFC and as mentioned by Rowan too a new function is an option. I > think that mostly we will go with the new function option. > I will try to edit the PR to add a new function, does there any > suggestions/naming conventions for the new function? a colleague > suggested being `array_group_by` and Hendra already suggested to be > `array_column_group` which is good too. It would be better if You add another voting item for this one. In my opinion, `column` is less important to be included, and `array_group` is sufficiently descriptive. `reducer` is one of the candidates to be included. Additionally, there are `mapper`, `filter`, and `sorter`. So Obviously we need a new function, rather than modify the old one. To be clear and to make it simpler, all callbacks operate on the deepest subgroup. Signature: reducer(array|object $item, int|string $index, mixed $cumulative): mixed mapper(array|object $item): array|object filter(array|object $item, int|string $index): bool sorter(array|object $item1, array|object $item2): int A note in case you are able to implement them: - `reducer` and `mapper` cannot coexist in a single function call. - `filter` should be executed before `reducer` or `mapper`. - `sorter` should be decided whether it executes before or after `reducer`/ `mapper`: `sorter` is more suitable to execute before `filter`, but more suitable after `mapper`. A note for consumers: - `mapper` is designed to operate on the subgroup item, but it can be operated on the field value of the item. - filtering can be done inside `reducer` or `mapper`, but the number of subgroup members is as it is. With dedicated `filter` supplied, we can decrease the number. - If You want to filter an intermediate group, You can use `unset` or `if-else` $group = array_group($people, ["education", "sex"], FN_REDUCER); foreach ($group as &$eduGroup) { foreach ($eduGroup as &$sexGroup) { unset($sexGroup["male"]); } } Not a perfect solution, but at least your code is reduced. Best Regards Hendra Gunawan. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] RFC [Discussion] array_column results grouping
> > Hello, this is a proposal to upgrade the functionality of > `array_column` to return an indexed array for all of the matched data > instead of a single result. > > the RFC had been created here > https://wiki.php.net/rfc/array_column_results_grouping and the PR is > in here https://github.com/php/php-src/pull/7698. > > However, I am not sure, if we need to add a fourth parameter to the > function to change its behavior or we can add it as a new function, > something like `array_column_group` or any other name. > Hai Hassan. It seems that your proposal is just save no more than 3 lines compared with `foreach`. Moreover, `foreach` can do better than your version. foreach ($persons as $p) { $groups[$p["education"]][$p["sex"]][MORE_SUBGRUP][] = $p; } output: $groups = [ "elementary" => [ "female" => [ MORE_SUBGRUP_1 => [ 0 => [...], 1 => [...] ], MORE_SUBGRUP_2 => [ 0 => [...], 1 => [...] ], ... ], "male" => [ MORE_SUBGRUP_1 => [ 0 => [...], 1 => [...] ], MORE_SUBGRUP_2 => [ 0 => [...], 1 => [...] ], ... ], ], "highschool" => [ ... ], ... ]; my suggestions are: - don't limit to array => involve object as well - offer reducer callable as an optional last param. reducer callable it will transform 2 steps algo (populating the groups and then reducing) to become a single step. but if it is not provided, the function returns the member of the group (same as example above). old way: // step-1 $group = []; foreach ($persons as $p) {/*...*/} // step-2 foreach ($group as &$eduGroup) { foreach ($eduGroup as &$sexGroup) { $sumWeight = 0; foreach ($sexGroup as $item) { $sumWeight += $item->weight; } $sexGroup = $sumWeight / count($sexGroup); } } output: $groups = [ "elementary" => [ "female" => 40, "male" => 50, ], "highschool" => [ "female" => 60, "male" => 65, ], ... ]; new way: array_column_group( $group, ["education", "sex", MORE_SUBGRUP], fn ($item, $i, $cumm) => ($item->weight + ($cumm * $i)) / ($i + 1) ); the signature: // array_column_group signature array_column_group( array|object $array, int|string|array $index_key, callable $reducer = null ) // callable signature fn (array|object $item, int|string $index, mixed $cummulative): mixed note: - $index_key can be in the form `["education", ...]` or `"education"`. - or even `[0, 1, ...]` or `0`. So virtually, `array_column_group` is a hybrid between `array_column` and `array_walk` (or other function with a funny name which I don't remember). Best Regards Hendra Gunawan. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Deprecate dynamic properties
Hi. A chunk in the RFC: abstract class Constraint { public $groups; public function __construct() { unset($this->groups); } public function __get($name) { // Will get called on first access, but once initialized. $this->groups = ...; } } Interesting! new to me. Maybe someday we will have this one: abstract class Constraint { public lazy $groups; public function __construct() { // no need to do this: // unset($this->groups); } public function __get($name) { // Will get called on first access, but once initialized. $this->groups = ...; } } Regards, Hendra Gunawan. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] A little syntactic sugar on array_* function calls?
Hello. > > The only correct way to resolve this issue is to not support mutable > operations. > Correct me if I'm wrong: scalar object will hit memory limit earlier than old API if it applied to $some_huge_shared_array for several method calls. > > I don't think there's much need for mutable operations. sort() and shuffle() > would be best implemented by returning a new array instead. array_push() is > redundant with $array[]. array_shift() and array_unshift() should never be > used. array_pop() and array_splice() are the only sensible mutable array > methods that come to mind, and I daresay we can do without them. > Suppose that we all agree with that. **Will scalar object preserve most of all functionality of the old API?** Some functions are very handy that keep us away from the gory detail implementation. In array case, we know that PHP array is a combination of array and plain object in JS term. There is a trend in user land PHP library that they are just copying the JS array API and poorly preserving the existing functionality of PHP old API. Implicitly, the author of this thread wants this to happen. If I am not wrong, scalar object date back to before PHP 7.0. Is there any consideration why scalar object was not escalated to the next phase, say to RFC? Regards Hendra Gunawan. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] A little syntactic sugar on array_* function calls?
Hello. > > Yes, but Nikita wrote this note about technical limitations at the bottom of > the repo README: > > Due to technical limitations, it is not possible to create mutable APIs for > primitive types. Modifying $self within the methods is not possible (or > rather, will have no effect, as you'd just be changing a copy). > If it is solved, this is a great accomplishment for PHP. But I think scalar object is not going anywhere in the near future. If you are not convinced, please take a look https://github.com/nikic/scalar_objects/issues/20#issuecomment-569520181. This makes me have a strong feeling about pipe operator greater than before to solve object-style for scalar issue. I hope that someone will take an initiative to fix the old inconsistent and confusing API. Pipe operator+new API is a better solution than no solution at all. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] A little syntactic sugar on array_* function calls?
Hello. > > ```php > $array|>map($fn1, ?)|>filter(?, $fn2); > $array->map($fn1)->filter($fn2); > ``` > Whitespace removal is not a solution for code length problems. You might have a new problem if you do it. "|" is very similar to the lowercase "L" and uppercase "i". It's just an extra 3 characters (", ?" or "?, "). For most people, this is not a problem at all. people tend to write "one statement per line" rather than "multi statement line". I myself usually write no more than 3 statements per line if they are less than 120 characters. The real problem is there is no consistency for "haystack vs needle" position. There are RFCs to fix this (along with the naming convention problem), but none of them are successful. > The pipe operator feels like a poor solution while "->" would do > exactly what people want. Not so poor if we * use "~>" as pipe operator rather than "|>" * redesign the api under their proper namespace and strictly place the "haystack" as the first function argument. Regards, Hendra Gunawan. -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] [RFC] Property accessors
Hi internals, > > I'd like to present an RFC for property accessors: > > https://wiki.php.net/rfc/property_accessors Hi internals, I am new here. Thank you Nikita for this wonderful proposal. A few days ago, I sent an identical message to this thread but I am not sure it was sent properly. So I sent it back here. Sorry about this. Let me make a suggestion for this one of mostly asked feature: class MyOldOrdinaryObject { public string $prop1 { get use getProp1; set use setProp1; } public string $prop2 { get use prefixProp2; set use prop2Sufix; } // pre existing methods // same function signature with corresponding accessor // method name is irrelevant public function getProp1(): string {/* ... */} public function setProp1(string $val): void {/* ... */} public function prefixProp2(): string {/* ... */} public function prop2Sufix(string $val): void {/* ... */} } This way: * without forcing them to use the new ones, users can choose whether to use old ones or new ones. * code duplication can be prevented, if we decided to preserve the old ones. * the accessors are more tidy and readable, if we decided to move out all multiline accessors. As far as I understand, the difference between "set" and "guard" is: with "set", we have freedom and responsibility to allocate a space. Additionally, we have to choose whether to use "set" or "guard", not both. It is a sad decision that "guard" has to be eliminated to reduce complexity. In my opinion, it is valuable that we can write code more concise than before: class MyOldOrdinaryObject { public string $prop1 { get; guard use commonGuard; } public string $prop2 { get; guard use commonGuard; } // Assuming that prop1 & prop2 have the same validity rules. // The visibility is private in order to prevent users accessing it. // Due to loss of space allocation and difference of function // signature, this method cannot be used in concert with "set". private function commonGuard(): void {/* ... */} } With this capability, the complex accessor in constructor problem can be solved class MyValueObject { public function __construct( public string $prop1 { get; private guard use guard1; } public string $prop2 { get; private guard use guard2; } public string $prop3 { get; private guard use commonGuard; } public string $prop4 { get; private guard use commonGuard; } ){} private function guard1(): void {/* ... */} private function guard2(): void {/* ... */} private function commonGuard(): void {/* ... */} } I hope that "guard" can be included again. I don't understand the internals of the engine. I think the mechanism of this is compiler assisted copy-paste (same as traits), but only the function body and the visibility is overridden based on accessors definition. Regards, Hendra Gunawan.
Re: [PHP-DEV] [RFC] Property accessors
Hi internals, I am new here. Let me make a suggestion for this one of mostly asked feature: class MyOldOrdinaryObject { public string $prop1 { get use getProp1; set use setProp1; } public string $prop2 { get use prefixProp2; set use prop2Sufix; } // pre existing methods // same function signature with corresponding accessor // method name is irrelevant public function getProp1(): string {/* ... */} public function setProp1(string $val): void {/* ... */} public function prefixProp2(): string {/* ... */} public function prop2Sufix(string $val): void {/* ... */} } This way: * without forcing them to use the new ones, users can choose whether to use old ones or new ones. * code duplication can be prevented, if we decided to preserve the old ones. * the accessors are more tidy and readable, if we decided to move out all multiline accessors. As far as I understand, the difference between "set" and "guard" is: with "set", we have freedom and responsibility to allocate a space. Additionally, we have to choose whether to use "set" or "guard", not both. It is a sad decision that "guard" has to be eliminated to reduce complexity. In my opinion, it is valuable that we can write code more concise than before: class MyOldOrdinaryObject { public string $prop1 { get; guard use commonGuard; } public string $prop2 { get; guard use commonGuard; } // Assuming that prop1 & prop2 have the same validity rules. // The visibility is private in order to prevent users accessing it. // Due to loss of space allocation and difference of function signature, // this method cannot be used in concert with "set". private function commonGuard(): void {/* ... */} } With this capability, the complex accessor in constructor problem can be solved: class MyValueObject { public function __construct( public string $prop1 { get; private guard use guard1; } public string $prop2 { get; private guard use guard2; } public string $prop3 { get; private guard use commonGuard; } public string $prop4 { get; private guard use commonGuard; } ){} private function guard1(): void {/* ... */} private function guard2(): void {/* ... */} private function commonGuard(): void {/* ... */} } I hope that "guard" can be included again. I don't understand the internals of PHP VM. I think the mechanism of this is compiler assisted copy-paste (same as traits), but only the function body and the visibility is overridden based on accessors definition. Regards, Hendra Gunawan. On Sat, May 8, 2021 at 5:16 AM Larry Garfield wrote: > On Tue, May 4, 2021, at 5:33 AM, Nikita Popov wrote: > > Hi internals, > > > > I'd like to present an RFC for property accessors: > > https://wiki.php.net/rfc/property_accessors > > > > Property accessors are like __get() and __set(), but for a single > property. > > They also support read-only properties and properties with asymmetric > > visibility (public read, private write) as a side-effect. > > > > The proposal is modeled after C#-style accessors (also used by Swift), > and > > syntactically similar to the previous > > https://wiki.php.net/rfc/propertygetsetsyntax-v1.2 proposal. > > > > While I put a lot of effort into both the proposal and the > implementation, > > I've grown increasingly uncertain that this is the right direction for us > > to take. The proposal turned out to be significantly more complex than I > > originally anticipated (despite reducing the scope to only "get" and > "set" > > accessors), and I'm sure there are some interactions I still haven't > > accounted for. I'm not convinced the value justifies the complexity. > > > > So, while I'm putting this up for discussion, it may be that I will not > > pursue landing it. I think a lot of the practical value of this accessors > > proposal would be captured by support for read-only (and/or > private-write) > > properties. This has been discussed (and declined) in the past, but > > probably should be revisited. > > > > Regards, > > Nikita > > Another question: I skimmed through the PR and its tests, and I didn't see > any tests around attributes. > > How do you envision attributes interacting with accessor-using > properties? I suppose there's no change for implicit accessors, but what > happens for explicit accessors? > > --Larry Garfield > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > >