# Methods which auto-return the class instance

- Thread: https://externals.io/message/119200
- Original archive: https://news-web.php.net/php.internals/119200
- Started by joke2k on 2022-12-23T00:08:32+00:00
- Messages: 10
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #119200 — joke2k — 2022-12-23T00:08:32+00:00

URL: https://externals.io/message/119200#119200

Hi folks,

What do you think about having a method which returns the class instance
`$this` by default only IF its return type is set as `self`?

It is very common for fluent class methods to have a verbose `return
$this;` ending in their body.
But If you have declared `self` as return type into a non-static class
method you have only two options to return:

- the $this object
- another instance of the same class or subclass

... in order to avoid a return type error.

My proposal is to set the instruction `return $this;` as optional for
non-static class methods with `self` declared as return type.

Example:
```
class Counter {

public function __construct(private int $counter = 0) {}

public function hit(): self { $this->counter++; }
public function print(): self { echo $this->counter; }

public function split(): self { return new self($this->counter); }

}

$main = (new Counter)->hit()->hit()->hit()->print()
// 3
$sub = $main->split()->hit()->print()
// 4
```

Thank you for reading my proposal,
please let me know if you like it or if there are any issues with this.

Regards,

Daniele

---

## #119202 — Claude Pache — 2022-12-23T09:33:34+00:00

URL: https://externals.io/message/119200#119202 · In reply to: #119200

> Le 23 déc. 2022 à 01:08, joke2k <joke2k@gmail.com> a écrit :
> 
> Hi folks,
> 
> What do you think about having a method which returns the class instance
> `$this` by default only IF its return type is set as `self`?
> 
> It is very common for fluent class methods to have a verbose `return
> $this;` ending in their body.
> But If you have declared `self` as return type into a non-static class
> method you have only two options to return:
> 
> - the $this object
> - another instance of the same class or subclass
> 
> ... in order to avoid a return type error.

It is still two options, and it is not clear in general which one to pick. You could also say that, if you have `object` as return type, there are two options to avoid a return type error: either return the `$this` object, or return another object.

> 
> My proposal is to set the instruction `return $this;` as optional for
> non-static class methods with `self` declared as return type.


I’d rather have a syntax saying explicitly that you want to return $this, rather than letting the interpreter guess what you meant. The obvious one is:

```php
public function hit(): $this { $this->counter++; }
```

Here, there is only one possible return value, and therefore the `return` instruction might be reasonably omitted.

The real question is: Is it worth to add special cases for some specific return values?

—Claude

---

## #119203 — Lynn — 2022-12-23T11:10:59+00:00

URL: https://externals.io/message/119200#119203 · In reply to: #119202

On Fri, Dec 23, 2022 at 10:33 AM Claude Pache <claude.pache@gmail.com>
wrote:

>
> ```php
> public function hit(): $this { $this->counter++; }
> ```
>
> Here, there is only one possible return value, and therefore the `return`
> instruction might be reasonably omitted.
>
> The real question is: Is it worth to add special cases for some specific
> return values?
>

We do have true, false, and null as return types (
https://www.php.net/releases/8.2/en.php#null_false_true_types). I'm
personally not opposed to having `$this` as return type, but it also starts
getting close to short function notations.

---

## #119204 — michal.brzuchalski@gmail.com — 2022-12-23T11:20:49+00:00

URL: https://externals.io/message/119200#119204 · In reply to: #119202

Hi Daniele and Claude,

pt., 23 gru 2022 o 10:33 Claude Pache <claude.pache@gmail.com> napisał(a):

>
> > […]
>
> It is still two options, and it is not clear in general which one to pick.
> You could also say that, if you have `object` as return type, there are two
> options to avoid a return type error: either return the `$this` object, or
> return another object.
>
> > […]
>
>
> I’d rather have a syntax saying explicitly that you want to return $this,
> rather than letting the interpreter guess what you meant. The obvious one
> is:
>
> ```php
> public function hit(): $this { $this->counter++; }
> ```
>
> Here, there is only one possible return value, and therefore the `return`
> instruction might be reasonably omitted.
>

I like the idea of `$this` as a return type but also strongly believe that
the use of `return $this;` should be forbidden,
eventually for control flow use of `return;` might be justified.

Cheers,
Michał Marcin Brzuchalski

---

## #119205 — joke2k — 2022-12-23T12:46:25+00:00

URL: https://externals.io/message/119200#119205 · In reply to: #119202

Thanks for the feedback!



> It is very common for fluent class methods to have a verbose `return
> $this;` ending in their body.
> But If you have declared `self` as return type into a non-static class
> method you have only two options to return:
>
> - the $this object
> - another instance of the same class or subclass
>
> ... in order to avoid a return type error.
>
>
> It is still two options, and it is not clear in general which one to pick.
> You could also say that, if you have `object` as return type, there are two
> options to avoid a return type error: either return the `$this` object, or
> return another object.
>

Yes but declaring `self` is more strict than `object`.
And talking about the word itself... Declaring to return (your-)`self` but
you could return someone-else of the same type as you.
But it is ok, it refers to the class name not the instance. just semantic.

My proposal is to set the instruction `return $this;` as optional for
> non-static class methods with `self` declared as return type.
>
>
> I’d rather have a syntax saying explicitly that you want to return $this,
> rather than letting the interpreter guess what you meant. The obvious one
> is:
>
> ```php
> public function hit(): $this { $this->counter++; }
> ```
>
> Here, there is only one possible return value, and therefore the `return`
> instruction might be reasonably omitted.
>

Return `$this` is a valid alternative indeed. It is an explicit subclass of
returning `self` which has a default return object, itself.

---

## #119206 — Claude Pache — 2022-12-23T13:29:07+00:00

URL: https://externals.io/message/119200#119206 · In reply to: #119205

> Le 23 déc. 2022 à 13:46, joke2k <joke2k@gmail.com> a écrit :
> 
> 
> > […]
> 
> It is still two options, and it is not clear in general which one to pick. You could also say that, if you have `object` as return type, there are two options to avoid a return type error: either return the `$this` object, or return another object.
> 
> Yes but declaring `self` is more strict than `object`. 
> And talking about the word itself... Declaring to return (your-)`self` but you could return someone-else of the same type as you. 
> But it is ok, it refers to the class name not the instance. just semantic.
> 


It is not about being less or more restricted, it is about being plainly ambiguous.

```php
class Point {
    
    public function __construct(
        protected float $x
      , protected float $y
    ) { }
    
    public function withY(float $y): static {
        $newPoint = clone $this;
        $newPoint->y = $y;
        // oops, forgot “return $newPoint;”
    }
}
```

With implicit behaviours (at least when there is more than one option), such sort of bugs become less apparent at runtime. Therefore, implicit behaviour ought to be avoided if possible.

—Claude

---

## #119207 — Robert Landers — 2022-12-23T14:37:02+00:00

URL: https://externals.io/message/119200#119207 · In reply to: #119200

> Hi folks,
>
> What do you think about having a method which returns the class instance
> `$this` by default only IF its return type is set as `self`?
>
> It is very common for fluent class methods to have a verbose `return
> $this;` ending in their body.
> But If you have declared `self` as return type into a non-static class
> method you have only two options to return:
>
> - the $this object
> - another instance of the same class or subclass
>
> ... in order to avoid a return type error.
>
> My proposal is to set the instruction `return $this;` as optional for
> non-static class methods with `self` declared as return type.
>
> Example:
> ```
> class Counter {
>
> public function __construct(private int $counter = 0) {}
>
> public function hit(): self { $this->counter++; }
> public function print(): self { echo $this->counter; }
>
> public function split(): self { return new self($this->counter); }
>
> }
>
> $main = (new Counter)->hit()->hit()->hit()->print()
> // 3
> $sub = $main->split()->hit()->print()
> // 4
> ```
>
> Thank you for reading my proposal,
> please let me know if you like it or if there are any issues with this.
>
> Regards,
>
> Daniele
>

As someone who used Scala for a number of years, I’d be very much
against this idea. Scala automatically returns the last line of any
function and we found it fairly difficult to maintain once the project
got fairly large and ended up switching to explicit returns. Mostly we
found it too easy to return the wrong thing.

In all fairness, I guess you technically don’t have to use it if you
don’t want to (you can use explicit returns), but IMHO, using this
would greatly affect readability. Every function you read that doesn’t
have a return, you’d have to check if the return type is self/static
and verify it is void.

-- 
Robert Landers
Software Engineer
Utrecht NL

---

## #119208 — Rowan Tommins — 2022-12-24T10:52:13+00:00

URL: https://externals.io/message/119200#119208 · In reply to: #119206

> > […]
>
>
>It is not about being less or more restricted, it is about being plainly ambiguous.


Another big advantage of "return $this" is that it can't affect any existing code. Granted, a function marked :self or :static which currently fails to return would be a runtime error, but changing that error into an implicit return $this could be very dangerous.

Regards,

-- 
Rowan Tommins
[IMSoP]

---

## #119209 — Ilija Tovilo — 2022-12-25T05:53:01+00:00

URL: https://externals.io/message/119200#119209 · In reply to: #119200

Hi Daniele


>
> Hi folks,
>
> What do you think about having a method which returns the class instance
> `$this` by default only IF its return type is set as `self`?
>
> It is very common for fluent class methods to have a verbose `return
> $this;` ending in their body.

Instead of adding special syntax to make writing fluent accessors
easier, I wonder if something akin to Dart's cascade operator would be
a better approach.

https://dart.dev/guides/language/language-tour#cascade-notation

$foo
   ..setBar('bar')
   ..setBaz('baz');

The syntax is just copied from Dart, there's probably a better fit for
PHP. .. would invoke a method call but discard the return value,
evaluating to the lhs of the method call instead.

With an operator solution one can use fluent method calls on APIs that
aren't specifically designed for it when desired, accessors can become
leaner as return $this is no longer necessary, and it becomes obvious
at call-site that the chained methods are called on the same object.

I'm not sure about syntax or the fact that Dart allows property
assignments in combination with .. as that makes the syntax ambiguous
(or whitespace sensitive), but that wouldn't be necessary for what
you're proposing.

Example of the ambiguity:

$foo
    ..bar = $bar
    ..baz()
// Could be parsed as
$foo..(bar = $bar)..baz()
$foo..bar = ($bar..baz())

An alternative might be a C# style syntax which would make property
assignments unambiguous.

$foo {
    setBar('bar'),
    baz = 'baz',
}

But this is also longer and less readable (to me at least).

Anyway, just my unrefined thoughts. I would not support implicit
`return $this` for self or static. At the very least, the return type
should be $this (which is essentially a sub-type of static) but that
too doesn't seem like an elegant solution to me.

Ilija

---

## #119211 — Pierre Joye — 2022-12-28T06:53:57+00:00

URL: https://externals.io/message/119200#119211 · In reply to: #119205

> Thanks for the feedback!
>
> 
>
> > […]
> pick.
> > […]
> two
> > […]
> or
> > […]
>
> Yes but declaring `self` is more strict than `object`.
> And talking about the word itself... Declaring to return (your-)`self` but
> you could return someone-else of the same type as you.
> But it is ok, it refers to the class name not the instance. just semantic.
>

I would rather endure it returns the used instance and not another one with
a compatible interface. Not doing do is actually confusing to me, as per
the meaning of self. .

Or maybe, if the goal is to ease declaration of fluent interfaces (methods
chaining), declaring a class fluent (annotation?) would achieve the same
with ambiguous names?
