On Mon, Sep 27, 2021 at 11:27 AM Konrad Baumgart <kon...@baumgart.pl> wrote:

> I was recently developing with js/ts and I liked the ease of returning
> multiple items from a function as an object, while still preserving
> their name.
>

I recently encountered this as well in Typescript. I believe the syntax is
something like this?
```js
const someProperty = "something";

const foo = {
    someProperty,
    anotherProperty: "Something else",
};

// same as
const foo = {
    someProperty: someProperty,
    anotherProperty: "Something else",
};
```
Obviously this won't work with PHP arrays, which is probably why you
decided for `=> $someProperty`.

I'm a big no-no when it comes to `compact()` and `extract()`. These
functions make my life hell. Despite knowing what they do, it still takes
me a lot of reading to try and figure out what they do. Even now I will
have to go to the documentation to understand exactly how either of them
work. Renaming a variable in a certain scope should not break something
outside of that scope, and I see this as a big problem in the proposal.
When I take your example, spot the error that will cause everything to
break runtime with limited static analysis to let you know (hint: missing a
g in the first variable).
```php
return [ => $dailyAgregations, => $weeklyAggregations];
```
Refactoring tools could just ignore the outside scope and automatically
change it, yet this won't solve anything for text find and replace.
```php
return [
    'dailyAggregations' => $theNewVariableName,
    => $weeklyAggregations,
];
```

If something like this were to be introduced, I'd happily see it happen
with anonymous objects and interfaces accepting properties:

```php
interface DashboardAggregations
{
    public readonly array $dailyAggregations;
    public readonly array $weeklyAggregations;
}

function getDashboardData() : DashboardAggregations
{
    $dailyAggregations = [];
    $weeklyAggregations = [];

    // ...
    return {
        $dailyAggregations,
        $weeklyAggregations,
    };

    // same as
    return {
        dailyAggregations: $dailyAggregations,
        weeklyAggregations: $weeklyAggregations,
    };

    // same as (if properties in interfaces were allowed)
    return new class($dailyAggregations, $weeklyAggregations) implements
DashboardAggregations {
        public function __construct(
            public readonly array $dailyAggregations,
            public readonly array $weeklyAggregations,
        ) {}
    };
}
```
If you then really need the destructuring, you could do something like this
(just a random syntax chosen), though I'd still be in favor of leaving this
aside as you now have a nice object with properties that are accessible.
```php
{$dailyAggregations, $weeklyAggregations} = getDashboardData();
```

This way php could verify the return value with the return type, and static
analyzers can determine the structure of what's to be returned. Imo this
functionality is not worth the headache with arrays.

That said, it feels like this proposal is more of a tuple/multiple return.

Reply via email to