On 9/5/2016 4:21 AM, Michał Brzuchalski wrote: > You may begin with modifications on RFC eg. in a gist so we can all > discuss about it before putting on RFC, is that okay to you?
Absolutely, that's how I thought about approaching it too because otherwise we might create a mess in the Wiki. On 9/5/2016 10:26 AM, Michał Brzuchalski wrote: > I had a talk at Room11 and we discussed idea of `mutator` keyword. > There were some concerns using `mutator` as a keyword - that's because > immutable object is not being muted and also magically appeared `$clone` > would be confusing. There's an idea of creating clone before function begins > and operating simply on `$this` while it's newly created clone from > immutable > object instance and the additional keyword for such method would be for eg. > `transformer`, so basically it may look like this: > > immutable class Money { > public $amount = 0; > public $currency; > public function __construct($amount, $currency) { > $this->amount = $amount; > $this->currency = $currency; > } > public transformer function amount($newamount) { > $this->amount = $newAmount; // $this actually is newly created clone > return $this; > } > } > > $oneHundret = new Money(100, $eur); > $twoHundret = $oneHundret->amount(200); > > How about that? The thing about mutator is only partly true because setters are generally just called mutator, it does not state anything about how it mutates something. Note that the keyword might proof useful in nonimmutable classes too for other use cases in the engine. Hence, I would not throw it off board just yet. It is true that $clone might come as a surprise and that's why I proposed to pass it as the first argument to the mutator function. However, you were right that that is a suboptimal proposal (and it pretty much goes completely against my previous paragraph). However, always providing $this as a clone is also not a good idea because you might want to return the same instance. This really depends on the kind of action that is desired. It's probably much simpler to keep the clone requirement and unseal the clone while making the __clone method protected by default. immutable prototype { protected function __clone(); } immutable class Money { public $amount; public $currency; public function __construct(int $amount, Currency $currency) { $this->amount = $amount; $this->currency = $currency; } public function withAmount(int $amount) { if ($this->amount === $amount) { return $this; } $clone = clone $this; $clone->amount = $amount; return $clone; } } This might seem like we haven't achieved much compared to the current state of affairs but we actually did: 1. No introduction of additional keywords (besides immutable) 2. No surprises (magic $clone variable) 3. No hard limitation on cloning (but disallowed by default) * 4. Full freedom to developers when to clone 5. Full freedom to developers what to return * Simply because a hard limitation is not required. Let people clone the immutable instances if they want too. Nothing bad happens besides wasting performance. I think that this is the simplest and thus best solution. :) -- Richard "Fleshgrinder" Fussenegger
signature.asc
Description: OpenPGP digital signature