# Proposal fo "Code-free constructors declaration"

- Thread: https://externals.io/message/103793
- Original archive: https://news-web.php.net/php.internals/103793
- Started by Andrey O Gromov on 2019-01-23T12:32:28+00:00
- Messages: 15
- 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

---

## #103793 — Andrey O Gromov — 2019-01-23T12:32:28+00:00

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

Full description
https://wiki.php.net/rfc/code_free_constructor
Draft realisation
https://github.com/php/php-src/compare/master...rjhdby:constructor

"Code free" constructor is constructor with only purpose to directly set 
object properties from received parameters and, optionally, call parent 
constructor.

Main idea is to move such constructor declaration inside class 
declaration.

Simple example:

Current syntax
class A extends B{
    public $prop;

    public function __construct($prop){
        parent::__construct("BlaBla", $prop);
        $this->prop = $prop;
    }
}

Proposed syntax
class A($prop) extends B("BlaBla", $prop) {
}

With respect, Andrey.

---

## #103797 — Bruce Weirdan — 2019-01-23T13:56:52+00:00

URL: https://externals.io/message/103793#103797 · In reply to: #103793

> Proposed syntax
> class A($prop) extends B("BlaBla", $prop) {
> }

Would this work with anonymous classes? If so, how would the syntax look like?

---

## #103798 — Andrey O Gromov — 2019-01-23T14:30:40+00:00

URL: https://externals.io/message/103793#103798 · In reply to: #103797

> > […]

>Would this work with anonymous classes? If so, how would the syntax look 
like?

Currently this syntax can't be used with anonymous classes because those 
classes instantiated 
at once they declared and same syntax is used for forwarding parameters 
directly into constructor. 

new class(10) extends SomeClass implements SomeInterface {
    public function __construct($num) {...}
} 

I think that it is possible to create additional rule when use 
"parameter_list" instead of "argument_list". 
Some research is required.
But it will add some ambiguity when reading code.

---

## #103802 — Dan Ackroyd — 2019-01-23T15:30:31+00:00

URL: https://externals.io/message/103793#103802 · In reply to: #103793

>
> Full description
> https://wiki.php.net/rfc/code_free_constructor
> Draft realisation
> https://github.com/php/php-src/compare/master...rjhdby:constructor
>

If this RFC solves a big problem for you, I would strongly recommend
looking at solving it with a preprocessor first:

https://preprocess.io/

cheers
Dan
Ack

---

## #103803 — Levi Morrison — 2019-01-23T15:43:34+00:00

URL: https://externals.io/message/103793#103803 · In reply to: #103797

>
> 
>
> > […]
>
> Would this work with anonymous classes? If so, how would the syntax look like?

I have the same question. I don't think it would work with them, but I
could be wrong.

---

## #103810 — Levi Morrison — 2019-01-23T17:38:36+00:00

URL: https://externals.io/message/103793#103810 · In reply to: #103803

>
> 
> > […]
>
> I have the same question. I don't think it would work with them, but I
> could be wrong.

Ah, another message confirmed it but it hit my spam folder: it does
not work with anonymous classes. In my opinion that is a non-starter.

---

## #103817 — Stanislav Malyshev — 2019-01-24T06:45:52+00:00

URL: https://externals.io/message/103793#103817 · In reply to: #103793

Hi!

> Proposed syntax
> class A($prop) extends B("BlaBla", $prop) {
> }

This looks like unobvious magic. PHP approach has traditionally been to
avoid unobvious magic, and be explicit about what is happening. This
functionality does not seem no be enabling anything different, and seems
to be pretty obscure as to what is going on. Also, $prop can not be
documented this way, and assigning default value to it may be a bit
weird too. I am all for paving the walkways, but this particular case
seems to be a bit too narrow to have a special language syntax for, and
the syntax seems to be not exactly obvious as to what's going on there.

-- 
Stas Malyshev
smalyshev@gmail.com

---

## #103818 — Andrey O Gromov — 2019-01-24T08:22:41+00:00

URL: https://externals.io/message/103793#103818 · In reply to: #103817

I'm added an illustration. Maybe it more clear for understanding.
https://wiki.php.net/_detail/rfc/joined.png?id=rfc%3Acode_free_constructor

> > […]

> This looks like unobvious magic. PHP approach has traditionally been to
> avoid unobvious magic, and be explicit about what is happening.
> This functionality does not seem no be enabling anything different, 
> and seems to be pretty obscure as to what is going on.
There is no magic, just alternative constructor syntax with some 
default behavior. Additional paragraph in documentation will resolve 
all obscurity.

Vice versa, this syntax make behavior more strict. No need to 
read constructor's body, because you know exactly what's going on.

Also there is no place for typos in boilerplate and refactoring errors.

IMHO inheritance also is more clear, because no need to search 
"parent::__construct" in the middle of class body.

> Also, $prop can not be documented this way, and assigning default 
> value to it may be a bit weird too.
Not sure that I understand this remark right way. What did you mean?
You can use php-doc similar you used it for functions.
Parameters block identical to function parameters block,
including types and default values.

> I am all for paving the walkways, but this particular case
> seems to be a bit too narrow to have a special language syntax for, and
> the syntax seems to be not exactly obvious as to what's going on there.
Matter of quality of documentation.

----------------------------
To Levi Morrison and Bruce Weirdan.

> > […]
look like?
> I have the same question. I don't think it would work with them, but I
> could be wrong.

There is no big problem to add same functionality to anonymous classes.
But unfortunately only possible syntax(I think) is not very nice.

new class(string $a, int $b, int $c=15)("Hi!",  20) extends SomeClass($a, 
115){...}

---

## #103843 — Nikita Popov — 2019-01-25T10:44:33+00:00

URL: https://externals.io/message/103793#103843 · In reply to: #103793

> Full description
> https://wiki.php.net/rfc/code_free_constructor
> Draft realisation
> https://github.com/php/php-src/compare/master...rjhdby:constructor
>
> "Code free" constructor is constructor with only purpose to directly set
> object properties from received parameters and, optionally, call parent
> constructor.
>
> Main idea is to move such constructor declaration inside class
> declaration.
>
> Simple example:
>
> Current syntax
> class A extends B{
>     public $prop;
>
>     public function __construct($prop){
>         parent::__construct("BlaBla", $prop);
>         $this->prop = $prop;
>     }
> }
>
> Proposed syntax
> class A($prop) extends B("BlaBla", $prop) {
> }
>
> With respect, Andrey.


Two alternatives you might want to consider:

* https://wiki.php.net/rfc/automatic_property_initialization => Proposed
function public function __construct(int $this->x, int $this->y) {}, which
avoids the need for explicit property assignments in the ctor. However, the
property still needs to be declared separately.

* https://docs.hhvm.com/hack/other-features/constructor-parameter-promotion
=> Uses public function __construct(public int $x, public int $y) {} to
declare properties in-line in the constructor.

I think that *if* we want to add some kind of sugar of this type, then I'd
strongly prefer the syntax used by Hack than the one proposed here. It
makes a lot more sense to me intuitively, probably because the property
declarations still looks like normal property declarations, they just occur
in-line in the ctor.

Nikita

---

## #103844 — Nikita Popov — 2019-01-25T11:05:21+00:00

URL: https://externals.io/message/103793#103844 · In reply to: #103843

> On Wed, Jan 23, 2019 at 1:33 PM Andrey O Gromov <AGromov@alfabank.ru>
> wrote:
>
> > […]
>
>
> Two alternatives you might want to consider:
>
> * https://wiki.php.net/rfc/automatic_property_initialization => Proposed
> function public function __construct(int $this->x, int $this->y) {}, which
> avoids the need for explicit property assignments in the ctor. However, the
> property still needs to be declared separately.
>
> *
> https://docs.hhvm.com/hack/other-features/constructor-parameter-promotion
> => Uses public function __construct(public int $x, public int $y) {} to
> declare properties in-line in the constructor.
>
> I think that *if* we want to add some kind of sugar of this type, then I'd
> strongly prefer the syntax used by Hack than the one proposed here. It
> makes a lot more sense to me intuitively, probably because the property
> declarations still looks like normal property declarations, they just occur
> in-line in the ctor.
>
> Nikita
>

To add to this: While I can totally understand the motivation to avoid the
property/constructor boilerplate (where the property name needs to be
repeated four times), I think that this is really solving the wrong
problem. The problem is the need to have a constructor at all.

Both this RFC and the two alternatives mentioned above really target the
case of "dumb" constructors that don't really do anything beyond assigning
properties from ctor arguments. I think that that is better solved by
adding a first-class syntax for object construction. I have something
roughly like this in mind:

class Point {
    public int $x;
    public int $y;
    public int $z;
}

// (syntax just a dummy)
$origin = new Point { x = 0, y = 0, z = 0 };

Where the object initialization syntax ensures that all properties that
don't have defaults are initialized. Especially now that we have typed
properties and it is feasible to have data objects with just public typed
properties, I think that this is the way to avoid ctor boilerplate, rather
than making it simpler to write that boilerplate.

Nikita

---

## #103846 — Rowan Collins — 2019-01-25T11:54:33+00:00

URL: https://externals.io/message/103793#103846 · In reply to: #103844

> class Point {
>     public int $x;
>     public int $y;
>     public int $z;
> }
>
> // (syntax just a dummy)
> $origin = new Point { x = 0, y = 0, z = 0 };
>
> Where the object initialization syntax ensures that all properties that
> don't have defaults are initialized. Especially now that we have typed
> properties and it is feasible to have data objects with just public typed
> properties, I think that this is the way to avoid ctor boilerplate, rather
> than making it simpler to write that boilerplate.
>


The big difference here is that you are making the short-hand the
responsibility of the caller, rather than the definer. I suspect there's a
Venn diagram of use cases where the two features would be useful.

In particular, the call-site syntax you have there would work really well
for a value type, and could go with having full support for that (e.g. have
the resulting object be immutable / copy-on-write); it works less well for
something like dependency injection, where the properties would normally be
private, and you might want to combine the short-hand with some normal
constructor logic.

Regards,
-- 
Rowan Collins
[IMSoP]

---

## #103848 — Levi Morrison — 2019-01-25T15:37:28+00:00

URL: https://externals.io/message/103793#103848 · In reply to: #103844

>
> 
>
> > […]
>
> To add to this: While I can totally understand the motivation to avoid the
> property/constructor boilerplate (where the property name needs to be
> repeated four times), I think that this is really solving the wrong
> problem. The problem is the need to have a constructor at all.
>
> Both this RFC and the two alternatives mentioned above really target the
> case of "dumb" constructors that don't really do anything beyond assigning
> properties from ctor arguments. I think that that is better solved by
> adding a first-class syntax for object construction. I have something
> roughly like this in mind:
>
> class Point {
>     public int $x;
>     public int $y;
>     public int $z;
> }
>
> // (syntax just a dummy)
> $origin = new Point { x = 0, y = 0, z = 0 };
>
> Where the object initialization syntax ensures that all properties that
> don't have defaults are initialized. Especially now that we have typed
> properties and it is feasible to have data objects with just public typed
> properties, I think that this is the way to avoid ctor boilerplate, rather
> than making it simpler to write that boilerplate.
>
> Nikita

I support this idea, although I think the `=` should be `=>` like
arrays, or `:` like JSON.

If you have any more complex of a need (such as private variables)
then I think you should write the constructor. The reason is that if
you have private variables, you need to establish a public API
contract.

---

## #103849 — Rowan Collins — 2019-01-25T16:36:57+00:00

URL: https://externals.io/message/103793#103849 · In reply to: #103848

>
> If you have any more complex of a need (such as private variables)
> then I think you should write the constructor. The reason is that if
> you have private variables, you need to establish a public API
> contract.
>

Right, which is why I think this is solving a different problem.

The OP was proposing a syntax that would allow you to simplify cases like
"call parent constructor with this constant, then set these 3 properties";
a call-time syntax like this is no use for that.

Regards,
-- 
Rowan Collins
[IMSoP]

---

## #103850 — Sebastian Bergmann — 2019-01-27T07:12:17+00:00

URL: https://externals.io/message/103793#103850 · In reply to: #103843

Am 25.01.2019 um 11:44 schrieb Nikita Popov:
> I think that *if* we want to add some kind of sugar of this type, then I'd
> strongly prefer the syntax used by Hack than the one proposed here.

Agreed.

---

## #103876 — Andrey O Gromov — 2019-01-29T12:18:16+00:00

URL: https://externals.io/message/103793#103876 · In reply to: #103849

Just updated proposal

https://wiki.php.net/rfc/code_free_constructor

v 0.2
Added visibility modificators syntax.
Changed behavior for parameters that need to be forwarded to parent.
Added “anonymous class” section.
Added “Q&A, Discussion” section.
Improved description of realization.
