Re: [PHP-DEV] RFC - Immutable classes

2016-09-15 Thread Fleshgrinder
On 9/14/2016 7:25 PM, Mathieu Rochette wrote:
> yeah the example is not that great, I'll usually want to clone to
> avoid calling a constructor with to many parameters (or a constructor
> doing too many things not needed here)
> 

That's exactly the reason why we want the _clone_ modifier. :)

On 9/14/2016 7:25 PM, Mathieu Rochette wrote:
> what's the difference between the two for an immutable class?
> 

The difference is that the engine cannot reason whether you need a clone
now or not. Allowing cloning in any context directly results in the fact
that someone from the outside can receive a copy of the object that is
actually mutable. However, exactly that is what we want to avoid by all
means.

It's true that userland deep cloning implementations will need to check
whether the instance at hand is cloneable or not. But as a matter of
fact they need to do that already anyways because there is no guarantee
that an object is actually cloneable because the `__clone` callback
could be invisible (`protected`/`private`) already.

-- 
Richard "Fleshgrinder" Fussenegger



signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] RFC - Immutable classes

2016-09-14 Thread Mathieu Rochette


Sent from my Alcatel Onetouch Idol 3 (4.7) 
On Sep 14, 2016 7:08 PM, Fleshgrinder  wrote: 
> 
> On 9/13/2016 11:38 PM, Mathieu Rochette wrote: 
> > I agree that blocking clone seems unnecessary. I also don't see why it 
> > is useful to have "clone" methods. Why not let "clone $this" produce a 
> > copy that is open to modification within the scope it's cloned in ? or, 
> > why would you limit yourself to one clone per method call ? maybe there 
> > is something I'm missing but I don't get why introducing a new method 
> > annotation is useful. it looks like an implementation details (using 
> > clone instead of new) of the method is leaking 
> > 
> > class Natural { 
> >  private $n; 
> >  public function __construct(int $n) {assert($n >= 0); $this->n = $n;} 
> >  public function nextTen() { 
> >   for ($i = 0, $c = $this; $i < 10; $i++, $c = clone $c;) { 
> >    $c->n++; 
> >    yield $c; 
> >   } 
> >  } 
> > } 
> 
> Why would you want to clone here? 
> 
>     final immutable class NaturalNumber { 
> 
>   private $n; 
> 
>   public function __construct(int $n) { 
>     assert($n >= 0); 
>     $this->n = $n; 
>   } 
> 
>   public function nextTen($n) { 
>     for ($i = $this->n; $i < 10; ++$i) { 
>   yield new static($i); 
>     } 
>   } 
> 
>     } 
> 
> That being said, the whole example is kind of weird. What kind of 
> functionality is that? Why is a value object creating multiple instances 
> for itself? Single responsibility seems to be broken because some kind 
> of collection should take care of that anyways. 

yeah the example is not that great, I'll usually want to clone to avoid calling 
a constructor with to many parameters (or a constructor doing too many things 
not needed here) 

> 
>     final immutable class NaturalNumber { 
> 
>   private $n; 
> 
>   public function __construct(int $n) {/*...*/} 
> 
>   public clone function add(int $n) { 
>     $this->n += $n; 
> 
>     return $this; 
>   } 
> 
>     } 
> 
>     final class NaturalNumberCollection { 
> 
>   public function nextTen(NaturalNumber $start) { 
>     // This cast does not work (yet) ... 
>     for ($i = (int) $start; $i < 10; ++$i) { 
>   yield $start->add($i); 
>     } 
>   } 
> 
>     } 
> 
> Same result but we just separated things nicely. I think the clone 
> modifier would help to create better code and keep it easy to understand. 
> 
> On 9/13/2016 11:38 PM, Mathieu Rochette wrote: 
> > again, why mark method as clone method in an interface, if the interface 
> > is already marked as immutable isn't it enough to specify the return 
> > type "static" ? 
> 
> Because it is unclear if you want to mutate in this context or return a 
> new instance altogether. 

what's the difference between the two for an immutable class? 

> 
> -- 
> Richard "Fleshgrinder" Fussenegger 
> 


Re: [PHP-DEV] RFC - Immutable classes

2016-09-14 Thread Fleshgrinder
On 9/13/2016 11:38 PM, Mathieu Rochette wrote:
> I agree that blocking clone seems unnecessary. I also don't see why it
> is useful to have "clone" methods. Why not let "clone $this" produce a
> copy that is open to modification within the scope it's cloned in ? or,
> why would you limit yourself to one clone per method call ? maybe there
> is something I'm missing but I don't get why introducing a new method
> annotation is useful. it looks like an implementation details (using
> clone instead of new) of the method is leaking
> 
> class Natural {
>  private $n;
>  public function __construct(int $n) {assert($n >= 0); $this->n = $n;}
>  public function nextTen() {
>   for ($i = 0, $c = $this; $i < 10; $i++, $c = clone $c;) {
>$c->n++;
>yield $c;
>   }
>  }
> }

Why would you want to clone here?

final immutable class NaturalNumber {

  private $n;

  public function __construct(int $n) {
assert($n >= 0);
$this->n = $n;
  }

  public function nextTen($n) {
for ($i = $this->n; $i < 10; ++$i) {
  yield new static($i);
}
  }

}

That being said, the whole example is kind of weird. What kind of
functionality is that? Why is a value object creating multiple instances
for itself? Single responsibility seems to be broken because some kind
of collection should take care of that anyways.

final immutable class NaturalNumber {

  private $n;

  public function __construct(int $n) {/*...*/}

  public clone function add(int $n) {
$this->n += $n;

return $this;
  }

}

final class NaturalNumberCollection {

  public function nextTen(NaturalNumber $start) {
// This cast does not work (yet) ...
for ($i = (int) $start; $i < 10; ++$i) {
  yield $start->add($i);
}
  }

}

Same result but we just separated things nicely. I think the clone
modifier would help to create better code and keep it easy to understand.

On 9/13/2016 11:38 PM, Mathieu Rochette wrote:
> again, why mark method as clone method in an interface, if the interface
> is already marked as immutable isn't it enough to specify the return
> type "static" ?

Because it is unclear if you want to mutate in this context or return a
new instance altogether.

-- 
Richard "Fleshgrinder" Fussenegger



signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] RFC - Immutable classes

2016-09-13 Thread Mathieu Rochette


On 09/13/2016 02:07 AM, Larry Garfield wrote:
> On 09/12/2016 06:47 PM, Stephen Reay wrote:
>>> Ah, I did see that one, but there was a lot of discussion after it
>>> so I thought the idea evolved.  Response below based on skimming the
>>> responses after that as well...
>>>
>>> It sounds like there's more that needs to go on, though.  It sounds
>>> like that thread is suggesting that $this in a method of an
>>> immutable object is always cloned, which seems excessive to me.
>>>
>>> The point about identity is well-taken.  However, it's more complex
>>> on objects because equality is not as simple as it is on strings.
>>> Two objects can be logically identical but physically different. For
>>> instance:
>>>
>>> class HttpHeaders {
>>>   public $attributes = [];
>>> }
>>>
>>> $a = new HttpHeaders();
>>> $a->attributes['foo'] = 'bar';
>>> $a->attributes['baz'] = 'buzz';
>>>
>>> $b = new HttpHeaders();
>>> $b->attributes['baz'] = 'buzz';
>>> $b->attributes['foo'] = 'bar';
>>>
>>> $a and $b are now not physically identical,  since their attributes
>>> array is in a different order.  However, header order doesn't matter
>>> in HTTP, or rather isn't supposed to.  (Modulo buggy
>>> implementations, of course.)  So are $a and $b identical?  I could
>>> very easily argue both directions on that.  Physical identity would
>>> be easier to automate checking in the engine; logical identity would
>>> require user-space code to make such decisions.
>>>
>>>  From the discussion of "transformer" methods, I'd propose a
>>> slightly different keyword.  To wit:
>>>
>>> 1) A class marked as "immutable" may not have any of its properties
>>> altered, EXCEPT in certain unlocked scopes.  The constructor is an
>>> unlocked scope.
>>>
>>> 2) A method may be marked "clone": public clone function foo() {}. A
>>> clone method is identical to any other method except that A) $this
>>> in its scope is not the original object, but the result of
>>> clone($this); B) A clone method is an unlocked scope, so modifying
>>> $this (the clone) is legal.  That is more self-descriptive than
>>> "transformer", and also doesn't require a new keyword.  (By
>>> implication, clone and static are mutually exclusive since clone
>>> requires an object to clone.)
>>>
>>> I don't know that there are any other unlocked scopes to consider...
>>>
>>> #2 does leave us with the identity question that Richard raises, in
>>> that returning an unmodified $this from a clone method still creates
>>> a new object identity.  However, I posit that is to be expected.  In
>>> Python, eg, while some built-in objects are immutable they are not,
>>> necessarily, always the same physical object in memory.  (999+1 is
>>> not the same object as 1000, but 1+2 and 2 likely will be due to
>>> internal engine optimizations.)  You need to do a value comparison
>>> of them.
>>>
>>> I don't see the identity case being resolved without an __identity()
>>> method, or similar.  Which could be useful in its own right so I'm
>>> not necessarily against it, but it's an extra, and I'd argue
>>> optional, piece of the puzzle.
>>>
>>> Related to whether or not the properties of an object may be mutable
>>> (arrays, other objects, etc.), they would in practice probably need
>>> to blacklist resources.  We ran into that issue in PSR-7, where the
>>> body stream has to be mutable, because streams.  Since PSR-7 is
>>> based on PHP 5.3 that doesn't cause any syntactic issues, just
>>> logical issues.  If the classes were marked immutable explicitly, it
>>> likely would be a problem since the streams cannot be immutable,
>>> thus they can't be used on an immutable object.  Which is... very
>>> sad making. :-(
>>>
>>> --Larry Garfield
>>>
>>> -- 
>>> PHP Internals - PHP Runtime Development Mailing List
>>> To unsubscribe, visit: http://www.php.net/unsub.php
>>>
>> I like your suggestion with the ‘clone’ keyword on methods.
>>
>> As I said before, I think it’s a mis-step to prevent manual cloning
>> at the engine level (even if the result is that you return the same
>> instance) - there is *bound* to be user land code that clones
>> objects. Without this, any use of clone in a distributed
>> library/framework will have to do a check to see if an object (except
>> those accepting final classes of known definition) is immutable
>> before attempting to clone it.
>
> I think most people in the thread have agreed that blocking clone() is
> unnecessary, the RFC just hasn't been updated yet.  With a clone
> method, an external clone becomes basically a pointless but harmless
> operation, I'd think.  A clone within the class would be fairly
> nonsensical, except for the clone methods.
I agree that blocking clone seems unnecessary. I also don't see why it
is useful to have "clone" methods. Why not let "clone $this" produce a
copy that is open to modification within the scope it's cloned in ? or,
why would you limit yourself to one clone per method call ? maybe there
is something I'm missing but I don't get 

Re: [PHP-DEV] RFC - Immutable classes

2016-09-13 Thread Lester Caine
On 13/09/16 00:47, Stephen Reay wrote:
> Regarding identity, I’m going to refer back to the DateTimeImmutable class. I 
> know its not the same implementation, but honestly I don’t think that 
> matters. Developers use PHP because they generally *don’t* have to worry 
> about the internal details of the engine.
> 
> e.g.: 
> $d = new DateTimeImmutable();
> $e = $d->add(new DateInterval('PT0S'));
> 
> var_dump($d === $e);  // bool(false)

ReadOnly DateTimeStamp is the only 'objects' I can currently see a use
for in my own code base. CoW makes perfect sense to me but I would not
view that as 'clone', simply 'construct a new readonly object'. I've
already indicated that I view date/time as a simple 64 bit number, and
'comparable' fits that model nicely except it needs a more flexible
TOLERANCE for months. ( And DateTimeImmutable does not work for me but
that is because I have raw access to the firebird timestamps )

Just where else do people think 'immutable' objects are essential? Just
what is necessary over a 'readonly object'?

I'm still trying to get my head around some of the hidden details here.
My 'readonly object' assumes the code to handle is a separate class used
to view the data, but I assume the sort of object being discussed here
is in essence a 'constructionaless' copy of the class? With wriggle room
to perhaps make some write code available for some strange reason? I'm
still struggling to see just where the 'code' fits in this. If I have a
copy of the code in the 'construction' version of the class does the
copy also need that code duplicated?

-- 
Lester Caine - G8HFL
-
Contact - http://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk
Rainbow Digital Media - http://rainbowdigitalmedia.co.uk

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] RFC - Immutable classes

2016-09-13 Thread Michał Brzuchalski
Proposed operator overloading and magic methods to compare with other
objects
is very good idea, I like it a lot, there even may be additional
restriction provided
with my other RFC https://wiki.php.net/rfc/object-typehint

But I think this goal should be provided in separate RFC as it is very
usefull in
immutable objects, but also will be in mutable objects. While this is not
required
to introduce immutable objects I thinkk it should be in separate RFC.

2016-09-13 8:40 GMT+02:00 Fleshgrinder :

> Thanks a lot for your feedback.
>
> I like the clone idea too and I also see no harm in allowing them in any
> context rather than only in immutable classes. I am really against the
> transformer keyword, don't ask me why, I just don't like it at all. :P
>
> I mentioned before that PHP should allow for operator overloading since
> there are other value object use cases that are even simpler than your
> HTTP header result: any value object that is case insensitive. Doh!
>
> I do like the https://wiki.php.net/rfc/comparable RFC but we would need
> more for value objects to be truly useful.
>
>   class A {
>
> // $this == $other
> function __isEqual($other);
>
> // $this === $other
> function __isIdentical($other);
>
>   }
>
> This will be very hard to get through though because it's operator
> overloading. I am currently already doing this in many of my value
> objects, although I usually implement an equals method only and let it
> take care of equals and identity checks at the same time.
>
>   final class HexNumber {
>
> private $val;
>
> public function __construct(string $hex) {
>   $this->val = strtolower($hex);
> }
>
> public function equals($other) {
>   if ($other instanceof self) {
> return $other->val === $this->val;
>   }
>
>   if (is_string($other)) {
> return strtolower($other) === $this->val;
>   }
>
>   return false;
> }
>
>   }
>
>   $hn = new HexNumber('ff00');
>   var_dump($hn->equals('FF00')); // bool(true)
>
> However, this is not necessarily exactly what you want in every context,
> hence, the proposal for operator overloading.
>
> That being said, I agree that this could (and probably should) be
> tackled in another RFC. Immutable classes do not have to solve every
> problem.
>
> --
> Richard "Fleshgrinder" Fussenegger
>
>


-- 
regards / pozdrawiam,
--
Michał Brzuchalski
brzuchalski.com


Re: [PHP-DEV] RFC - Immutable classes

2016-09-13 Thread Fleshgrinder
Thanks a lot for your feedback.

I like the clone idea too and I also see no harm in allowing them in any
context rather than only in immutable classes. I am really against the
transformer keyword, don't ask me why, I just don't like it at all. :P

I mentioned before that PHP should allow for operator overloading since
there are other value object use cases that are even simpler than your
HTTP header result: any value object that is case insensitive. Doh!

I do like the https://wiki.php.net/rfc/comparable RFC but we would need
more for value objects to be truly useful.

  class A {

// $this == $other
function __isEqual($other);

// $this === $other
function __isIdentical($other);

  }

This will be very hard to get through though because it's operator
overloading. I am currently already doing this in many of my value
objects, although I usually implement an equals method only and let it
take care of equals and identity checks at the same time.

  final class HexNumber {

private $val;

public function __construct(string $hex) {
  $this->val = strtolower($hex);
}

public function equals($other) {
  if ($other instanceof self) {
return $other->val === $this->val;
  }

  if (is_string($other)) {
return strtolower($other) === $this->val;
  }

  return false;
}

  }

  $hn = new HexNumber('ff00');
  var_dump($hn->equals('FF00')); // bool(true)

However, this is not necessarily exactly what you want in every context,
hence, the proposal for operator overloading.

That being said, I agree that this could (and probably should) be
tackled in another RFC. Immutable classes do not have to solve every
problem.

-- 
Richard "Fleshgrinder" Fussenegger



signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] RFC - Immutable classes

2016-09-12 Thread Larry Garfield

On 09/12/2016 06:47 PM, Stephen Reay wrote:

Ah, I did see that one, but there was a lot of discussion after it so I thought 
the idea evolved.  Response below based on skimming the responses after that as 
well...

It sounds like there's more that needs to go on, though.  It sounds like that 
thread is suggesting that $this in a method of an immutable object is always 
cloned, which seems excessive to me.

The point about identity is well-taken.  However, it's more complex on objects 
because equality is not as simple as it is on strings. Two objects can be 
logically identical but physically different. For instance:

class HttpHeaders {
  public $attributes = [];
}

$a = new HttpHeaders();
$a->attributes['foo'] = 'bar';
$a->attributes['baz'] = 'buzz';

$b = new HttpHeaders();
$b->attributes['baz'] = 'buzz';
$b->attributes['foo'] = 'bar';

$a and $b are now not physically identical,  since their attributes array is in 
a different order.  However, header order doesn't matter in HTTP, or rather 
isn't supposed to.  (Modulo buggy implementations, of course.)  So are $a and 
$b identical?  I could very easily argue both directions on that.  Physical 
identity would be easier to automate checking in the engine; logical identity 
would require user-space code to make such decisions.

 From the discussion of "transformer" methods, I'd propose a slightly different 
keyword.  To wit:

1) A class marked as "immutable" may not have any of its properties altered, 
EXCEPT in certain unlocked scopes.  The constructor is an unlocked scope.

2) A method may be marked "clone": public clone function foo() {}. A clone method is 
identical to any other method except that A) $this in its scope is not the original object, but the 
result of clone($this); B) A clone method is an unlocked scope, so modifying $this (the clone) is 
legal.  That is more self-descriptive than "transformer", and also doesn't require a new 
keyword.  (By implication, clone and static are mutually exclusive since clone requires an object 
to clone.)

I don't know that there are any other unlocked scopes to consider...

#2 does leave us with the identity question that Richard raises, in that 
returning an unmodified $this from a clone method still creates a new object 
identity.  However, I posit that is to be expected.  In Python, eg, while some 
built-in objects are immutable they are not, necessarily, always the same 
physical object in memory.  (999+1 is not the same object as 1000, but 1+2 and 
2 likely will be due to internal engine optimizations.)  You need to do a value 
comparison of them.

I don't see the identity case being resolved without an __identity() method, or 
similar.  Which could be useful in its own right so I'm not necessarily against 
it, but it's an extra, and I'd argue optional, piece of the puzzle.

Related to whether or not the properties of an object may be mutable (arrays, 
other objects, etc.), they would in practice probably need to blacklist 
resources.  We ran into that issue in PSR-7, where the body stream has to be 
mutable, because streams.  Since PSR-7 is based on PHP 5.3 that doesn't cause 
any syntactic issues, just logical issues.  If the classes were marked 
immutable explicitly, it likely would be a problem since the streams cannot be 
immutable, thus they can't be used on an immutable object.  Which is... very 
sad making. :-(

--Larry Garfield

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php


I like your suggestion with the ‘clone’ keyword on methods.

As I said before, I think it’s a mis-step to prevent manual cloning at the 
engine level (even if the result is that you return the same instance) - there 
is *bound* to be user land code that clones objects. Without this, any use of 
clone in a distributed library/framework will have to do a check to see if an 
object (except those accepting final classes of known definition) is immutable 
before attempting to clone it.


I think most people in the thread have agreed that blocking clone() is 
unnecessary, the RFC just hasn't been updated yet.  With a clone method, 
an external clone becomes basically a pointless but harmless operation, 
I'd think.  A clone within the class would be fairly nonsensical, except 
for the clone methods.



Regarding identity, I’m going to refer back to the DateTimeImmutable class. I 
know its not the same implementation, but honestly I don’t think that matters. 
Developers use PHP because they generally *don’t* have to worry about the 
internal details of the engine.

e.g.:
$d = new DateTimeImmutable();
$e = $d->add(new DateInterval('PT0S'));

var_dump($d === $e);  // bool(false)


Personally I think if we want to worry about whether two objects represent the same 
value, wouldn’t that be better handled (and with much greater positive effect for 
developers) by finalising & passing the Comparable RFC 
(https://wiki.php.net/rfc/comparable)?

Cheers

Stephen


That does 

Re: [PHP-DEV] RFC - Immutable classes

2016-09-12 Thread Stephen Reay
Hi Larry,

> On 13 Sep 2016, at 03:11, Larry Garfield  wrote:
> 
> On 09/12/2016 11:40 AM, Fleshgrinder wrote:
>> On 9/11/2016 10:04 PM, Larry Garfield wrote:
>>> On 09/10/2016 05:55 AM, Fleshgrinder wrote:
 @Larry what do you think about the CoW proposal?
>>> I'm afraid I got lost in the thread somewhere with the back and forth
>>> about implementation details. Can you repost the current proposal, or
>>> has the RFC page been updated with the latest CoW-based recommendation?
>>> 
>>> --Larry Garfield
>>> 
>> No worries, here is the original message of mine in response to you (but
>> I guess that I did not include you in the recipients):
>> 
>> https://marc.info/?l=php-internals=147318929726088=2
>> 
> 
> Ah, I did see that one, but there was a lot of discussion after it so I 
> thought the idea evolved.  Response below based on skimming the responses 
> after that as well...
> 
> It sounds like there's more that needs to go on, though.  It sounds like that 
> thread is suggesting that $this in a method of an immutable object is always 
> cloned, which seems excessive to me.
> 
> The point about identity is well-taken.  However, it's more complex on 
> objects because equality is not as simple as it is on strings. Two objects 
> can be logically identical but physically different. For instance:
> 
> class HttpHeaders {
>  public $attributes = [];
> }
> 
> $a = new HttpHeaders();
> $a->attributes['foo'] = 'bar';
> $a->attributes['baz'] = 'buzz';
> 
> $b = new HttpHeaders();
> $b->attributes['baz'] = 'buzz';
> $b->attributes['foo'] = 'bar';
> 
> $a and $b are now not physically identical,  since their attributes array is 
> in a different order.  However, header order doesn't matter in HTTP, or 
> rather isn't supposed to.  (Modulo buggy implementations, of course.)  So are 
> $a and $b identical?  I could very easily argue both directions on that.  
> Physical identity would be easier to automate checking in the engine; logical 
> identity would require user-space code to make such decisions.
> 
> From the discussion of "transformer" methods, I'd propose a slightly 
> different keyword.  To wit:
> 
> 1) A class marked as "immutable" may not have any of its properties altered, 
> EXCEPT in certain unlocked scopes.  The constructor is an unlocked scope.
> 
> 2) A method may be marked "clone": public clone function foo() {}. A clone 
> method is identical to any other method except that A) $this in its scope is 
> not the original object, but the result of clone($this); B) A clone method is 
> an unlocked scope, so modifying $this (the clone) is legal.  That is more 
> self-descriptive than "transformer", and also doesn't require a new keyword.  
> (By implication, clone and static are mutually exclusive since clone requires 
> an object to clone.)
> 
> I don't know that there are any other unlocked scopes to consider...
> 
> #2 does leave us with the identity question that Richard raises, in that 
> returning an unmodified $this from a clone method still creates a new object 
> identity.  However, I posit that is to be expected.  In Python, eg, while 
> some built-in objects are immutable they are not, necessarily, always the 
> same physical object in memory.  (999+1 is not the same object as 1000, but 
> 1+2 and 2 likely will be due to internal engine optimizations.)  You need to 
> do a value comparison of them.
> 
> I don't see the identity case being resolved without an __identity() method, 
> or similar.  Which could be useful in its own right so I'm not necessarily 
> against it, but it's an extra, and I'd argue optional, piece of the puzzle.
> 
> Related to whether or not the properties of an object may be mutable (arrays, 
> other objects, etc.), they would in practice probably need to blacklist 
> resources.  We ran into that issue in PSR-7, where the body stream has to be 
> mutable, because streams.  Since PSR-7 is based on PHP 5.3 that doesn't cause 
> any syntactic issues, just logical issues.  If the classes were marked 
> immutable explicitly, it likely would be a problem since the streams cannot 
> be immutable, thus they can't be used on an immutable object.  Which is... 
> very sad making. :-(
> 
> --Larry Garfield
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
> 

I like your suggestion with the ‘clone’ keyword on methods. 

As I said before, I think it’s a mis-step to prevent manual cloning at the 
engine level (even if the result is that you return the same instance) - there 
is *bound* to be user land code that clones objects. Without this, any use of 
clone in a distributed library/framework will have to do a check to see if an 
object (except those accepting final classes of known definition) is immutable 
before attempting to clone it.

Regarding identity, I’m going to refer back to the DateTimeImmutable class. I 
know its not the same implementation, but honestly I don’t think that 

Re: [PHP-DEV] RFC - Immutable classes

2016-09-12 Thread Larry Garfield

On 09/12/2016 11:40 AM, Fleshgrinder wrote:

On 9/11/2016 10:04 PM, Larry Garfield wrote:

On 09/10/2016 05:55 AM, Fleshgrinder wrote:

@Larry what do you think about the CoW proposal?

I'm afraid I got lost in the thread somewhere with the back and forth
about implementation details. Can you repost the current proposal, or
has the RFC page been updated with the latest CoW-based recommendation?

--Larry Garfield


No worries, here is the original message of mine in response to you (but
I guess that I did not include you in the recipients):

https://marc.info/?l=php-internals=147318929726088=2



Ah, I did see that one, but there was a lot of discussion after it so I 
thought the idea evolved.  Response below based on skimming the 
responses after that as well...


It sounds like there's more that needs to go on, though.  It sounds like 
that thread is suggesting that $this in a method of an immutable object 
is always cloned, which seems excessive to me.


The point about identity is well-taken.  However, it's more complex on 
objects because equality is not as simple as it is on strings. Two 
objects can be logically identical but physically different. For instance:


class HttpHeaders {
  public $attributes = [];
}

$a = new HttpHeaders();
$a->attributes['foo'] = 'bar';
$a->attributes['baz'] = 'buzz';

$b = new HttpHeaders();
$b->attributes['baz'] = 'buzz';
$b->attributes['foo'] = 'bar';

$a and $b are now not physically identical,  since their attributes 
array is in a different order.  However, header order doesn't matter in 
HTTP, or rather isn't supposed to.  (Modulo buggy implementations, of 
course.)  So are $a and $b identical?  I could very easily argue both 
directions on that.  Physical identity would be easier to automate 
checking in the engine; logical identity would require user-space code 
to make such decisions.


From the discussion of "transformer" methods, I'd propose a slightly 
different keyword.  To wit:


1) A class marked as "immutable" may not have any of its properties 
altered, EXCEPT in certain unlocked scopes.  The constructor is an 
unlocked scope.


2) A method may be marked "clone": public clone function foo() {}. A 
clone method is identical to any other method except that A) $this in 
its scope is not the original object, but the result of clone($this); B) 
A clone method is an unlocked scope, so modifying $this (the clone) is 
legal.  That is more self-descriptive than "transformer", and also 
doesn't require a new keyword.  (By implication, clone and static are 
mutually exclusive since clone requires an object to clone.)


I don't know that there are any other unlocked scopes to consider...

#2 does leave us with the identity question that Richard raises, in that 
returning an unmodified $this from a clone method still creates a new 
object identity.  However, I posit that is to be expected.  In Python, 
eg, while some built-in objects are immutable they are not, necessarily, 
always the same physical object in memory.  (999+1 is not the same 
object as 1000, but 1+2 and 2 likely will be due to internal engine 
optimizations.)  You need to do a value comparison of them.


I don't see the identity case being resolved without an __identity() 
method, or similar.  Which could be useful in its own right so I'm not 
necessarily against it, but it's an extra, and I'd argue optional, piece 
of the puzzle.


Related to whether or not the properties of an object may be mutable 
(arrays, other objects, etc.), they would in practice probably need to 
blacklist resources.  We ran into that issue in PSR-7, where the body 
stream has to be mutable, because streams.  Since PSR-7 is based on PHP 
5.3 that doesn't cause any syntactic issues, just logical issues.  If 
the classes were marked immutable explicitly, it likely would be a 
problem since the streams cannot be immutable, thus they can't be used 
on an immutable object.  Which is... very sad making. :-(


--Larry Garfield

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] RFC - Immutable classes

2016-09-12 Thread Fleshgrinder
On 9/11/2016 10:04 PM, Larry Garfield wrote:
> On 09/10/2016 05:55 AM, Fleshgrinder wrote:
>> @Larry what do you think about the CoW proposal?
> 
> I'm afraid I got lost in the thread somewhere with the back and forth
> about implementation details. Can you repost the current proposal, or
> has the RFC page been updated with the latest CoW-based recommendation?
> 
> --Larry Garfield
> 

No worries, here is the original message of mine in response to you (but
I guess that I did not include you in the recipients):

https://marc.info/?l=php-internals=147318929726088=2

-- 
Richard "Fleshgrinder" Fussenegger



signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] RFC - Immutable classes

2016-09-12 Thread Silvio Marijić
@Larry

RFC is not updated with the solution for cloning yet. So far I did add
changes on which we have agreed on. Currently we have to candidates:

First one is to have copy on write (As Christoph pointed out, we had that
in PHP 4).
Second proposal is to introduce "transformer" keyword as a method modifier.
In "transformer" method $this would basically represent cloned instance
instead of the original object.


Cheers.

2016-09-11 22:04 GMT+02:00 Larry Garfield :

> On 09/10/2016 05:55 AM, Fleshgrinder wrote:
>
>> So? Where are we now? CoW is definitely doable and I personally think
>> that it's the best approach because the engine has full control that
>> nothing goes south. I also do not think that it's magic in any way since
>> developers have to add the _immutable_ keyword explicitly to the class.
>> That this modifier modifies the behavior should be obvious, _abstract_
>> and _interface_ also do that.
>>
>> Since I mention _interface_. I've been thinking about it and I would
>> prefer it if the _immutable_ modifier also works for interfaces.
>> Interfaces are pure abstract classes after all and they are meant to
>> define a contract for implementors. I cannot see any good reason why it
>> should not be allowed to force implementors of an interface to be
>> immutable; same as with abstract classes.
>>
>> Another aspect that we should discuss is how immutable properties should
>> behave in case we decide for CoW.
>>
>> @Larry what do you think about the CoW proposal?
>>
>
> I'm afraid I got lost in the thread somewhere with the back and forth
> about implementation details. Can you repost the current proposal, or has
> the RFC page been updated with the latest CoW-based recommendation?
>
>
> --Larry Garfield
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>


-- 
Silvio Marijić
Software Engineer
2e Systems


Re: [PHP-DEV] RFC - Immutable classes

2016-09-11 Thread Larry Garfield

On 09/10/2016 05:55 AM, Fleshgrinder wrote:

So? Where are we now? CoW is definitely doable and I personally think
that it's the best approach because the engine has full control that
nothing goes south. I also do not think that it's magic in any way since
developers have to add the _immutable_ keyword explicitly to the class.
That this modifier modifies the behavior should be obvious, _abstract_
and _interface_ also do that.

Since I mention _interface_. I've been thinking about it and I would
prefer it if the _immutable_ modifier also works for interfaces.
Interfaces are pure abstract classes after all and they are meant to
define a contract for implementors. I cannot see any good reason why it
should not be allowed to force implementors of an interface to be
immutable; same as with abstract classes.

Another aspect that we should discuss is how immutable properties should
behave in case we decide for CoW.

@Larry what do you think about the CoW proposal?


I'm afraid I got lost in the thread somewhere with the back and forth 
about implementation details. Can you repost the current proposal, or 
has the RFC page been updated with the latest CoW-based recommendation?


--Larry Garfield

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] RFC - Immutable classes

2016-09-10 Thread Silvio Marijić
I agree. Will add this feature to RFC also

Cheers
On Sep 10, 2016 8:02 PM, "Marco Pivetta"  wrote:

> On Sat, Sep 10, 2016 at 7:49 PM, Niklas Keller  wrote:
>
>> 2016-09-10 19:41 GMT+02:00 Silvio Marijić :
>>
>> > @Fleshgrinder,
>> >
>> > While I'm not sure at the moment about CoW, I can agree that we should
>> add
>> > immutable keyword as a interface modifier to make sure all classes
>> > implementing must be immutable.
>>
>>
>> As interfaces can't have member variables, that doesn't make sense to me.
>>
>
> It still makes sense from a consumer perspective, so having the
> restriction in the contract is quite good.
>
> If you accept a `Number`, you expect to be able to serialize/de-serialize
> it, and you expect it to be "locked", immutable.
> If you let an implementation of `Number` to have mutable state in, then
> you break all the code that relies on `Number`.
> Note that it is still possible to break this though, so maybe we'd need
> some other modifiers about behavior too (pure function modifier?)
>
> immutable interface Number
> {
> public function toFloat() : float;
> }
> immutable class RandomNumber implements Number
> {
> public function toFloat() : float { return (float) random_int(1,
> 10); /* yo, look at my global mutable hidden state! */ }
> }
>
> Requiring immutable values in consumers will likely improve code
> quality/safety and reduce dangerous assumptions, and it will probably also
> allow for optimizations in the engine later on.
>
> Marco Pivetta
>
> http://twitter.com/Ocramius
>
> http://ocramius.github.com/
>
>


Re: [PHP-DEV] RFC - Immutable classes

2016-09-10 Thread Marco Pivetta
On Sat, Sep 10, 2016 at 7:49 PM, Niklas Keller  wrote:

> 2016-09-10 19:41 GMT+02:00 Silvio Marijić :
>
> > @Fleshgrinder,
> >
> > While I'm not sure at the moment about CoW, I can agree that we should
> add
> > immutable keyword as a interface modifier to make sure all classes
> > implementing must be immutable.
>
>
> As interfaces can't have member variables, that doesn't make sense to me.
>

It still makes sense from a consumer perspective, so having the restriction
in the contract is quite good.

If you accept a `Number`, you expect to be able to serialize/de-serialize
it, and you expect it to be "locked", immutable.
If you let an implementation of `Number` to have mutable state in, then you
break all the code that relies on `Number`.
Note that it is still possible to break this though, so maybe we'd need
some other modifiers about behavior too (pure function modifier?)

immutable interface Number
{
public function toFloat() : float;
}
immutable class RandomNumber implements Number
{
public function toFloat() : float { return (float) random_int(1,
10); /* yo, look at my global mutable hidden state! */ }
}

Requiring immutable values in consumers will likely improve code
quality/safety and reduce dangerous assumptions, and it will probably also
allow for optimizations in the engine later on.

Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/


Re: [PHP-DEV] RFC - Immutable classes

2016-09-10 Thread Niklas Keller
2016-09-10 19:41 GMT+02:00 Silvio Marijić :

> @Fleshgrinder,
>
> While I'm not sure at the moment about CoW, I can agree that we should add
> immutable keyword as a interface modifier to make sure all classes
> implementing must be immutable.


As interfaces can't have member variables, that doesn't make sense to me.


Re: [PHP-DEV] RFC - Immutable classes

2016-09-10 Thread Silvio Marijić
@Fleshgrinder,

While I'm not sure at the moment about CoW, I can agree that we should add
immutable keyword as a interface modifier to make sure all classes
implementing must be immutable.
On Sep 10, 2016 12:55 PM, "Fleshgrinder"  wrote:

> So? Where are we now? CoW is definitely doable and I personally think
> that it's the best approach because the engine has full control that
> nothing goes south. I also do not think that it's magic in any way since
> developers have to add the _immutable_ keyword explicitly to the class.
> That this modifier modifies the behavior should be obvious, _abstract_
> and _interface_ also do that.
>
> Since I mention _interface_. I've been thinking about it and I would
> prefer it if the _immutable_ modifier also works for interfaces.
> Interfaces are pure abstract classes after all and they are meant to
> define a contract for implementors. I cannot see any good reason why it
> should not be allowed to force implementors of an interface to be
> immutable; same as with abstract classes.
>
> Another aspect that we should discuss is how immutable properties should
> behave in case we decide for CoW.
>
> @Larry what do you think about the CoW proposal?
>
> --
> Richard "Fleshgrinder" Fussenegger
>
>


Re: [PHP-DEV] RFC - Immutable classes

2016-09-10 Thread Fleshgrinder
So? Where are we now? CoW is definitely doable and I personally think
that it's the best approach because the engine has full control that
nothing goes south. I also do not think that it's magic in any way since
developers have to add the _immutable_ keyword explicitly to the class.
That this modifier modifies the behavior should be obvious, _abstract_
and _interface_ also do that.

Since I mention _interface_. I've been thinking about it and I would
prefer it if the _immutable_ modifier also works for interfaces.
Interfaces are pure abstract classes after all and they are meant to
define a contract for implementors. I cannot see any good reason why it
should not be allowed to force implementors of an interface to be
immutable; same as with abstract classes.

Another aspect that we should discuss is how immutable properties should
behave in case we decide for CoW.

@Larry what do you think about the CoW proposal?

-- 
Richard "Fleshgrinder" Fussenegger



signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] RFC - Immutable classes

2016-09-09 Thread Silvio Marijić
@Fleshgrinder,

Well since implementation is still underway I think the best ways would be
to wait untill we finish implementation, and then we all can do the review
to make sure everything is in place.

2016-09-09 23:16 GMT+02:00 Fleshgrinder :

> On 9/9/2016 10:02 PM, Silvio Marijić wrote:
> > It will be patched before this RFC goes into official discussion.
> >
>
> That explains why all the rewritten tests I provided for Reflection fail:
>
> https://github.com/brzuchal/php-src/pull/1
>
> Should I create this PR against another repository? I created it against
> the one that was last posted for review but no clue which would be right
> one to contribute here?!?
>
> --
> Richard "Fleshgrinder" Fussenegger
>
>


-- 
Silvio Marijić
Software Engineer
2e Systems


Re: [PHP-DEV] RFC - Immutable classes

2016-09-09 Thread Fleshgrinder
On 9/9/2016 10:02 PM, Silvio Marijić wrote:
> It will be patched before this RFC goes into official discussion.
> 

That explains why all the rewritten tests I provided for Reflection fail:

https://github.com/brzuchal/php-src/pull/1

Should I create this PR against another repository? I created it against
the one that was last posted for review but no clue which would be right
one to contribute here?!?

-- 
Richard "Fleshgrinder" Fussenegger



signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] RFC - Immutable classes

2016-09-09 Thread Silvio Marijić
It will be patched before this RFC goes into official discussion.

2016-09-09 22:01 GMT+02:00 Silvio Marijić :

> @Fred
>
> Thanks for taking interest. I still need to fully patch reflection
> extension for this. We had more important discussions in the past two weeks.
>
> Cheers,
> Silvio
>
> 2016-09-09 21:46 GMT+02:00 Fred Emmott :
>
>> I see Reflection is still todo;  should there be a similar escape hatch
>> to ReflectionMethod::setAccessible()?
>>
>> This would allow things like: https://gist.github.com/
>> fredemmott/01ad55c0c03c8d7ba62bbd6e9fb23686 (apologies for the hack-like
>> syntax) - the ‘every property must be a constructor parameter’ approach in
>> the RFC seems like it would rapidly become unwieldy for classes with a
>> large number of properties.
>>
>> Regards,
>>  - Fred
>>
>>
>> On Aug 8, 2016, at 3:31 AM, Silvio Marijić 
>> wrote:
>>
>>
>> Hi,
>>
>> I would need your help with one idea. I'm working on one RFC that I'm
>> would
>> like to submit. Idea is that after you initialize object eg. after
>> constructor returns, object would be locked, and you wouldn't be able to
>> change properties on that object anymore. It would like this:
>>
>> >
>> immutable class Email {
>>
>> public $email;
>> public function __construct($email){
>> $this->email = $email;
>> }
>> }
>> $email = new Email("exam...@email.com");
>>
>>
>>
>>
>> After instance of class is created, object is "frozen" so call like this
>>
>> $email->email = "n...@email.com";
>>
>>
>> Would result in error.
>>
>> I have already implementation up to certain degree, but I need one advice
>> from more experienced developers. Where is the place where I could put
>> logic to lock object after the constructor has finished? Maybe in zend vm
>> on ZEND_NEW token?
>>
>> Some constraints are needed:
>>
>>   1. Child class that extends immutable class must be defined as immutable
>>   also.
>>   2. If property on immutable class contains object, it must be instance
>>   of immutable class.
>>   3. You can not have immutability per property, it either whole class or
>>   none.
>>
>> Thank you all in advance.
>>
>> --
>> Silvio Marijić
>> Software Engineer
>> 2e Systems
>>
>>
>>
>
>
> --
> Silvio Marijić
> Software Engineer
> 2e Systems
>



-- 
Silvio Marijić
Software Engineer
2e Systems


Re: [PHP-DEV] RFC - Immutable classes

2016-09-09 Thread Silvio Marijić
@Fred

Thanks for taking interest. I still need to fully patch reflection
extension for this. We had more important discussions in the past two weeks.

Cheers,
Silvio

2016-09-09 21:46 GMT+02:00 Fred Emmott :

> I see Reflection is still todo;  should there be a similar escape hatch to
> ReflectionMethod::setAccessible()?
>
> This would allow things like: https://gist.github.com/fredemmott/
> 01ad55c0c03c8d7ba62bbd6e9fb23686 (apologies for the hack-like syntax) -
> the ‘every property must be a constructor parameter’ approach in the RFC
> seems like it would rapidly become unwieldy for classes with a large number
> of properties.
>
> Regards,
>  - Fred
>
>
> On Aug 8, 2016, at 3:31 AM, Silvio Marijić 
> wrote:
>
>
> Hi,
>
> I would need your help with one idea. I'm working on one RFC that I'm would
> like to submit. Idea is that after you initialize object eg. after
> constructor returns, object would be locked, and you wouldn't be able to
> change properties on that object anymore. It would like this:
>
> 
> immutable class Email {
>
> public $email;
> public function __construct($email){
> $this->email = $email;
> }
> }
> $email = new Email("exam...@email.com");
>
>
>
>
> After instance of class is created, object is "frozen" so call like this
>
> $email->email = "n...@email.com";
>
>
> Would result in error.
>
> I have already implementation up to certain degree, but I need one advice
> from more experienced developers. Where is the place where I could put
> logic to lock object after the constructor has finished? Maybe in zend vm
> on ZEND_NEW token?
>
> Some constraints are needed:
>
>   1. Child class that extends immutable class must be defined as immutable
>   also.
>   2. If property on immutable class contains object, it must be instance
>   of immutable class.
>   3. You can not have immutability per property, it either whole class or
>   none.
>
> Thank you all in advance.
>
> --
> Silvio Marijić
> Software Engineer
> 2e Systems
>
>
>


-- 
Silvio Marijić
Software Engineer
2e Systems


Re: [PHP-DEV] RFC - Immutable classes

2016-09-09 Thread Fred Emmott
I see Reflection is still todo;  should there be a similar escape hatch to 
ReflectionMethod::setAccessible()?

This would allow things like: 
https://gist.github.com/fredemmott/01ad55c0c03c8d7ba62bbd6e9fb23686 
 
(apologies for the hack-like syntax) - the ‘every property must be a 
constructor parameter’ approach in the RFC seems like it would rapidly become 
unwieldy for classes with a large number of properties.

Regards,
 - Fred
 

On Aug 8, 2016, at 3:31 AM, Silvio Marijić  wrote:
> 
> Hi,
> 
> I would need your help with one idea. I'm working on one RFC that I'm would
> like to submit. Idea is that after you initialize object eg. after
> constructor returns, object would be locked, and you wouldn't be able to
> change properties on that object anymore. It would like this:
> 
>  
> immutable class Email {
>> public $email;
>> public function __construct($email){
>> $this->email = $email;
>> }
>> }
>> $email = new Email("exam...@email.com");
> 
> 
> 
> After instance of class is created, object is "frozen" so call like this
> 
> $email->email = "n...@email.com";
> 
> 
> Would result in error.
> 
> I have already implementation up to certain degree, but I need one advice
> from more experienced developers. Where is the place where I could put
> logic to lock object after the constructor has finished? Maybe in zend vm
> on ZEND_NEW token?
> 
> Some constraints are needed:
> 
>   1. Child class that extends immutable class must be defined as immutable
>   also.
>   2. If property on immutable class contains object, it must be instance
>   of immutable class.
>   3. You can not have immutability per property, it either whole class or
>   none.
> 
> Thank you all in advance.
> 
> -- 
> Silvio Marijić
> Software Engineer
> 2e Systems



Re: [PHP-DEV] RFC - Immutable classes

2016-09-08 Thread Christoph M. Becker
On 08.09.2016 at 09:41, Silvio Marijić wrote:

> I get the nostalgia :)
> I think that *zend_compare_symbol_tables* compares only hash tables whether
> they contain same properties regardless of the values.

What I wanted to show was that PHP 4 objects implemented copy-on-write
semantics; the test script doesn't show that, because `===` triggers a
value comparision in PHP 4 (didn't know that).

However,  shows that we had copy-on-write for
PHP 4 objects.

Cheers!

> 2016-09-07 20:44 GMT+02:00 Silvio Marijić :
> 
>> @Fleshgrinder
>>
>> I will make changes that if immutable objects are being compared that they
>> will be compared by value rather then hash
>> On Sep 7, 2016 8:27 PM, "Christoph M. Becker"  wrote:
>>
>>> On 07.09.2016 at 20:11, Fleshgrinder wrote:
>>>
 On 9/7/2016 8:57 AM, Michał Brzuchalski wrote:

> AFAIK CoW in case of objects would be impossible to implement.

 Nothing is impossible. :)

 We have full access to the real object inside of zend_std_write_property
 and can easily clone it, perform the desired changes and return without
 affecting anyone.

 I am not 100% sure how to do this without fiddling around a bit.

 @nikic and @afaults: I am really sorry to bother you both but you guys
 simply know the PHP source endlessly good. What do you think, would it
 be possible to implement copy-on-write for an object as we have it with
 our scalar and compound types?

 final class A {
   public $p;
 }

 $a = new A;
 $b = $a;

 var_dump($a === $b); // bool(true)

 $b->p = 1;

 var_dump($a === $b); // bool(false)

 It's only about writing to existing properties.
>>>
>>> Ah, good old PHP 4, see . :-)

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] RFC - Immutable classes

2016-09-08 Thread Silvio Marijić
@Christoph

I get the nostalgia :)
I think that *zend_compare_symbol_tables* compares only hash tables whether
they contain same properties regardless of the values.

2016-09-07 20:44 GMT+02:00 Silvio Marijić :

> @Fleshgrinder
>
> I will make changes that if immutable objects are being compared that they
> will be compared by value rather then hash
> On Sep 7, 2016 8:27 PM, "Christoph M. Becker"  wrote:
>
>> On 07.09.2016 at 20:11, Fleshgrinder wrote:
>>
>> > On 9/7/2016 8:57 AM, Michał Brzuchalski wrote:
>> >
>> >> AFAIK CoW in case of objects would be impossible to implement.
>> >
>> > Nothing is impossible. :)
>> >
>> > We have full access to the real object inside of zend_std_write_property
>> > and can easily clone it, perform the desired changes and return without
>> > affecting anyone.
>> >
>> > I am not 100% sure how to do this without fiddling around a bit.
>> >
>> > @nikic and @afaults: I am really sorry to bother you both but you guys
>> > simply know the PHP source endlessly good. What do you think, would it
>> > be possible to implement copy-on-write for an object as we have it with
>> > our scalar and compound types?
>> >
>> > final class A {
>> >   public $p;
>> > }
>> >
>> > $a = new A;
>> > $b = $a;
>> >
>> > var_dump($a === $b); // bool(true)
>> >
>> > $b->p = 1;
>> >
>> > var_dump($a === $b); // bool(false)
>> >
>> > It's only about writing to existing properties.
>>
>> Ah, good old PHP 4, see . :-)
>>
>> --
>> Christoph M. Becker
>>
>>


-- 
Silvio Marijić
Software Engineer
2e Systems


Re: [PHP-DEV] RFC - Immutable classes

2016-09-07 Thread Silvio Marijić
@Fleshgrinder

I will make changes that if immutable objects are being compared that they
will be compared by value rather then hash
On Sep 7, 2016 8:27 PM, "Christoph M. Becker"  wrote:

> On 07.09.2016 at 20:11, Fleshgrinder wrote:
>
> > On 9/7/2016 8:57 AM, Michał Brzuchalski wrote:
> >
> >> AFAIK CoW in case of objects would be impossible to implement.
> >
> > Nothing is impossible. :)
> >
> > We have full access to the real object inside of zend_std_write_property
> > and can easily clone it, perform the desired changes and return without
> > affecting anyone.
> >
> > I am not 100% sure how to do this without fiddling around a bit.
> >
> > @nikic and @afaults: I am really sorry to bother you both but you guys
> > simply know the PHP source endlessly good. What do you think, would it
> > be possible to implement copy-on-write for an object as we have it with
> > our scalar and compound types?
> >
> > final class A {
> >   public $p;
> > }
> >
> > $a = new A;
> > $b = $a;
> >
> > var_dump($a === $b); // bool(true)
> >
> > $b->p = 1;
> >
> > var_dump($a === $b); // bool(false)
> >
> > It's only about writing to existing properties.
>
> Ah, good old PHP 4, see . :-)
>
> --
> Christoph M. Becker
>
>


Re: [PHP-DEV] RFC - Immutable classes

2016-09-07 Thread Christoph M. Becker
On 07.09.2016 at 20:11, Fleshgrinder wrote:

> On 9/7/2016 8:57 AM, Michał Brzuchalski wrote:
>
>> AFAIK CoW in case of objects would be impossible to implement.
> 
> Nothing is impossible. :)
> 
> We have full access to the real object inside of zend_std_write_property
> and can easily clone it, perform the desired changes and return without
> affecting anyone.
> 
> I am not 100% sure how to do this without fiddling around a bit.
> 
> @nikic and @afaults: I am really sorry to bother you both but you guys
> simply know the PHP source endlessly good. What do you think, would it
> be possible to implement copy-on-write for an object as we have it with
> our scalar and compound types?
> 
> final class A {
>   public $p;
> }
> 
> $a = new A;
> $b = $a;
> 
> var_dump($a === $b); // bool(true)
> 
> $b->p = 1;
> 
> var_dump($a === $b); // bool(false)
> 
> It's only about writing to existing properties.

Ah, good old PHP 4, see . :-)

-- 
Christoph M. Becker


-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] RFC - Immutable classes

2016-09-07 Thread Fleshgrinder
First a general comment on cloning.

Nothing bad happens if we allow cloning other than a performance hit.
But only if we ensure that immutable objects are identified by value and
not by the usual object hash. In case of the latter, as it is
implemented right now, you end up with an exact copy but different, due
to the usual object hash.

Now this might not be as bad as it sounds but it kind of makes the hole
point of having immutable value objects less useful. And heck, we want a
proper implementation of this.

Hence, even if we allow cloning, at least an E_INFO should be emitted if
done so in order to be able to spot those useless cloning operations in
your code easily.

Note that changing an existing class to an immutable class is always a
breaking change, no matter what. Simply because you do not know what the
libraries and applications that depend on your library are doing with
that class right now. ;)

All of this are reasons why I generally make the __clone callback of my
value objects private or protected. It ensures that nobody is able to
clone them without running into problems. It's all about encapsulation
and only providing the behavior for the objects that is required.

I am and will be a strong proponent of disallowing cloning on immutable
objects. There is not a single argument why this should work.

On 9/7/2016 8:57 AM, Michał Brzuchalski wrote:
> AFAIK CoW in case of objects would be impossible to implement.
> 

Nothing is impossible. :)

We have full access to the real object inside of zend_std_write_property
and can easily clone it, perform the desired changes and return without
affecting anyone.

I am not 100% sure how to do this without fiddling around a bit.

@nikic and @afaults: I am really sorry to bother you both but you guys
simply know the PHP source endlessly good. What do you think, would it
be possible to implement copy-on-write for an object as we have it with
our scalar and compound types?

final class A {
  public $p;
}

$a = new A;
$b = $a;

var_dump($a === $b); // bool(true)

$b->p = 1;

var_dump($a === $b); // bool(false)

It's only about writing to existing properties.

-- 
Richard "Fleshgrinder" Fussenegger



signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] RFC - Immutable classes

2016-09-07 Thread Silvio Marijić
@Lester

I might have expressed my self in a wrong way, there is not wrong with
encapsulation. Thing is that there is no proper support and unified
solution from the language. There are much examples of real world cases
where this can be useful. I understand that same behaviour can be achieved
on multiple different ways without moving that to the language it's self,
that is not a question at all. As I said in RFC, goal is to bring one
solution which can be easily enforced and move that from the the developer
to the language to take care of that.

Cheers

2016-09-07 15:24 GMT+02:00 Mathieu Rochette :

>
>
> On 07/09/2016 15:09, Michał Brzuchalski wrote:
>
>> @Mathieu How about that: https://gist.github.com/brzuch
>> al/e7b721e22a19cca42ec0d1f597a23baf
>> We've discussed this could be best option, when invoking `transformer`
>> method (or whatever we call it)
>> there is `$this = clone $this` invoked under the hood.
>>
> I don't know, it seems a bit strange to override $this . I can't have the
> original object and the new one at the same time.
> Or do you mean I also have the option to do "$clone = clone $this" ?
>
>>
>> 2016-09-07 14:53 GMT+02:00 Mathieu Rochette  math...@rochette.cc>>:
>>
>> a few remarks on mutator methods:
>>
>>   * It could be a nice way to solve the "create another one almost
>> the same" use case.
>>   * I don't mind if $clone is an explicit parameter or magically
>> available
>>   * what happens if I call other function/methods with this $clone
>> before the end of the function ?
>>   * and the only downside: I have to make a method just for
>>
>> cloning. that means I have to call a mutator multiple times if
>> I want to make a bunch of clone, eg:
>>
>> because of the last point, I think I'd like the seal the clone at
>> then end of the block/method better, here are 2 examples to
>> illustrate what I mean
>>
>> class immutable foo {
>>   private $prop = 0;
>>
>>   public function __construct($v) {$this->prop = $v;}
>>
>>   public function bar(obj $o) {
>> $e->makeSomethingWith($this->cloneAndEdit(42));
>>   }
>>
>>   public function many($n) {
>> $a = [];
>> for ($i = 0; $i < $n; $i++) {
>>   $a[] = $this->cloneAndEdit($i));
>> }
>> return $a;
>>
>>   }
>>
>>   public function mut cloneAndEdit($n) {
>> $clone->prop = $n;
>>   }
>> }
>>
>> // vs
>>
>> class immutable foo {
>>   private $prop = 0;
>>
>>   public function __construct($v) {$this->prop = $v;}
>>
>>   public function bar(obj $o) {
>> $c = $clone $this;
>> $c->prop = 42;
>> $e->makeSomethingWith($c);
>>   }
>>
>>   public function many($n) {
>> $a = [];
>> for ($i = 0; $i < $n; $i++) {
>> $a[] = $c = $clone $this;
>>   $c->prop = 42;
>> }
>> return $a;
>>   }
>> }
>>
>> I understand that it's still not clear exactly when the object
>> should be sealed but if it can works this one would have my preference
>>
>> On 04/09/2016 14:10, Michał Brzuchalski wrote:
>>
>>> 2016-09-04 10:55 GMT+02:00 Fleshgrinder
>>> :
>>>
>>>
>>> Hi Chris!

 On 9/3/2016 5:00 PM, Chris Riley wrote:

> - Properties can be declared immutable. Immutable properties may
> only be
> changed under two circumstances: a) In the objects constructor b)
> If they
> are null (This enables setter injection if required)
>
> The constraint b) would make the object mutable and defeat the
 purpose
 of the immutable modifier since any property could change at any
 time if
 it was NULL at the beginning. Requiring syncing in concurrent
 environments.

 On 9/3/2016 5:00 PM, Chris Riley wrote:

> - Arrays assigned to immutable properties would not be possible to
> change
>
> Array support would definitely be very nice. I mean, we have
 constant
 arrays already, hence, it is possible.

 On 9/3/2016 5:00 PM, Chris Riley wrote:

> - Objects assigned to immutable properties would be possible to
> change,
>
 so

> long as the same object remained assigned to the property.
>
> This would once more lead to mutability and the constraint of
 immutability would be violated.

 On 9/3/2016 5:00 PM, Chris Riley wrote:

>  From a developer adoption point of view, I think these two points
> are
> important to making immutable classes generally useful. Without 1,
> it
>
 will

> be a nuisance to use 3rd party libraries esp those which retain
> compatibility for PHP < 7.2. Without 2 you block the ability to use
>
 

Re: [PHP-DEV] RFC - Immutable classes

2016-09-07 Thread Mathieu Rochette



On 07/09/2016 15:09, Michał Brzuchalski wrote:
@Mathieu How about that: 
https://gist.github.com/brzuchal/e7b721e22a19cca42ec0d1f597a23baf
We've discussed this could be best option, when invoking `transformer` 
method (or whatever we call it)

there is `$this = clone $this` invoked under the hood.
I don't know, it seems a bit strange to override $this . I can't have 
the original object and the new one at the same time.

Or do you mean I also have the option to do "$clone = clone $this" ?


2016-09-07 14:53 GMT+02:00 Mathieu Rochette >:


a few remarks on mutator methods:

  * It could be a nice way to solve the "create another one almost
the same" use case.
  * I don't mind if $clone is an explicit parameter or magically
available
  * what happens if I call other function/methods with this $clone
before the end of the function ?
  * and the only downside: I have to make a method just for
cloning. that means I have to call a mutator multiple times if
I want to make a bunch of clone, eg:

because of the last point, I think I'd like the seal the clone at
then end of the block/method better, here are 2 examples to
illustrate what I mean

class immutable foo {
  private $prop = 0;

  public function __construct($v) {$this->prop = $v;}

  public function bar(obj $o) {
$e->makeSomethingWith($this->cloneAndEdit(42));
  }

  public function many($n) {
$a = [];
for ($i = 0; $i < $n; $i++) {
  $a[] = $this->cloneAndEdit($i));
}
return $a;

  }

  public function mut cloneAndEdit($n) {
$clone->prop = $n;
  }
}

// vs

class immutable foo {
  private $prop = 0;

  public function __construct($v) {$this->prop = $v;}

  public function bar(obj $o) {
$c = $clone $this;
$c->prop = 42;
$e->makeSomethingWith($c);
  }

  public function many($n) {
$a = [];
for ($i = 0; $i < $n; $i++) {
$a[] = $c = $clone $this;
  $c->prop = 42;
}
return $a;
  }
}

I understand that it's still not clear exactly when the object
should be sealed but if it can works this one would have my preference

On 04/09/2016 14:10, Michał Brzuchalski wrote:

2016-09-04 10:55 GMT+02:00 Fleshgrinder 
:


Hi Chris!

On 9/3/2016 5:00 PM, Chris Riley wrote:

- Properties can be declared immutable. Immutable properties may only be
changed under two circumstances: a) In the objects constructor b) If they
are null (This enables setter injection if required)


The constraint b) would make the object mutable and defeat the purpose
of the immutable modifier since any property could change at any time if
it was NULL at the beginning. Requiring syncing in concurrent environments.

On 9/3/2016 5:00 PM, Chris Riley wrote:

- Arrays assigned to immutable properties would not be possible to change


Array support would definitely be very nice. I mean, we have constant
arrays already, hence, it is possible.

On 9/3/2016 5:00 PM, Chris Riley wrote:

- Objects assigned to immutable properties would be possible to change,

so

long as the same object remained assigned to the property.


This would once more lead to mutability and the constraint of
immutability would be violated.

On 9/3/2016 5:00 PM, Chris Riley wrote:

 From a developer adoption point of view, I think these two points are
important to making immutable classes generally useful. Without 1, it

will

be a nuisance to use 3rd party libraries esp those which retain
compatibility for PHP < 7.2. Without 2 you block the ability to use

setter

injection, which I personally would be in favour of if it meant that devs
stopped using it - it wouldn't - they would simply not use immutable
classes, loosing the benefits thereof.


The adoption of the feature will be halted until 7.2 is widely available
in bigger projects. That is most certainly right. However, we should aim
for the best, most useful, and future proof solution and not towards the
one that's adopted very fast but lacks some important constraints.
Having truly immutable objects is required in concurrent scenarios and
such scenarios are in the future for PHP and not in the past.

Regarding setter injection: I do not see the need for it at all in the
context of immutable objects. In the end we are talking about value
objects here and they should not have any optional dependencies. Maybe
you could come up with a use case to illustrate the need?

On 9/3/2016 5:00 PM, Chris Riley wrote:

Dealing with the clone issue some of my ideas since then were:

- Seal/Unseal (As per Larry's suggestion)
- Parameters to 

Re: [PHP-DEV] RFC - Immutable classes

2016-09-07 Thread Lester Caine
On 07/09/16 10:28, Silvio Marijić wrote:
> DateTimeImmutable does not prevent cloning because immutability is achieved
> by encapsulation, and we want to get rid of the need of encapsulation in
> our implementation of immutable objects.

What is the problem with 'encapsulation'? By that I mean creating
readonly result set from class and packaging it with just the links to
the functions that display those results. Nothing stopping the class
building multiple objects, and the construction code is unnecessary once
the target has been created. Simplifying access to the set of variables
making up the object might help with all the different options for
getters and the like, but essentially the object is just a set of
variables which build a result which may potentially just be a
pre-formatted string or a number. In my book date/time is still a 32bit
day count and 32bit time fraction so a DateTimeImmutable is just a 64bit
number ... which you can't write to.

-- 
Lester Caine - G8HFL
-
Contact - http://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk
Rainbow Digital Media - http://rainbowdigitalmedia.co.uk

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] RFC - Immutable classes

2016-09-07 Thread Michał Brzuchalski
@Mathieu How about that:
https://gist.github.com/brzuchal/e7b721e22a19cca42ec0d1f597a23baf
We've discussed this could be best option, when invoking `transformer`
method (or whatever we call it)
there is `$this = clone $this` invoked under the hood.

2016-09-07 14:53 GMT+02:00 Mathieu Rochette :

> a few remarks on mutator methods:
>
>- It could be a nice way to solve the "create another one almost the
>same" use case.
>- I don't mind if $clone is an explicit parameter or magically
>available
>- what happens if I call other function/methods with this $clone
>before the end of the function ?
>- and the only downside: I have to make a method just for cloning.
>that means I have to call a mutator multiple times if I want to make a
>bunch of clone, eg:
>
> because of the last point, I think I'd like the seal the clone at then end
> of the block/method better, here are 2 examples to illustrate what I mean
> class immutable foo {
>   private $prop = 0;
>
>   public function __construct($v) {$this->prop = $v;}
>
>   public function bar(obj $o) {
> $e->makeSomethingWith($this->cloneAndEdit(42));
>   }
>
>   public function many($n) {
> $a = [];
> for ($i = 0; $i < $n; $i++) {
>   $a[] = $this->cloneAndEdit($i));
> }
> return $a;
>
>   }
>
>   public function mut cloneAndEdit($n) {
> $clone->prop = $n;
>   }
> }
>
> // vs
>
> class immutable foo {
>   private $prop = 0;
>
>   public function __construct($v) {$this->prop = $v;}
>
>   public function bar(obj $o) {
> $c = $clone $this;
> $c->prop = 42;
> $e->makeSomethingWith($c);
>   }
>
>   public function many($n) {
> $a = [];
> for ($i = 0; $i < $n; $i++) {
>   $a[] = $c = $clone $this;
>   $c->prop = 42;
> }
> return $a;
>   }
> }
>
> I understand that it's still not clear exactly when the object should be
> sealed but if it can works this one would have my preference
> On 04/09/2016 14:10, Michał Brzuchalski wrote:
>
> 2016-09-04 10:55 GMT+02:00 Fleshgrinder  
> :
>
>
> Hi Chris!
>
> On 9/3/2016 5:00 PM, Chris Riley wrote:
>
> - Properties can be declared immutable. Immutable properties may only be
> changed under two circumstances: a) In the objects constructor b) If they
> are null (This enables setter injection if required)
>
>
> The constraint b) would make the object mutable and defeat the purpose
> of the immutable modifier since any property could change at any time if
> it was NULL at the beginning. Requiring syncing in concurrent environments.
>
> On 9/3/2016 5:00 PM, Chris Riley wrote:
>
> - Arrays assigned to immutable properties would not be possible to change
>
>
> Array support would definitely be very nice. I mean, we have constant
> arrays already, hence, it is possible.
>
> On 9/3/2016 5:00 PM, Chris Riley wrote:
>
> - Objects assigned to immutable properties would be possible to change,
>
> so
>
> long as the same object remained assigned to the property.
>
>
> This would once more lead to mutability and the constraint of
> immutability would be violated.
>
> On 9/3/2016 5:00 PM, Chris Riley wrote:
>
> From a developer adoption point of view, I think these two points are
> important to making immutable classes generally useful. Without 1, it
>
> will
>
> be a nuisance to use 3rd party libraries esp those which retain
> compatibility for PHP < 7.2. Without 2 you block the ability to use
>
> setter
>
> injection, which I personally would be in favour of if it meant that devs
> stopped using it - it wouldn't - they would simply not use immutable
> classes, loosing the benefits thereof.
>
>
> The adoption of the feature will be halted until 7.2 is widely available
> in bigger projects. That is most certainly right. However, we should aim
> for the best, most useful, and future proof solution and not towards the
> one that's adopted very fast but lacks some important constraints.
> Having truly immutable objects is required in concurrent scenarios and
> such scenarios are in the future for PHP and not in the past.
>
> Regarding setter injection: I do not see the need for it at all in the
> context of immutable objects. In the end we are talking about value
> objects here and they should not have any optional dependencies. Maybe
> you could come up with a use case to illustrate the need?
>
> On 9/3/2016 5:00 PM, Chris Riley wrote:
>
> Dealing with the clone issue some of my ideas since then were:
>
> - Seal/Unseal (As per Larry's suggestion)
> - Parameters to __clone; in this instance the clone method would be
>
> allowed
>
> to change properties of the object as well as the constructor. This feels
> like it may breach the principal of least surprise as cloning an object
>
> no
>
> longer guarantees an exact copy.
> - A new magic method __mutate($property, $newvalue) called instead of a
> fatal error when a property is changed. This probably lays too many traps
> for developers for it 

Re: [PHP-DEV] RFC - Immutable classes

2016-09-07 Thread Mathieu Rochette

a few remarks on mutator methods:

 * It could be a nice way to solve the "create another one almost the
   same" use case.
 * I don't mind if $clone is an explicit parameter or magically available
 * what happens if I call other function/methods with this $clone
   before the end of the function ?
 * and the only downside: I have to make a method just for cloning.
   that means I have to call a mutator multiple times if I want to make
   a bunch of clone, eg:

because of the last point, I think I'd like the seal the clone at then 
end of the block/method better, here are 2 examples to illustrate what I 
mean


class immutable foo {
  private $prop = 0;

  public function __construct($v) {$this->prop = $v;}

  public function bar(obj $o) {
$e->makeSomethingWith($this->cloneAndEdit(42));
  }

  public function many($n) {
$a = [];
for ($i = 0; $i < $n; $i++) {
  $a[] = $this->cloneAndEdit($i));
}
return $a;

  }

  public function mut cloneAndEdit($n) {
$clone->prop = $n;
  }
}

// vs

class immutable foo {
  private $prop = 0;

  public function __construct($v) {$this->prop = $v;}

  public function bar(obj $o) {
$c = $clone $this;
$c->prop = 42;
$e->makeSomethingWith($c);
  }

  public function many($n) {
$a = [];
for ($i = 0; $i < $n; $i++) {
$a[] = $c = $clone $this;
  $c->prop = 42;
}
return $a;
  }
}

I understand that it's still not clear exactly when the object should be 
sealed but if it can works this one would have my preference


On 04/09/2016 14:10, Michał Brzuchalski wrote:

2016-09-04 10:55 GMT+02:00 Fleshgrinder :


Hi Chris!

On 9/3/2016 5:00 PM, Chris Riley wrote:

- Properties can be declared immutable. Immutable properties may only be
changed under two circumstances: a) In the objects constructor b) If they
are null (This enables setter injection if required)


The constraint b) would make the object mutable and defeat the purpose
of the immutable modifier since any property could change at any time if
it was NULL at the beginning. Requiring syncing in concurrent environments.

On 9/3/2016 5:00 PM, Chris Riley wrote:

- Arrays assigned to immutable properties would not be possible to change


Array support would definitely be very nice. I mean, we have constant
arrays already, hence, it is possible.

On 9/3/2016 5:00 PM, Chris Riley wrote:

- Objects assigned to immutable properties would be possible to change,

so

long as the same object remained assigned to the property.


This would once more lead to mutability and the constraint of
immutability would be violated.

On 9/3/2016 5:00 PM, Chris Riley wrote:

 From a developer adoption point of view, I think these two points are
important to making immutable classes generally useful. Without 1, it

will

be a nuisance to use 3rd party libraries esp those which retain
compatibility for PHP < 7.2. Without 2 you block the ability to use

setter

injection, which I personally would be in favour of if it meant that devs
stopped using it - it wouldn't - they would simply not use immutable
classes, loosing the benefits thereof.


The adoption of the feature will be halted until 7.2 is widely available
in bigger projects. That is most certainly right. However, we should aim
for the best, most useful, and future proof solution and not towards the
one that's adopted very fast but lacks some important constraints.
Having truly immutable objects is required in concurrent scenarios and
such scenarios are in the future for PHP and not in the past.

Regarding setter injection: I do not see the need for it at all in the
context of immutable objects. In the end we are talking about value
objects here and they should not have any optional dependencies. Maybe
you could come up with a use case to illustrate the need?

On 9/3/2016 5:00 PM, Chris Riley wrote:

Dealing with the clone issue some of my ideas since then were:

- Seal/Unseal (As per Larry's suggestion)
- Parameters to __clone; in this instance the clone method would be

allowed

to change properties of the object as well as the constructor. This feels
like it may breach the principal of least surprise as cloning an object

no

longer guarantees an exact copy.
- A new magic method __mutate($property, $newvalue) called instead of a
fatal error when a property is changed. This probably lays too many traps
for developers for it to be a good idea.
- Implicitly returning a new object whenever a property is changed.

Similar

reservations to the above.
- A new magic method __with($newInstance, $args) and a keyword with that

is

used in place of clone eg $x = $y with ($arg1, $arg2); in this instance,
__with receives a clone of $y (after calling __clone) and an array

[$arg1,

$arg2] the with magic method is allowed to mutate $newInstance and must
return it. This is currently my favoured solution


How does one know which property is to be mutated in the __with method?
You should also not underestimate the performance hit 

Re: [PHP-DEV] RFC - Immutable classes

2016-09-07 Thread Stephen Reay
Well crap I just realised I hadn’t hit reply-all several replies ago!.

I also just noticed that you had mentioned about allowing property writes only 
in __construct and __clone last week, and asked about how it might look. I 
wasn’t subscribed then so I didn’t see the earlier discussions.

I’ll go back and read through the earlier discussions, I don’t want to rehash 
what’s already been suggested and discarded due to impracticality.



> On 7 Sep 2016, at 19:04, Stephen Reay  wrote:
> 
> Right, but thats just because ($object) is a statement that evaluates to 
> $object and clone is a language construct, isn’t it? I don’t think I’ve ever 
> seen clone($object) used in the wild.
> 
> What do you think about having the change assignment(s) be handled by 
> __clone() (perhaps with a $changes array as its argument?), so the developer 
> still has control over how/what things are set, as they do in __construct.
> I fear that having the properties set by the clone operation is one step too 
> much into the ‘it happens by magic’ direction - PHP doesn't auto-set 
> properties passed to a constructor, so why here?
> 
> 
> 
>> On 7 Sep 2016, at 18:50, Silvio Marijić > > wrote:
>> 
>> Well it's not new, both clone $object and clone($object) are valid 
>> statements in PHP at the moment. But yes, you are close, in my opinion 
>> constructor and clone are the points where object can be modified.
>> Syntax can be discussed. But we should try to have minimal impact as 
>> possible on the syntax.
>> 
>> 2016-09-07 13:37 GMT+02:00 Stephen Reay > >:
>> OK. I could live with a concept where the object is only modifiable as part 
>> of the clone operation, but Im not mad about that syntax.
>> 
>> Are you proposing that clone($object, array $changes) is a new builtin 
>> function/language construct, and it does the actual property writes? In this 
>> situation, would it be safe to say that only the constructor (and 
>> destructor? e.g. imagine closing a resource handle in a destructor) can make 
>> changes to class properties?
>> 
>> Could that be achieved with syntax closer to what we use now? `clone $this 
>> use ($foo, $bar, $baz);` or similar?
>> 
>> 
>> 
>>> On 7 Sep 2016, at 18:19, Silvio Marijić >> > wrote:
>>> 
>>> I've forgot return in addItem() but you get the idea
>>> 
>>> 2016-09-07 13:19 GMT+02:00 Silvio Marijić >> >:
>>> Hi Stephen,
>>> 
>>> Well in your example it would look like this:
>>> 
>>> immutable class ValueObject {
>>>public $values = [];
>>>public function __construct($value) {
>>>   array_push($this->values, $value);
>>>}
>>> 
>>> public function addItem($value){
>>>  $values = $this->values;
>>>  array_push($values, $value);
>>> 
>>>  $cloned = clone($this, ['values' => $values]
>>> }
>>> }
>>> 
>>> $vo = new ValueObject(1);
>>> $newVo = $vo->addItem(2);
>>> 
>>> 
>>> 
>>> On Sep 7, 2016 12:52 PM, "Stephen Reay" >> > wrote:
>>> Hi Silvio,
>>> 
>>> Can you give an example of what you mean about passing properties that are 
>>> changing?
>>> 
>>> Also, how would this affect e.g. an object that has objects or arrays as 
>>> members.
>>> 
>>> It’s not always going to be just `$clone = clone $this; $clone->foo = 
>>> $foo;` - you could be adding/appending/removing array/object members too.
>>> 
>>> Cheers
>>> 
>>> Stephen
>>> 
 On 7 Sep 2016, at 17:43, Silvio Marijić > wrote:
 
 @Stephan
 
 I am against that any kind of method can make modification on original 
 object.
 
 Cloning can be allowed but for this use case where you would pass 
 properties that are changing, we would have to modify syntax of clone
 
 On Sep 7, 2016 12:37 PM, "Stephen Reay" > wrote:
 Hey Matheiu, Silvio,
 
 That is my main concern with the inability to clone from outside the 
 class. I don’t think immutable should cause an error in this situation - 
 if you really don’t want to allow users to create objects they can’t 
 modify (which I understand) could clone on an immutable object from 
 outside the class, simply return the object itself ?
 
 Re: immutable only externally - yes, as I mentioned I can understand that 
 would be a deal-break for some. In that situation, I’d be happy with some 
 way to indicate that a method can make changes. Would this then mean that 
 such a method could modify the object itself, rather than the clone?
 
 Cheers
 
 Stephen
 
 > On 7 Sep 2016, at 17:09, Mathieu Rochette  

Re: [PHP-DEV] RFC - Immutable classes

2016-09-07 Thread Silvio Marijić
Ok, I have some time also so we can together try to write some initial
implementation of that.

2016-09-07 14:10 GMT+02:00 Michał Brzuchalski :

> Silvio,
>
> I can try with it tommorow, we'll see about that.
>
>
> 2016-09-07 14:05 GMT+02:00 Silvio Marijić :
>
>> Michal, how much work do you estimate it would take us to implement
>> method modificator solution?
>>
>> 2016-09-07 14:01 GMT+02:00 Michał Brzuchalski :
>>
>>> Hi,
>>>
>>> Frozing an immutable object after it's creation is most important
>>> feature of Immutable Classes.
>>> Without it you cannot have guarantee it's internal state is consistent
>>> as it was during creation.
>>> Having methods access to write is quite dangerous - think about CLosure
>>> binded to immutable object - there is a way to change internal state of
>>> such object, and you've broken immutability in it.
>>>
>>> Changing object state is reasonable only on clones, because you newer
>>> know what references to original object.
>>> There can be cloning objects as they are now - I don't see it usefull,
>>> but if somebody really want's it, why not.
>>>
>>> IMHO providing method modificator for changing object in context of
>>> newly created clone is the best solution. The keyword for it isn't chosen
>>> yet, we may discuss it or even vote for it. For now we can call it anyway
>>> while keeping in mind it may change during voting.
>>>
>>>
>>>
>>> 2016-09-07 12:43 GMT+02:00 Silvio Marijić :
>>>
 @Stephan

 I am against that any kind of method can make modification on original
 object.

 Cloning can be allowed but for this use case where you would pass
 properties that are changing, we would have to modify syntax of clone
 On Sep 7, 2016 12:37 PM, "Stephen Reay" 
 wrote:

 > Hey Matheiu, Silvio,
 >
 > That is my main concern with the inability to clone from outside the
 > class. I don’t think immutable should cause an error in this
 situation - if
 > you really don’t want to allow users to create objects they can’t
 modify
 > (which I understand) could clone on an immutable object from outside
 the
 > class, simply return the object itself ?
 >
 > Re: immutable only externally - yes, as I mentioned I can understand
 that
 > would be a deal-break for some. In that situation, I’d be happy with
 some
 > way to indicate that a method can make changes. Would this then mean
 that
 > such a method could modify the object itself, rather than the clone?
 >
 > Cheers
 >
 > Stephen
 >
 > > On 7 Sep 2016, at 17:09, Mathieu Rochette 
 wrote:
 > >
 > >
 > >
 > > On 07/09/2016 11:28, Silvio Marijić wrote:
 > >> Hi Stephen,
 > >>
 > >> Cloning is disabled at the moment in implementation because you
 would
 > end
 > >> up with a object that you can not change, so you have no use of
 that.
 > I'll
 > >> change that as soon as we find some good solution for handling
 that.
 > Your
 > >> example is not really clear to me. At what point we should
 unlock/lock
 > >> object based on your example?
 > > what would happen if you tried to clone an immutable object, throw
 an
 > error ?
 > > it means that you might have to use reflection to check if the
 object is
 > immutable before cloning it. otherwise making a class immutable would
 be a
 > BC
 > >>
 > >> DateTimeImmutable does not prevent cloning because immutability is
 > achieved
 > >> by encapsulation, and we want to get rid of the need of
 encapsulation in
 > >> our implementation of immutable objects.
 > >>
 > >> Best,
 > >> Silvio.
 > >>
 > >> 2016-09-07 11:05 GMT+02:00 Stephen Reay :
 > >>
 > >>> (Sorry for any dupes, sent from wrong address originally)
 > >>>
 > >>> From a developer point of view, I would suggest that a feature
 should
 > aim
 > >>> to be as clear to understand with as little “magic" as possible.
 > >>>
 > >>>
 > >>> If the goal of an immutable class is to allow public properties
 to be
 > made
 > >>> read-only, my expectation would be that:
 > >>>
 > >>> - write access to any public property from outside class context,
 is an
 > >>> error.
 > >>>
 > >>> This seems to be pretty much accepted by everyone
 > >>>
 > >>>
 > >>> - clone still works as expected
 > >>>
 > >>> There has been some suggestion that clone $immutableObj should
 not be
 > >>> allowed. Unless there is some specific language/engine gain by
 that,
 > what
 > >>> is the point of having this behaviour?
 > >>> Existing built-in immutable classes (like DateTimeImmutable) do
 not
 

Re: [PHP-DEV] RFC - Immutable classes

2016-09-07 Thread Michał Brzuchalski
Silvio,

I can try with it tommorow, we'll see about that.

2016-09-07 14:05 GMT+02:00 Silvio Marijić :

> Michal, how much work do you estimate it would take us to implement method
> modificator solution?
>
> 2016-09-07 14:01 GMT+02:00 Michał Brzuchalski :
>
>> Hi,
>>
>> Frozing an immutable object after it's creation is most important feature
>> of Immutable Classes.
>> Without it you cannot have guarantee it's internal state is consistent as
>> it was during creation.
>> Having methods access to write is quite dangerous - think about CLosure
>> binded to immutable object - there is a way to change internal state of
>> such object, and you've broken immutability in it.
>>
>> Changing object state is reasonable only on clones, because you newer
>> know what references to original object.
>> There can be cloning objects as they are now - I don't see it usefull,
>> but if somebody really want's it, why not.
>>
>> IMHO providing method modificator for changing object in context of newly
>> created clone is the best solution. The keyword for it isn't chosen yet, we
>> may discuss it or even vote for it. For now we can call it anyway while
>> keeping in mind it may change during voting.
>>
>>
>>
>> 2016-09-07 12:43 GMT+02:00 Silvio Marijić :
>>
>>> @Stephan
>>>
>>> I am against that any kind of method can make modification on original
>>> object.
>>>
>>> Cloning can be allowed but for this use case where you would pass
>>> properties that are changing, we would have to modify syntax of clone
>>> On Sep 7, 2016 12:37 PM, "Stephen Reay" 
>>> wrote:
>>>
>>> > Hey Matheiu, Silvio,
>>> >
>>> > That is my main concern with the inability to clone from outside the
>>> > class. I don’t think immutable should cause an error in this situation
>>> - if
>>> > you really don’t want to allow users to create objects they can’t
>>> modify
>>> > (which I understand) could clone on an immutable object from outside
>>> the
>>> > class, simply return the object itself ?
>>> >
>>> > Re: immutable only externally - yes, as I mentioned I can understand
>>> that
>>> > would be a deal-break for some. In that situation, I’d be happy with
>>> some
>>> > way to indicate that a method can make changes. Would this then mean
>>> that
>>> > such a method could modify the object itself, rather than the clone?
>>> >
>>> > Cheers
>>> >
>>> > Stephen
>>> >
>>> > > On 7 Sep 2016, at 17:09, Mathieu Rochette 
>>> wrote:
>>> > >
>>> > >
>>> > >
>>> > > On 07/09/2016 11:28, Silvio Marijić wrote:
>>> > >> Hi Stephen,
>>> > >>
>>> > >> Cloning is disabled at the moment in implementation because you
>>> would
>>> > end
>>> > >> up with a object that you can not change, so you have no use of
>>> that.
>>> > I'll
>>> > >> change that as soon as we find some good solution for handling that.
>>> > Your
>>> > >> example is not really clear to me. At what point we should
>>> unlock/lock
>>> > >> object based on your example?
>>> > > what would happen if you tried to clone an immutable object, throw an
>>> > error ?
>>> > > it means that you might have to use reflection to check if the
>>> object is
>>> > immutable before cloning it. otherwise making a class immutable would
>>> be a
>>> > BC
>>> > >>
>>> > >> DateTimeImmutable does not prevent cloning because immutability is
>>> > achieved
>>> > >> by encapsulation, and we want to get rid of the need of
>>> encapsulation in
>>> > >> our implementation of immutable objects.
>>> > >>
>>> > >> Best,
>>> > >> Silvio.
>>> > >>
>>> > >> 2016-09-07 11:05 GMT+02:00 Stephen Reay :
>>> > >>
>>> > >>> (Sorry for any dupes, sent from wrong address originally)
>>> > >>>
>>> > >>> From a developer point of view, I would suggest that a feature
>>> should
>>> > aim
>>> > >>> to be as clear to understand with as little “magic" as possible.
>>> > >>>
>>> > >>>
>>> > >>> If the goal of an immutable class is to allow public properties to
>>> be
>>> > made
>>> > >>> read-only, my expectation would be that:
>>> > >>>
>>> > >>> - write access to any public property from outside class context,
>>> is an
>>> > >>> error.
>>> > >>>
>>> > >>> This seems to be pretty much accepted by everyone
>>> > >>>
>>> > >>>
>>> > >>> - clone still works as expected
>>> > >>>
>>> > >>> There has been some suggestion that clone $immutableObj should not
>>> be
>>> > >>> allowed. Unless there is some specific language/engine gain by
>>> that,
>>> > what
>>> > >>> is the point of having this behaviour?
>>> > >>> Existing built-in immutable classes (like DateTimeImmutable) do not
>>> > >>> prevent cloning, so why should this?
>>> > >>>
>>> > >>> - regular cloning from within class method(s) is the suggested way
>>> to
>>> > >>> provide “create a copy of the object with a new value”
>>> functionality.
>>> > >>>
>>> > >>> This example was given before, effectively:
>>> > >>>
>>> > >>> public function 

Re: [PHP-DEV] RFC - Immutable classes

2016-09-07 Thread Silvio Marijić
Michal, how much work do you estimate it would take us to implement method
modificator solution?

2016-09-07 14:01 GMT+02:00 Michał Brzuchalski :

> Hi,
>
> Frozing an immutable object after it's creation is most important feature
> of Immutable Classes.
> Without it you cannot have guarantee it's internal state is consistent as
> it was during creation.
> Having methods access to write is quite dangerous - think about CLosure
> binded to immutable object - there is a way to change internal state of
> such object, and you've broken immutability in it.
>
> Changing object state is reasonable only on clones, because you newer know
> what references to original object.
> There can be cloning objects as they are now - I don't see it usefull, but
> if somebody really want's it, why not.
>
> IMHO providing method modificator for changing object in context of newly
> created clone is the best solution. The keyword for it isn't chosen yet, we
> may discuss it or even vote for it. For now we can call it anyway while
> keeping in mind it may change during voting.
>
>
>
> 2016-09-07 12:43 GMT+02:00 Silvio Marijić :
>
>> @Stephan
>>
>> I am against that any kind of method can make modification on original
>> object.
>>
>> Cloning can be allowed but for this use case where you would pass
>> properties that are changing, we would have to modify syntax of clone
>> On Sep 7, 2016 12:37 PM, "Stephen Reay"  wrote:
>>
>> > Hey Matheiu, Silvio,
>> >
>> > That is my main concern with the inability to clone from outside the
>> > class. I don’t think immutable should cause an error in this situation
>> - if
>> > you really don’t want to allow users to create objects they can’t modify
>> > (which I understand) could clone on an immutable object from outside the
>> > class, simply return the object itself ?
>> >
>> > Re: immutable only externally - yes, as I mentioned I can understand
>> that
>> > would be a deal-break for some. In that situation, I’d be happy with
>> some
>> > way to indicate that a method can make changes. Would this then mean
>> that
>> > such a method could modify the object itself, rather than the clone?
>> >
>> > Cheers
>> >
>> > Stephen
>> >
>> > > On 7 Sep 2016, at 17:09, Mathieu Rochette 
>> wrote:
>> > >
>> > >
>> > >
>> > > On 07/09/2016 11:28, Silvio Marijić wrote:
>> > >> Hi Stephen,
>> > >>
>> > >> Cloning is disabled at the moment in implementation because you would
>> > end
>> > >> up with a object that you can not change, so you have no use of that.
>> > I'll
>> > >> change that as soon as we find some good solution for handling that.
>> > Your
>> > >> example is not really clear to me. At what point we should
>> unlock/lock
>> > >> object based on your example?
>> > > what would happen if you tried to clone an immutable object, throw an
>> > error ?
>> > > it means that you might have to use reflection to check if the object
>> is
>> > immutable before cloning it. otherwise making a class immutable would
>> be a
>> > BC
>> > >>
>> > >> DateTimeImmutable does not prevent cloning because immutability is
>> > achieved
>> > >> by encapsulation, and we want to get rid of the need of
>> encapsulation in
>> > >> our implementation of immutable objects.
>> > >>
>> > >> Best,
>> > >> Silvio.
>> > >>
>> > >> 2016-09-07 11:05 GMT+02:00 Stephen Reay :
>> > >>
>> > >>> (Sorry for any dupes, sent from wrong address originally)
>> > >>>
>> > >>> From a developer point of view, I would suggest that a feature
>> should
>> > aim
>> > >>> to be as clear to understand with as little “magic" as possible.
>> > >>>
>> > >>>
>> > >>> If the goal of an immutable class is to allow public properties to
>> be
>> > made
>> > >>> read-only, my expectation would be that:
>> > >>>
>> > >>> - write access to any public property from outside class context,
>> is an
>> > >>> error.
>> > >>>
>> > >>> This seems to be pretty much accepted by everyone
>> > >>>
>> > >>>
>> > >>> - clone still works as expected
>> > >>>
>> > >>> There has been some suggestion that clone $immutableObj should not
>> be
>> > >>> allowed. Unless there is some specific language/engine gain by that,
>> > what
>> > >>> is the point of having this behaviour?
>> > >>> Existing built-in immutable classes (like DateTimeImmutable) do not
>> > >>> prevent cloning, so why should this?
>> > >>>
>> > >>> - regular cloning from within class method(s) is the suggested way
>> to
>> > >>> provide “create a copy of the object with a new value”
>> functionality.
>> > >>>
>> > >>> This example was given before, effectively:
>> > >>>
>> > >>> public function withValue($val) {
>> > >>> $clone = clone $this;
>> > >>> $clone->val = $val;
>> > >>>
>> > >>> return $clone;
>> > >>> }
>> > >>>
>> > >>>
>> > >>>
>> > >>>
>> > >>>
>> >  On 7 Sep 2016, at 13:57, Michał Brzuchalski <
>> mic...@brzuchalski.com>
>> > >>> wrote:
>> >  

Re: [PHP-DEV] RFC - Immutable classes

2016-09-07 Thread Michał Brzuchalski
Hi,

Frozing an immutable object after it's creation is most important feature
of Immutable Classes.
Without it you cannot have guarantee it's internal state is consistent as
it was during creation.
Having methods access to write is quite dangerous - think about CLosure
binded to immutable object - there is a way to change internal state of
such object, and you've broken immutability in it.

Changing object state is reasonable only on clones, because you newer know
what references to original object.
There can be cloning objects as they are now - I don't see it usefull, but
if somebody really want's it, why not.

IMHO providing method modificator for changing object in context of newly
created clone is the best solution. The keyword for it isn't chosen yet, we
may discuss it or even vote for it. For now we can call it anyway while
keeping in mind it may change during voting.



2016-09-07 12:43 GMT+02:00 Silvio Marijić :

> @Stephan
>
> I am against that any kind of method can make modification on original
> object.
>
> Cloning can be allowed but for this use case where you would pass
> properties that are changing, we would have to modify syntax of clone
> On Sep 7, 2016 12:37 PM, "Stephen Reay"  wrote:
>
> > Hey Matheiu, Silvio,
> >
> > That is my main concern with the inability to clone from outside the
> > class. I don’t think immutable should cause an error in this situation -
> if
> > you really don’t want to allow users to create objects they can’t modify
> > (which I understand) could clone on an immutable object from outside the
> > class, simply return the object itself ?
> >
> > Re: immutable only externally - yes, as I mentioned I can understand that
> > would be a deal-break for some. In that situation, I’d be happy with some
> > way to indicate that a method can make changes. Would this then mean that
> > such a method could modify the object itself, rather than the clone?
> >
> > Cheers
> >
> > Stephen
> >
> > > On 7 Sep 2016, at 17:09, Mathieu Rochette  wrote:
> > >
> > >
> > >
> > > On 07/09/2016 11:28, Silvio Marijić wrote:
> > >> Hi Stephen,
> > >>
> > >> Cloning is disabled at the moment in implementation because you would
> > end
> > >> up with a object that you can not change, so you have no use of that.
> > I'll
> > >> change that as soon as we find some good solution for handling that.
> > Your
> > >> example is not really clear to me. At what point we should unlock/lock
> > >> object based on your example?
> > > what would happen if you tried to clone an immutable object, throw an
> > error ?
> > > it means that you might have to use reflection to check if the object
> is
> > immutable before cloning it. otherwise making a class immutable would be
> a
> > BC
> > >>
> > >> DateTimeImmutable does not prevent cloning because immutability is
> > achieved
> > >> by encapsulation, and we want to get rid of the need of encapsulation
> in
> > >> our implementation of immutable objects.
> > >>
> > >> Best,
> > >> Silvio.
> > >>
> > >> 2016-09-07 11:05 GMT+02:00 Stephen Reay :
> > >>
> > >>> (Sorry for any dupes, sent from wrong address originally)
> > >>>
> > >>> From a developer point of view, I would suggest that a feature should
> > aim
> > >>> to be as clear to understand with as little “magic" as possible.
> > >>>
> > >>>
> > >>> If the goal of an immutable class is to allow public properties to be
> > made
> > >>> read-only, my expectation would be that:
> > >>>
> > >>> - write access to any public property from outside class context, is
> an
> > >>> error.
> > >>>
> > >>> This seems to be pretty much accepted by everyone
> > >>>
> > >>>
> > >>> - clone still works as expected
> > >>>
> > >>> There has been some suggestion that clone $immutableObj should not be
> > >>> allowed. Unless there is some specific language/engine gain by that,
> > what
> > >>> is the point of having this behaviour?
> > >>> Existing built-in immutable classes (like DateTimeImmutable) do not
> > >>> prevent cloning, so why should this?
> > >>>
> > >>> - regular cloning from within class method(s) is the suggested way to
> > >>> provide “create a copy of the object with a new value” functionality.
> > >>>
> > >>> This example was given before, effectively:
> > >>>
> > >>> public function withValue($val) {
> > >>> $clone = clone $this;
> > >>> $clone->val = $val;
> > >>>
> > >>> return $clone;
> > >>> }
> > >>>
> > >>>
> > >>>
> > >>>
> > >>>
> >  On 7 Sep 2016, at 13:57, Michał Brzuchalski  >
> > >>> wrote:
> >  06.09.2016 9:13 PM "Fleshgrinder" 
> napisał(a):
> > > I understand the concerns of all of you very well and it's nice to
> > see a
> > > discussion around this topic. Fun fact, we are not the only ones
> with
> > > these issues: https://github.com/dotnet/roslyn/issues/159
> > >
> > > On 9/6/2016 6:01 PM, 

Re: [PHP-DEV] RFC - Immutable classes

2016-09-07 Thread Silvio Marijić
@Stephan

I am against that any kind of method can make modification on original
object.

Cloning can be allowed but for this use case where you would pass
properties that are changing, we would have to modify syntax of clone
On Sep 7, 2016 12:37 PM, "Stephen Reay"  wrote:

> Hey Matheiu, Silvio,
>
> That is my main concern with the inability to clone from outside the
> class. I don’t think immutable should cause an error in this situation - if
> you really don’t want to allow users to create objects they can’t modify
> (which I understand) could clone on an immutable object from outside the
> class, simply return the object itself ?
>
> Re: immutable only externally - yes, as I mentioned I can understand that
> would be a deal-break for some. In that situation, I’d be happy with some
> way to indicate that a method can make changes. Would this then mean that
> such a method could modify the object itself, rather than the clone?
>
> Cheers
>
> Stephen
>
> > On 7 Sep 2016, at 17:09, Mathieu Rochette  wrote:
> >
> >
> >
> > On 07/09/2016 11:28, Silvio Marijić wrote:
> >> Hi Stephen,
> >>
> >> Cloning is disabled at the moment in implementation because you would
> end
> >> up with a object that you can not change, so you have no use of that.
> I'll
> >> change that as soon as we find some good solution for handling that.
> Your
> >> example is not really clear to me. At what point we should unlock/lock
> >> object based on your example?
> > what would happen if you tried to clone an immutable object, throw an
> error ?
> > it means that you might have to use reflection to check if the object is
> immutable before cloning it. otherwise making a class immutable would be a
> BC
> >>
> >> DateTimeImmutable does not prevent cloning because immutability is
> achieved
> >> by encapsulation, and we want to get rid of the need of encapsulation in
> >> our implementation of immutable objects.
> >>
> >> Best,
> >> Silvio.
> >>
> >> 2016-09-07 11:05 GMT+02:00 Stephen Reay :
> >>
> >>> (Sorry for any dupes, sent from wrong address originally)
> >>>
> >>> From a developer point of view, I would suggest that a feature should
> aim
> >>> to be as clear to understand with as little “magic" as possible.
> >>>
> >>>
> >>> If the goal of an immutable class is to allow public properties to be
> made
> >>> read-only, my expectation would be that:
> >>>
> >>> - write access to any public property from outside class context, is an
> >>> error.
> >>>
> >>> This seems to be pretty much accepted by everyone
> >>>
> >>>
> >>> - clone still works as expected
> >>>
> >>> There has been some suggestion that clone $immutableObj should not be
> >>> allowed. Unless there is some specific language/engine gain by that,
> what
> >>> is the point of having this behaviour?
> >>> Existing built-in immutable classes (like DateTimeImmutable) do not
> >>> prevent cloning, so why should this?
> >>>
> >>> - regular cloning from within class method(s) is the suggested way to
> >>> provide “create a copy of the object with a new value” functionality.
> >>>
> >>> This example was given before, effectively:
> >>>
> >>> public function withValue($val) {
> >>> $clone = clone $this;
> >>> $clone->val = $val;
> >>>
> >>> return $clone;
> >>> }
> >>>
> >>>
> >>>
> >>>
> >>>
>  On 7 Sep 2016, at 13:57, Michał Brzuchalski 
> >>> wrote:
>  06.09.2016 9:13 PM "Fleshgrinder"  napisał(a):
> > I understand the concerns of all of you very well and it's nice to
> see a
> > discussion around this topic. Fun fact, we are not the only ones with
> > these issues: https://github.com/dotnet/roslyn/issues/159
> >
> > On 9/6/2016 6:01 PM, Larry Garfield wrote:
> >> How big of a need is it to allow returning $this instead of $clone,
> >> and/or can that be internalized somehow as well?  With
> copy-on-write,
> >> is that really an issue beyond a micro-optimization?
> > I asked the same question before because I am also unable to answer
> this
> > question regarding the engine.
> >
> > However, for me it is more than micro-optimization, it is about
> >>> identity.
> > final class Immutable {
> >   // ... the usual ...
> >   public function withValue($value) {
> > $clone = clone $this;
> > $clone->value = $value;
> > return $clone;
> >   }
> > }
> >
> > $red = new Immutable('red');
> > $still_red = $red->withValue('red');
> >
> > var_dump($red === $still_red); // bool(false)
> >
> > This is a problem in terms of value objects and PHP still does not
> allow
> > us operator overloading. A circumstance that I definitely want to
> > address in the near future.
> >
> > But the keyword copy-on-write leads me to yet another proposal,
> actually
> > your input led me to two new proposals.
> >
> 

Re: [PHP-DEV] RFC - Immutable classes

2016-09-07 Thread Stephen Reay
Hey Matheiu, Silvio,

That is my main concern with the inability to clone from outside the class. I 
don’t think immutable should cause an error in this situation - if you really 
don’t want to allow users to create objects they can’t modify (which I 
understand) could clone on an immutable object from outside the class, simply 
return the object itself ?

Re: immutable only externally - yes, as I mentioned I can understand that would 
be a deal-break for some. In that situation, I’d be happy with some way to 
indicate that a method can make changes. Would this then mean that such a 
method could modify the object itself, rather than the clone?

Cheers

Stephen

> On 7 Sep 2016, at 17:09, Mathieu Rochette  wrote:
> 
> 
> 
> On 07/09/2016 11:28, Silvio Marijić wrote:
>> Hi Stephen,
>> 
>> Cloning is disabled at the moment in implementation because you would end
>> up with a object that you can not change, so you have no use of that. I'll
>> change that as soon as we find some good solution for handling that. Your
>> example is not really clear to me. At what point we should unlock/lock
>> object based on your example?
> what would happen if you tried to clone an immutable object, throw an error ?
> it means that you might have to use reflection to check if the object is 
> immutable before cloning it. otherwise making a class immutable would be a BC
>> 
>> DateTimeImmutable does not prevent cloning because immutability is achieved
>> by encapsulation, and we want to get rid of the need of encapsulation in
>> our implementation of immutable objects.
>> 
>> Best,
>> Silvio.
>> 
>> 2016-09-07 11:05 GMT+02:00 Stephen Reay :
>> 
>>> (Sorry for any dupes, sent from wrong address originally)
>>> 
>>> From a developer point of view, I would suggest that a feature should aim
>>> to be as clear to understand with as little “magic" as possible.
>>> 
>>> 
>>> If the goal of an immutable class is to allow public properties to be made
>>> read-only, my expectation would be that:
>>> 
>>> - write access to any public property from outside class context, is an
>>> error.
>>> 
>>> This seems to be pretty much accepted by everyone
>>> 
>>> 
>>> - clone still works as expected
>>> 
>>> There has been some suggestion that clone $immutableObj should not be
>>> allowed. Unless there is some specific language/engine gain by that, what
>>> is the point of having this behaviour?
>>> Existing built-in immutable classes (like DateTimeImmutable) do not
>>> prevent cloning, so why should this?
>>> 
>>> - regular cloning from within class method(s) is the suggested way to
>>> provide “create a copy of the object with a new value” functionality.
>>> 
>>> This example was given before, effectively:
>>> 
>>> public function withValue($val) {
>>> $clone = clone $this;
>>> $clone->val = $val;
>>> 
>>> return $clone;
>>> }
>>> 
>>> 
>>> 
>>> 
>>> 
 On 7 Sep 2016, at 13:57, Michał Brzuchalski 
>>> wrote:
 06.09.2016 9:13 PM "Fleshgrinder"  napisał(a):
> I understand the concerns of all of you very well and it's nice to see a
> discussion around this topic. Fun fact, we are not the only ones with
> these issues: https://github.com/dotnet/roslyn/issues/159
> 
> On 9/6/2016 6:01 PM, Larry Garfield wrote:
>> How big of a need is it to allow returning $this instead of $clone,
>> and/or can that be internalized somehow as well?  With copy-on-write,
>> is that really an issue beyond a micro-optimization?
> I asked the same question before because I am also unable to answer this
> question regarding the engine.
> 
> However, for me it is more than micro-optimization, it is about
>>> identity.
> final class Immutable {
>   // ... the usual ...
>   public function withValue($value) {
> $clone = clone $this;
> $clone->value = $value;
> return $clone;
>   }
> }
> 
> $red = new Immutable('red');
> $still_red = $red->withValue('red');
> 
> var_dump($red === $still_red); // bool(false)
> 
> This is a problem in terms of value objects and PHP still does not allow
> us operator overloading. A circumstance that I definitely want to
> address in the near future.
> 
> But the keyword copy-on-write leads me to yet another proposal, actually
> your input led me to two new proposals.
> 
> # Copy-on-Write (CoW)
> Why are we even bothering on finding ways on making it hard for
> developers while the solution to our problem is directly in front of us:
> PHP Strings!
> 
 AFAIK CoW in case of objects would be impossible to implement.
 
> Every place in a PHP program refers to the same string if that string is
> the same string. In the second someone mutates that string in any way
> she gets her own mutated reference to that string.
> 
> That's exactly how we 

Re: [PHP-DEV] RFC - Immutable classes

2016-09-07 Thread Silvio Marijić
@Mathieu,

Object can not be modified neither internally or externally, question is if
you clone object where should we allow modification of cloned object
On Sep 7, 2016 12:13 PM, "Mathieu Rochette"  wrote:

>
>
> On 07/09/2016 11:05, Stephen Reay wrote:
>
>> (Sorry for any dupes, sent from wrong address originally)
>>
>>  From a developer point of view, I would suggest that a feature should
>> aim to be as clear to understand with as little “magic" as possible.
>>
>>
>> If the goal of an immutable class is to allow public properties to be
>> made read-only, my expectation would be that:
>>
> I don't think this is the goal, in immutable classes, the object itself
> should not be able to alter itself either (whatever the visibility of the
> property is)
>
>>
>> - write access to any public property from outside class context, is an
>> error.
>>
>> This seems to be pretty much accepted by everyone
>>
>>
>> - clone still works as expected
>>
>> There has been some suggestion that clone $immutableObj should not be
>> allowed. Unless there is some specific language/engine gain by that, what
>> is the point of having this behaviour?
>> Existing built-in immutable classes (like DateTimeImmutable) do not
>> prevent cloning, so why should this?
>>
>> - regular cloning from within class method(s) is the suggested way to
>> provide “create a copy of the object with a new value” functionality.
>>
>> This example was given before, effectively:
>>
>> public function withValue($val) {
>> $clone = clone $this;
>> $clone->val = $val;
>>
>> return $clone;
>> }
>>
>>
>>
>>
>>
>> On 7 Sep 2016, at 13:57, Michał Brzuchalski 
>>> wrote:
>>>
>>> 06.09.2016 9:13 PM "Fleshgrinder"  napisał(a):
>>>
 I understand the concerns of all of you very well and it's nice to see a
 discussion around this topic. Fun fact, we are not the only ones with
 these issues: https://github.com/dotnet/roslyn/issues/159

 On 9/6/2016 6:01 PM, Larry Garfield wrote:

> How big of a need is it to allow returning $this instead of $clone,
> and/or can that be internalized somehow as well?  With copy-on-write,
> is that really an issue beyond a micro-optimization?
>
 I asked the same question before because I am also unable to answer this
 question regarding the engine.

 However, for me it is more than micro-optimization, it is about
 identity.

 final class Immutable {
// ... the usual ...
public function withValue($value) {
  $clone = clone $this;
  $clone->value = $value;
  return $clone;
}
 }

 $red = new Immutable('red');
 $still_red = $red->withValue('red');

 var_dump($red === $still_red); // bool(false)

 This is a problem in terms of value objects and PHP still does not allow
 us operator overloading. A circumstance that I definitely want to
 address in the near future.

 But the keyword copy-on-write leads me to yet another proposal, actually
 your input led me to two new proposals.

 # Copy-on-Write (CoW)
 Why are we even bothering on finding ways on making it hard for
 developers while the solution to our problem is directly in front of us:
 PHP Strings!

 AFAIK CoW in case of objects would be impossible to implement.
>>>
>>> Every place in a PHP program refers to the same string if that string is
 the same string. In the second someone mutates that string in any way
 she gets her own mutated reference to that string.

 That's exactly how we could deal with immutable objects. Developers do
 not need to take care of anything, they just write totally normal
 objects and the engine takes care of everything.

 This approach also has the advantage that the return value of any method
 is (as always) up to the developers.

 (Cloning is disabled and results in an error as is because it makes no
 sense at all.)

 # Identity
 This directly leads to the second part of my thoughts and I already
 touched that topic: identity. If we have two strings their binary
 representation is always the same:

 var_dump('string' === 'string'); // bool(true)

 This is the exact behavior one wants for value objects too. Hence,
 immutable objects should have this behavior since they identify
 themselves by their values and not through instances. If I create two
 instances of Money with the amount 10 and the Currency EUR then they are
 always the same, no matter what. This would also mean that no developer
 ever needs to check if the new value is the same as the existing one,
 nor does anyone ever has to implement the flyweight pattern for
 immutable objects.

 A last very important attribute is that it does not matter in which
 thread an immutable value object is 

Re: [PHP-DEV] RFC - Immutable classes

2016-09-07 Thread Mathieu Rochette



On 07/09/2016 11:05, Stephen Reay wrote:

(Sorry for any dupes, sent from wrong address originally)

 From a developer point of view, I would suggest that a feature should aim to be as 
clear to understand with as little “magic" as possible.


If the goal of an immutable class is to allow public properties to be made 
read-only, my expectation would be that:
I don't think this is the goal, in immutable classes, the object itself 
should not be able to alter itself either (whatever the visibility of 
the property is)


- write access to any public property from outside class context, is an error.

This seems to be pretty much accepted by everyone


- clone still works as expected

There has been some suggestion that clone $immutableObj should not be allowed. 
Unless there is some specific language/engine gain by that, what is the point 
of having this behaviour?
Existing built-in immutable classes (like DateTimeImmutable) do not prevent 
cloning, so why should this?

- regular cloning from within class method(s) is the suggested way to provide 
“create a copy of the object with a new value” functionality.

This example was given before, effectively:

public function withValue($val) {
$clone = clone $this;
$clone->val = $val;

return $clone;
}






On 7 Sep 2016, at 13:57, Michał Brzuchalski  wrote:

06.09.2016 9:13 PM "Fleshgrinder"  napisał(a):

I understand the concerns of all of you very well and it's nice to see a
discussion around this topic. Fun fact, we are not the only ones with
these issues: https://github.com/dotnet/roslyn/issues/159

On 9/6/2016 6:01 PM, Larry Garfield wrote:

How big of a need is it to allow returning $this instead of $clone,
and/or can that be internalized somehow as well?  With copy-on-write,
is that really an issue beyond a micro-optimization?

I asked the same question before because I am also unable to answer this
question regarding the engine.

However, for me it is more than micro-optimization, it is about identity.

final class Immutable {
   // ... the usual ...
   public function withValue($value) {
 $clone = clone $this;
 $clone->value = $value;
 return $clone;
   }
}

$red = new Immutable('red');
$still_red = $red->withValue('red');

var_dump($red === $still_red); // bool(false)

This is a problem in terms of value objects and PHP still does not allow
us operator overloading. A circumstance that I definitely want to
address in the near future.

But the keyword copy-on-write leads me to yet another proposal, actually
your input led me to two new proposals.

# Copy-on-Write (CoW)
Why are we even bothering on finding ways on making it hard for
developers while the solution to our problem is directly in front of us:
PHP Strings!


AFAIK CoW in case of objects would be impossible to implement.


Every place in a PHP program refers to the same string if that string is
the same string. In the second someone mutates that string in any way
she gets her own mutated reference to that string.

That's exactly how we could deal with immutable objects. Developers do
not need to take care of anything, they just write totally normal
objects and the engine takes care of everything.

This approach also has the advantage that the return value of any method
is (as always) up to the developers.

(Cloning is disabled and results in an error as is because it makes no
sense at all.)

# Identity
This directly leads to the second part of my thoughts and I already
touched that topic: identity. If we have two strings their binary
representation is always the same:

var_dump('string' === 'string'); // bool(true)

This is the exact behavior one wants for value objects too. Hence,
immutable objects should have this behavior since they identify
themselves by their values and not through instances. If I create two
instances of Money with the amount 10 and the Currency EUR then they are
always the same, no matter what. This would also mean that no developer
ever needs to check if the new value is the same as the existing one,
nor does anyone ever has to implement the flyweight pattern for
immutable objects.

A last very important attribute is that it does not matter in which
thread an immutable value object is created because it always has the
same identity regardless of it.

This could easily be achieved by overwriting the object hashes
(spl_object_hash) with something that hashes based on the values, and
predictably across threads (UUIDs?).

# Full Example
value = $value;
}

public function withValue($value) {
   $this->value = $value;
}

}

class A {

public $vo;

public function __construct(ValueObject $vo) {
   $this->vo = $vo;
}

}

class B {

public $vo;

public function __construct(ValueObject $vo) {
   $this->vo = $vo;
}

}

$vo = new ValueObject(1);

$a = new A($vo);
$b = new B($vo);

var_dump($a->vo === $b->vo); // bool(true)

$a->vo->withValue(2);

var_dump($a->vo === $b->vo); // bool(false)


Re: [PHP-DEV] RFC - Immutable classes

2016-09-07 Thread Mathieu Rochette



On 07/09/2016 11:28, Silvio Marijić wrote:

Hi Stephen,

Cloning is disabled at the moment in implementation because you would end
up with a object that you can not change, so you have no use of that. I'll
change that as soon as we find some good solution for handling that. Your
example is not really clear to me. At what point we should unlock/lock
object based on your example?
what would happen if you tried to clone an immutable object, throw an 
error ?
it means that you might have to use reflection to check if the object is 
immutable before cloning it. otherwise making a class immutable would be 
a BC


DateTimeImmutable does not prevent cloning because immutability is achieved
by encapsulation, and we want to get rid of the need of encapsulation in
our implementation of immutable objects.

Best,
Silvio.

2016-09-07 11:05 GMT+02:00 Stephen Reay :


(Sorry for any dupes, sent from wrong address originally)

 From a developer point of view, I would suggest that a feature should aim
to be as clear to understand with as little “magic" as possible.


If the goal of an immutable class is to allow public properties to be made
read-only, my expectation would be that:

- write access to any public property from outside class context, is an
error.

This seems to be pretty much accepted by everyone


- clone still works as expected

There has been some suggestion that clone $immutableObj should not be
allowed. Unless there is some specific language/engine gain by that, what
is the point of having this behaviour?
Existing built-in immutable classes (like DateTimeImmutable) do not
prevent cloning, so why should this?

- regular cloning from within class method(s) is the suggested way to
provide “create a copy of the object with a new value” functionality.

This example was given before, effectively:

public function withValue($val) {
 $clone = clone $this;
 $clone->val = $val;

 return $clone;
}






On 7 Sep 2016, at 13:57, Michał Brzuchalski 

wrote:

06.09.2016 9:13 PM "Fleshgrinder"  napisał(a):

I understand the concerns of all of you very well and it's nice to see a
discussion around this topic. Fun fact, we are not the only ones with
these issues: https://github.com/dotnet/roslyn/issues/159

On 9/6/2016 6:01 PM, Larry Garfield wrote:

How big of a need is it to allow returning $this instead of $clone,
and/or can that be internalized somehow as well?  With copy-on-write,
is that really an issue beyond a micro-optimization?

I asked the same question before because I am also unable to answer this
question regarding the engine.

However, for me it is more than micro-optimization, it is about

identity.

final class Immutable {
   // ... the usual ...
   public function withValue($value) {
 $clone = clone $this;
 $clone->value = $value;
 return $clone;
   }
}

$red = new Immutable('red');
$still_red = $red->withValue('red');

var_dump($red === $still_red); // bool(false)

This is a problem in terms of value objects and PHP still does not allow
us operator overloading. A circumstance that I definitely want to
address in the near future.

But the keyword copy-on-write leads me to yet another proposal, actually
your input led me to two new proposals.

# Copy-on-Write (CoW)
Why are we even bothering on finding ways on making it hard for
developers while the solution to our problem is directly in front of us:
PHP Strings!


AFAIK CoW in case of objects would be impossible to implement.


Every place in a PHP program refers to the same string if that string is
the same string. In the second someone mutates that string in any way
she gets her own mutated reference to that string.

That's exactly how we could deal with immutable objects. Developers do
not need to take care of anything, they just write totally normal
objects and the engine takes care of everything.

This approach also has the advantage that the return value of any method
is (as always) up to the developers.

(Cloning is disabled and results in an error as is because it makes no
sense at all.)

# Identity
This directly leads to the second part of my thoughts and I already
touched that topic: identity. If we have two strings their binary
representation is always the same:

var_dump('string' === 'string'); // bool(true)

This is the exact behavior one wants for value objects too. Hence,
immutable objects should have this behavior since they identify
themselves by their values and not through instances. If I create two
instances of Money with the amount 10 and the Currency EUR then they are
always the same, no matter what. This would also mean that no developer
ever needs to check if the new value is the same as the existing one,
nor does anyone ever has to implement the flyweight pattern for
immutable objects.

A last very important attribute is that it does not matter in which
thread an immutable value object is created because it always has 

Re: [PHP-DEV] RFC - Immutable classes

2016-09-07 Thread Silvio Marijić
And also Fleshgrinder made a good point about comparing two immutable
objects. They should be compared based on value, not on identity.

2016-09-07 11:28 GMT+02:00 Silvio Marijić :

> Hi Stephen,
>
> Cloning is disabled at the moment in implementation because you would end
> up with a object that you can not change, so you have no use of that. I'll
> change that as soon as we find some good solution for handling that. Your
> example is not really clear to me. At what point we should unlock/lock
> object based on your example?
>
> DateTimeImmutable does not prevent cloning because immutability is
> achieved by encapsulation, and we want to get rid of the need of
> encapsulation in our implementation of immutable objects.
>
> Best,
> Silvio.
>
> 2016-09-07 11:05 GMT+02:00 Stephen Reay :
>
>> (Sorry for any dupes, sent from wrong address originally)
>>
>> From a developer point of view, I would suggest that a feature should aim
>> to be as clear to understand with as little “magic" as possible.
>>
>>
>> If the goal of an immutable class is to allow public properties to be
>> made read-only, my expectation would be that:
>>
>> - write access to any public property from outside class context, is an
>> error.
>>
>> This seems to be pretty much accepted by everyone
>>
>>
>> - clone still works as expected
>>
>> There has been some suggestion that clone $immutableObj should not be
>> allowed. Unless there is some specific language/engine gain by that, what
>> is the point of having this behaviour?
>> Existing built-in immutable classes (like DateTimeImmutable) do not
>> prevent cloning, so why should this?
>>
>> - regular cloning from within class method(s) is the suggested way to
>> provide “create a copy of the object with a new value” functionality.
>>
>> This example was given before, effectively:
>>
>> public function withValue($val) {
>> $clone = clone $this;
>> $clone->val = $val;
>>
>> return $clone;
>> }
>>
>>
>>
>>
>>
>> > On 7 Sep 2016, at 13:57, Michał Brzuchalski 
>> wrote:
>> >
>> > 06.09.2016 9:13 PM "Fleshgrinder"  napisał(a):
>> >>
>> >> I understand the concerns of all of you very well and it's nice to see
>> a
>> >> discussion around this topic. Fun fact, we are not the only ones with
>> >> these issues: https://github.com/dotnet/roslyn/issues/159
>> >>
>> >> On 9/6/2016 6:01 PM, Larry Garfield wrote:
>> >>> How big of a need is it to allow returning $this instead of $clone,
>> >>> and/or can that be internalized somehow as well?  With copy-on-write,
>> >>> is that really an issue beyond a micro-optimization?
>> >>
>> >> I asked the same question before because I am also unable to answer
>> this
>> >> question regarding the engine.
>> >>
>> >> However, for me it is more than micro-optimization, it is about
>> identity.
>> >>
>> >> final class Immutable {
>> >>   // ... the usual ...
>> >>   public function withValue($value) {
>> >> $clone = clone $this;
>> >> $clone->value = $value;
>> >> return $clone;
>> >>   }
>> >> }
>> >>
>> >> $red = new Immutable('red');
>> >> $still_red = $red->withValue('red');
>> >>
>> >> var_dump($red === $still_red); // bool(false)
>> >>
>> >> This is a problem in terms of value objects and PHP still does not
>> allow
>> >> us operator overloading. A circumstance that I definitely want to
>> >> address in the near future.
>> >>
>> >> But the keyword copy-on-write leads me to yet another proposal,
>> actually
>> >> your input led me to two new proposals.
>> >>
>> >> # Copy-on-Write (CoW)
>> >> Why are we even bothering on finding ways on making it hard for
>> >> developers while the solution to our problem is directly in front of
>> us:
>> >> PHP Strings!
>> >>
>> >
>> > AFAIK CoW in case of objects would be impossible to implement.
>> >
>> >> Every place in a PHP program refers to the same string if that string
>> is
>> >> the same string. In the second someone mutates that string in any way
>> >> she gets her own mutated reference to that string.
>> >>
>> >> That's exactly how we could deal with immutable objects. Developers do
>> >> not need to take care of anything, they just write totally normal
>> >> objects and the engine takes care of everything.
>> >>
>> >> This approach also has the advantage that the return value of any
>> method
>> >> is (as always) up to the developers.
>> >>
>> >> (Cloning is disabled and results in an error as is because it makes no
>> >> sense at all.)
>> >>
>> >> # Identity
>> >> This directly leads to the second part of my thoughts and I already
>> >> touched that topic: identity. If we have two strings their binary
>> >> representation is always the same:
>> >>
>> >> var_dump('string' === 'string'); // bool(true)
>> >>
>> >> This is the exact behavior one wants for value objects too. Hence,
>> >> immutable objects should have this behavior since they identify
>> >> themselves by their values and not 

Re: [PHP-DEV] RFC - Immutable classes

2016-09-07 Thread Silvio Marijić
Hi Stephen,

Cloning is disabled at the moment in implementation because you would end
up with a object that you can not change, so you have no use of that. I'll
change that as soon as we find some good solution for handling that. Your
example is not really clear to me. At what point we should unlock/lock
object based on your example?

DateTimeImmutable does not prevent cloning because immutability is achieved
by encapsulation, and we want to get rid of the need of encapsulation in
our implementation of immutable objects.

Best,
Silvio.

2016-09-07 11:05 GMT+02:00 Stephen Reay :

> (Sorry for any dupes, sent from wrong address originally)
>
> From a developer point of view, I would suggest that a feature should aim
> to be as clear to understand with as little “magic" as possible.
>
>
> If the goal of an immutable class is to allow public properties to be made
> read-only, my expectation would be that:
>
> - write access to any public property from outside class context, is an
> error.
>
> This seems to be pretty much accepted by everyone
>
>
> - clone still works as expected
>
> There has been some suggestion that clone $immutableObj should not be
> allowed. Unless there is some specific language/engine gain by that, what
> is the point of having this behaviour?
> Existing built-in immutable classes (like DateTimeImmutable) do not
> prevent cloning, so why should this?
>
> - regular cloning from within class method(s) is the suggested way to
> provide “create a copy of the object with a new value” functionality.
>
> This example was given before, effectively:
>
> public function withValue($val) {
> $clone = clone $this;
> $clone->val = $val;
>
> return $clone;
> }
>
>
>
>
>
> > On 7 Sep 2016, at 13:57, Michał Brzuchalski 
> wrote:
> >
> > 06.09.2016 9:13 PM "Fleshgrinder"  napisał(a):
> >>
> >> I understand the concerns of all of you very well and it's nice to see a
> >> discussion around this topic. Fun fact, we are not the only ones with
> >> these issues: https://github.com/dotnet/roslyn/issues/159
> >>
> >> On 9/6/2016 6:01 PM, Larry Garfield wrote:
> >>> How big of a need is it to allow returning $this instead of $clone,
> >>> and/or can that be internalized somehow as well?  With copy-on-write,
> >>> is that really an issue beyond a micro-optimization?
> >>
> >> I asked the same question before because I am also unable to answer this
> >> question regarding the engine.
> >>
> >> However, for me it is more than micro-optimization, it is about
> identity.
> >>
> >> final class Immutable {
> >>   // ... the usual ...
> >>   public function withValue($value) {
> >> $clone = clone $this;
> >> $clone->value = $value;
> >> return $clone;
> >>   }
> >> }
> >>
> >> $red = new Immutable('red');
> >> $still_red = $red->withValue('red');
> >>
> >> var_dump($red === $still_red); // bool(false)
> >>
> >> This is a problem in terms of value objects and PHP still does not allow
> >> us operator overloading. A circumstance that I definitely want to
> >> address in the near future.
> >>
> >> But the keyword copy-on-write leads me to yet another proposal, actually
> >> your input led me to two new proposals.
> >>
> >> # Copy-on-Write (CoW)
> >> Why are we even bothering on finding ways on making it hard for
> >> developers while the solution to our problem is directly in front of us:
> >> PHP Strings!
> >>
> >
> > AFAIK CoW in case of objects would be impossible to implement.
> >
> >> Every place in a PHP program refers to the same string if that string is
> >> the same string. In the second someone mutates that string in any way
> >> she gets her own mutated reference to that string.
> >>
> >> That's exactly how we could deal with immutable objects. Developers do
> >> not need to take care of anything, they just write totally normal
> >> objects and the engine takes care of everything.
> >>
> >> This approach also has the advantage that the return value of any method
> >> is (as always) up to the developers.
> >>
> >> (Cloning is disabled and results in an error as is because it makes no
> >> sense at all.)
> >>
> >> # Identity
> >> This directly leads to the second part of my thoughts and I already
> >> touched that topic: identity. If we have two strings their binary
> >> representation is always the same:
> >>
> >> var_dump('string' === 'string'); // bool(true)
> >>
> >> This is the exact behavior one wants for value objects too. Hence,
> >> immutable objects should have this behavior since they identify
> >> themselves by their values and not through instances. If I create two
> >> instances of Money with the amount 10 and the Currency EUR then they are
> >> always the same, no matter what. This would also mean that no developer
> >> ever needs to check if the new value is the same as the existing one,
> >> nor does anyone ever has to implement the flyweight pattern for
> >> immutable objects.
> >>
> >> A 

Re: [PHP-DEV] RFC - Immutable classes

2016-09-07 Thread Stephen Reay
(Sorry for any dupes, sent from wrong address originally)

From a developer point of view, I would suggest that a feature should aim to be 
as clear to understand with as little “magic" as possible.


If the goal of an immutable class is to allow public properties to be made 
read-only, my expectation would be that:

- write access to any public property from outside class context, is an error.

This seems to be pretty much accepted by everyone


- clone still works as expected

There has been some suggestion that clone $immutableObj should not be allowed. 
Unless there is some specific language/engine gain by that, what is the point 
of having this behaviour?
Existing built-in immutable classes (like DateTimeImmutable) do not prevent 
cloning, so why should this?

- regular cloning from within class method(s) is the suggested way to provide 
“create a copy of the object with a new value” functionality.

This example was given before, effectively:

public function withValue($val) {
$clone = clone $this;
$clone->val = $val;

return $clone;
}





> On 7 Sep 2016, at 13:57, Michał Brzuchalski  wrote:
> 
> 06.09.2016 9:13 PM "Fleshgrinder"  napisał(a):
>> 
>> I understand the concerns of all of you very well and it's nice to see a
>> discussion around this topic. Fun fact, we are not the only ones with
>> these issues: https://github.com/dotnet/roslyn/issues/159
>> 
>> On 9/6/2016 6:01 PM, Larry Garfield wrote:
>>> How big of a need is it to allow returning $this instead of $clone,
>>> and/or can that be internalized somehow as well?  With copy-on-write,
>>> is that really an issue beyond a micro-optimization?
>> 
>> I asked the same question before because I am also unable to answer this
>> question regarding the engine.
>> 
>> However, for me it is more than micro-optimization, it is about identity.
>> 
>> final class Immutable {
>>   // ... the usual ...
>>   public function withValue($value) {
>> $clone = clone $this;
>> $clone->value = $value;
>> return $clone;
>>   }
>> }
>> 
>> $red = new Immutable('red');
>> $still_red = $red->withValue('red');
>> 
>> var_dump($red === $still_red); // bool(false)
>> 
>> This is a problem in terms of value objects and PHP still does not allow
>> us operator overloading. A circumstance that I definitely want to
>> address in the near future.
>> 
>> But the keyword copy-on-write leads me to yet another proposal, actually
>> your input led me to two new proposals.
>> 
>> # Copy-on-Write (CoW)
>> Why are we even bothering on finding ways on making it hard for
>> developers while the solution to our problem is directly in front of us:
>> PHP Strings!
>> 
> 
> AFAIK CoW in case of objects would be impossible to implement.
> 
>> Every place in a PHP program refers to the same string if that string is
>> the same string. In the second someone mutates that string in any way
>> she gets her own mutated reference to that string.
>> 
>> That's exactly how we could deal with immutable objects. Developers do
>> not need to take care of anything, they just write totally normal
>> objects and the engine takes care of everything.
>> 
>> This approach also has the advantage that the return value of any method
>> is (as always) up to the developers.
>> 
>> (Cloning is disabled and results in an error as is because it makes no
>> sense at all.)
>> 
>> # Identity
>> This directly leads to the second part of my thoughts and I already
>> touched that topic: identity. If we have two strings their binary
>> representation is always the same:
>> 
>> var_dump('string' === 'string'); // bool(true)
>> 
>> This is the exact behavior one wants for value objects too. Hence,
>> immutable objects should have this behavior since they identify
>> themselves by their values and not through instances. If I create two
>> instances of Money with the amount 10 and the Currency EUR then they are
>> always the same, no matter what. This would also mean that no developer
>> ever needs to check if the new value is the same as the existing one,
>> nor does anyone ever has to implement the flyweight pattern for
>> immutable objects.
>> 
>> A last very important attribute is that it does not matter in which
>> thread an immutable value object is created because it always has the
>> same identity regardless of it.
>> 
>> This could easily be achieved by overwriting the object hashes
>> (spl_object_hash) with something that hashes based on the values, and
>> predictably across threads (UUIDs?).
>> 
>> # Full Example
>> > 
>> final immutable class ValueObject {
>> 
>> public $value;
>> 
>> public function __construct($value) {
>>   $this->value = $value;
>> }
>> 
>> public function withValue($value) {
>>   $this->value = $value;
>> }
>> 
>> }
>> 
>> class A {
>> 
>> public $vo;
>> 
>> public function __construct(ValueObject $vo) {
>>   $this->vo = $vo;
>> }
>> 
>> }
>> 
>> class B {
>> 
>> public $vo;
>> 
>> public function 

Re: [PHP-DEV] RFC - Immutable classes

2016-09-07 Thread Michał Brzuchalski
06.09.2016 9:13 PM "Fleshgrinder"  napisał(a):
>
> I understand the concerns of all of you very well and it's nice to see a
> discussion around this topic. Fun fact, we are not the only ones with
> these issues: https://github.com/dotnet/roslyn/issues/159
>
> On 9/6/2016 6:01 PM, Larry Garfield wrote:
> > How big of a need is it to allow returning $this instead of $clone,
> > and/or can that be internalized somehow as well?  With copy-on-write,
> > is that really an issue beyond a micro-optimization?
>
> I asked the same question before because I am also unable to answer this
> question regarding the engine.
>
> However, for me it is more than micro-optimization, it is about identity.
>
>   final class Immutable {
> // ... the usual ...
> public function withValue($value) {
>   $clone = clone $this;
>   $clone->value = $value;
>   return $clone;
> }
>   }
>
>   $red = new Immutable('red');
>   $still_red = $red->withValue('red');
>
>   var_dump($red === $still_red); // bool(false)
>
> This is a problem in terms of value objects and PHP still does not allow
> us operator overloading. A circumstance that I definitely want to
> address in the near future.
>
> But the keyword copy-on-write leads me to yet another proposal, actually
> your input led me to two new proposals.
>
> # Copy-on-Write (CoW)
> Why are we even bothering on finding ways on making it hard for
> developers while the solution to our problem is directly in front of us:
> PHP Strings!
>

AFAIK CoW in case of objects would be impossible to implement.

> Every place in a PHP program refers to the same string if that string is
> the same string. In the second someone mutates that string in any way
> she gets her own mutated reference to that string.
>
> That's exactly how we could deal with immutable objects. Developers do
> not need to take care of anything, they just write totally normal
> objects and the engine takes care of everything.
>
> This approach also has the advantage that the return value of any method
> is (as always) up to the developers.
>
> (Cloning is disabled and results in an error as is because it makes no
> sense at all.)
>
> # Identity
> This directly leads to the second part of my thoughts and I already
> touched that topic: identity. If we have two strings their binary
> representation is always the same:
>
>   var_dump('string' === 'string'); // bool(true)
>
> This is the exact behavior one wants for value objects too. Hence,
> immutable objects should have this behavior since they identify
> themselves by their values and not through instances. If I create two
> instances of Money with the amount 10 and the Currency EUR then they are
> always the same, no matter what. This would also mean that no developer
> ever needs to check if the new value is the same as the existing one,
> nor does anyone ever has to implement the flyweight pattern for
> immutable objects.
>
> A last very important attribute is that it does not matter in which
> thread an immutable value object is created because it always has the
> same identity regardless of it.
>
> This could easily be achieved by overwriting the object hashes
> (spl_object_hash) with something that hashes based on the values, and
> predictably across threads (UUIDs?).
>
> # Full Example
> 
> final immutable class ValueObject {
>
>   public $value;
>
>   public function __construct($value) {
> $this->value = $value;
>   }
>
>   public function withValue($value) {
> $this->value = $value;
>   }
>
> }
>
> class A {
>
>   public $vo;
>
>   public function __construct(ValueObject $vo) {
> $this->vo = $vo;
>   }
>
> }
>
> class B {
>
>   public $vo;
>
>   public function __construct(ValueObject $vo) {
> $this->vo = $vo;
>   }
>
> }
>
> $vo = new ValueObject(1);
>
> $a = new A($vo);
> $b = new B($vo);
>
> var_dump($a->vo === $b->vo); // bool(true)
>
> $a->vo->withValue(2);
>
> var_dump($a->vo === $b->vo); // bool(false)
>
> $a->vo->withValue(1);
>
> var_dump($a->vo === $b->vo); // bool(true)
>
> // :)
>
> ?>
>
> --
> Richard "Fleshgrinder" Fussenegger
>


Re: [PHP-DEV] RFC - Immutable classes

2016-09-06 Thread Fleshgrinder
I understand the concerns of all of you very well and it's nice to see a
discussion around this topic. Fun fact, we are not the only ones with
these issues: https://github.com/dotnet/roslyn/issues/159

On 9/6/2016 6:01 PM, Larry Garfield wrote:
> How big of a need is it to allow returning $this instead of $clone,
> and/or can that be internalized somehow as well?  With copy-on-write,
> is that really an issue beyond a micro-optimization?

I asked the same question before because I am also unable to answer this
question regarding the engine.

However, for me it is more than micro-optimization, it is about identity.

  final class Immutable {
// ... the usual ...
public function withValue($value) {
  $clone = clone $this;
  $clone->value = $value;
  return $clone;
}
  }

  $red = new Immutable('red');
  $still_red = $red->withValue('red');

  var_dump($red === $still_red); // bool(false)

This is a problem in terms of value objects and PHP still does not allow
us operator overloading. A circumstance that I definitely want to
address in the near future.

But the keyword copy-on-write leads me to yet another proposal, actually
your input led me to two new proposals.

# Copy-on-Write (CoW)
Why are we even bothering on finding ways on making it hard for
developers while the solution to our problem is directly in front of us:
PHP Strings!

Every place in a PHP program refers to the same string if that string is
the same string. In the second someone mutates that string in any way
she gets her own mutated reference to that string.

That's exactly how we could deal with immutable objects. Developers do
not need to take care of anything, they just write totally normal
objects and the engine takes care of everything.

This approach also has the advantage that the return value of any method
is (as always) up to the developers.

(Cloning is disabled and results in an error as is because it makes no
sense at all.)

# Identity
This directly leads to the second part of my thoughts and I already
touched that topic: identity. If we have two strings their binary
representation is always the same:

  var_dump('string' === 'string'); // bool(true)

This is the exact behavior one wants for value objects too. Hence,
immutable objects should have this behavior since they identify
themselves by their values and not through instances. If I create two
instances of Money with the amount 10 and the Currency EUR then they are
always the same, no matter what. This would also mean that no developer
ever needs to check if the new value is the same as the existing one,
nor does anyone ever has to implement the flyweight pattern for
immutable objects.

A last very important attribute is that it does not matter in which
thread an immutable value object is created because it always has the
same identity regardless of it.

This could easily be achieved by overwriting the object hashes
(spl_object_hash) with something that hashes based on the values, and
predictably across threads (UUIDs?).

# Full Example
value = $value;
  }

  public function withValue($value) {
$this->value = $value;
  }

}

class A {

  public $vo;

  public function __construct(ValueObject $vo) {
$this->vo = $vo;
  }

}

class B {

  public $vo;

  public function __construct(ValueObject $vo) {
$this->vo = $vo;
  }

}

$vo = new ValueObject(1);

$a = new A($vo);
$b = new B($vo);

var_dump($a->vo === $b->vo); // bool(true)

$a->vo->withValue(2);

var_dump($a->vo === $b->vo); // bool(false)

$a->vo->withValue(1);

var_dump($a->vo === $b->vo); // bool(true)

// :)

?>

-- 
Richard "Fleshgrinder" Fussenegger



signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] RFC - Immutable classes

2016-09-06 Thread Silvio Marijić
@Larry,
Fact that $this in transformer method represents clone and the original
object was my biggest concern, but again if you look at t from a point of
view where that method describes transformation it doesn't look that bad.
My initial idea was to introduce copy() method which would take as a first
argument immutable object and as a second array of parameters which are
going to be changed.

If we decide for transformer method as a solution, I don't think it has
much sense to allow cloning immutable object from user land.

I think we can live with the fact that they are mutable only in a
controlled way. But the fact that some solution for cloning is here is a
great deal since that was issue from the day 1.

Cheers,
Silvio.

2016-09-06 18:01 GMT+02:00 Larry Garfield :

> On 09/05/2016 11:37 AM, Fleshgrinder wrote:
>
>>
>> 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.
>>
>
> Naming things is hard. :-)  While working on PSR-13 for FIG, we ended up
> with the name "evolvable" for interfaces with the withFoo() methods.  I am
> not necessarily endorsing that as the best term (we weren't super happy
> about it but it was better than the alternatives), but providing it as a
> data point.
>
>
> 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. :)
>>
>
> How big of a need is it to allow returning $this instead of $clone, and/or
> can that be internalized somehow as well?  With copy-on-write, is that
> really an issue beyond a micro-optimization?
>
> As an end-user/developer, it's unclear to me how I'd know visually what
> scopes an object can be modified in.  Basically, in the above example
> there's an implicit unlock-on-clone and lock-on-return. There's no clear
> indication of that, however, since there's no extra keywords.  Is that
> sufficiently obvious for developers?  I fear not.
>
> 

Re: [PHP-DEV] RFC - Immutable classes

2016-09-06 Thread Larry Garfield

On 09/05/2016 11:37 AM, Fleshgrinder wrote:


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.


Naming things is hard. :-)  While working on PSR-13 for FIG, we ended up 
with the name "evolvable" for interfaces with the withFoo() methods.  I 
am not necessarily endorsing that as the best term (we weren't super 
happy about it but it was better than the alternatives), but providing 
it as a data point.



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. :)


How big of a need is it to allow returning $this instead of $clone, 
and/or can that be internalized somehow as well?  With copy-on-write, is 
that really an issue beyond a micro-optimization?


As an end-user/developer, it's unclear to me how I'd know visually what 
scopes an object can be modified in.  Basically, in the above example 
there's an implicit unlock-on-clone and lock-on-return. There's no clear 
indication of that, however, since there's no extra keywords.  Is that 
sufficiently obvious for developers?  I fear not.


Also, would the above still allow for custom clone() implementations on 
an immutable object or no?  I' not sure off hand which I'd prefer, 
honestly...


Another note: This would preclude "externally immutable" objects, eg, 
ones that can compute and internally cache a value but are still 
effectively immutable as the outside world sees them.  That's probably 
acceptable since the manual way is still available, but I thought it 
worth calling out.


I definitely like any of these options better than an explicit 
user-facing lock/unlock mechanism, as that's begging for abuse, 
confusion, and inconsistency.


--Larry Garfield

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] RFC - Immutable classes

2016-09-05 Thread Fleshgrinder
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


Re: [PHP-DEV] RFC - Immutable classes

2016-09-05 Thread Michał Brzuchalski
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?


2016-09-05 4:21 GMT+02:00 Michał Brzuchalski :

>
>
> 2016-09-04 22:38 GMT+02:00 Fleshgrinder :
>
>> On 9/4/2016 2:29 PM, Michał Brzuchalski wrote:
>> >> Providing `mutator` | `mut` keyword as method modifier sounds liek a
>> good
>> >> idea,
>> >> althought passing `$clone` parameter as first additional param could
>> break
>> >> method declaration and would be misleading.
>> >>
>> >> Assuming mutator method is designed to  return mutated clone of
>> immutable
>> >> object
>> >> having `$clone` variable could be handled internally without breaking
>> >> method declaration.
>> >>
>> >> Such variable could be unlocked while in mutator method and locked on
>> >> return.
>> >> I was thinking about additional check if such mutator returns `$clone`
>> but
>> >> not `$this`
>> >> but I don't see the need of it - assuming there is no what to change in
>> >> some
>> >> circumstances ther would be also possible to return `$this`.
>> >>
>> >> The return type declaration `self` could increase readability, but
>> should
>> >> not be required,
>> >> as some developers doesn't already use return types.
>> >>
>> >
>> > It could look like in this gist
>> > https://gist.github.com/brzuchal/e7b721e22a19cca42ec0d1f597a23baf
>> >
>>
>> This is exactly how I meant it, yes. I actually prefer it if the
>> variable just exist in the context instead of passing it as first
>> argument. It's less obvious that it exists but the same could be said
>> about $this.
>>
>> Would it be possible to have this thing just in time instead of
>> automatically created in every mutator function?
>>
>>   public mutator function f() {
>> if (condition) {
>>   $clone is created;
>>   return $clone;
>> }
>> return $this;
>>   }
>>
>> PS: I started overhauling the test cases and error messages and will
>> create a PR against your branch soon. I will start with the RFC
>> afterwards. Should I simply edit the RFC in the Wiki or should we manage
>> this somewhere else?
>>
>>
> 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?
>
>
>> --
>> Richard "Fleshgrinder" Fussenegger
>>
>>
>
>
> --
> regards / pozdrawiam,
> --
> Michał Brzuchalski
> brzuchalski.com
>



-- 
regards / pozdrawiam,
--
Michał Brzuchalski
brzuchalski.com


Re: [PHP-DEV] RFC - Immutable classes

2016-09-04 Thread Michał Brzuchalski
2016-09-04 22:38 GMT+02:00 Fleshgrinder :

> On 9/4/2016 2:29 PM, Michał Brzuchalski wrote:
> >> Providing `mutator` | `mut` keyword as method modifier sounds liek a
> good
> >> idea,
> >> althought passing `$clone` parameter as first additional param could
> break
> >> method declaration and would be misleading.
> >>
> >> Assuming mutator method is designed to  return mutated clone of
> immutable
> >> object
> >> having `$clone` variable could be handled internally without breaking
> >> method declaration.
> >>
> >> Such variable could be unlocked while in mutator method and locked on
> >> return.
> >> I was thinking about additional check if such mutator returns `$clone`
> but
> >> not `$this`
> >> but I don't see the need of it - assuming there is no what to change in
> >> some
> >> circumstances ther would be also possible to return `$this`.
> >>
> >> The return type declaration `self` could increase readability, but
> should
> >> not be required,
> >> as some developers doesn't already use return types.
> >>
> >
> > It could look like in this gist
> > https://gist.github.com/brzuchal/e7b721e22a19cca42ec0d1f597a23baf
> >
>
> This is exactly how I meant it, yes. I actually prefer it if the
> variable just exist in the context instead of passing it as first
> argument. It's less obvious that it exists but the same could be said
> about $this.
>
> Would it be possible to have this thing just in time instead of
> automatically created in every mutator function?
>
>   public mutator function f() {
> if (condition) {
>   $clone is created;
>   return $clone;
> }
> return $this;
>   }
>
> PS: I started overhauling the test cases and error messages and will
> create a PR against your branch soon. I will start with the RFC
> afterwards. Should I simply edit the RFC in the Wiki or should we manage
> this somewhere else?
>
>
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?


> --
> Richard "Fleshgrinder" Fussenegger
>
>


-- 
regards / pozdrawiam,
--
Michał Brzuchalski
brzuchalski.com


Re: [PHP-DEV] RFC - Immutable classes

2016-09-04 Thread Fleshgrinder
On 9/4/2016 2:29 PM, Michał Brzuchalski wrote:
>> Providing `mutator` | `mut` keyword as method modifier sounds liek a good
>> idea,
>> althought passing `$clone` parameter as first additional param could break
>> method declaration and would be misleading.
>>
>> Assuming mutator method is designed to  return mutated clone of immutable
>> object
>> having `$clone` variable could be handled internally without breaking
>> method declaration.
>>
>> Such variable could be unlocked while in mutator method and locked on
>> return.
>> I was thinking about additional check if such mutator returns `$clone` but
>> not `$this`
>> but I don't see the need of it - assuming there is no what to change in
>> some
>> circumstances ther would be also possible to return `$this`.
>>
>> The return type declaration `self` could increase readability, but should
>> not be required,
>> as some developers doesn't already use return types.
>>
> 
> It could look like in this gist
> https://gist.github.com/brzuchal/e7b721e22a19cca42ec0d1f597a23baf
> 

This is exactly how I meant it, yes. I actually prefer it if the
variable just exist in the context instead of passing it as first
argument. It's less obvious that it exists but the same could be said
about $this.

Would it be possible to have this thing just in time instead of
automatically created in every mutator function?

  public mutator function f() {
if (condition) {
  $clone is created;
  return $clone;
}
return $this;
  }

PS: I started overhauling the test cases and error messages and will
create a PR against your branch soon. I will start with the RFC
afterwards. Should I simply edit the RFC in the Wiki or should we manage
this somewhere else?

-- 
Richard "Fleshgrinder" Fussenegger



signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] RFC - Immutable classes

2016-09-04 Thread Michał Brzuchalski
2016-09-04 14:10 GMT+02:00 Michał Brzuchalski :

>
>
> 2016-09-04 10:55 GMT+02:00 Fleshgrinder :
>
>> Hi Chris!
>>
>> On 9/3/2016 5:00 PM, Chris Riley wrote:
>> > - Properties can be declared immutable. Immutable properties may only be
>> > changed under two circumstances: a) In the objects constructor b) If
>> they
>> > are null (This enables setter injection if required)
>> >
>>
>> The constraint b) would make the object mutable and defeat the purpose
>> of the immutable modifier since any property could change at any time if
>> it was NULL at the beginning. Requiring syncing in concurrent
>> environments.
>>
>> On 9/3/2016 5:00 PM, Chris Riley wrote:
>> > - Arrays assigned to immutable properties would not be possible to
>> change
>> >
>>
>> Array support would definitely be very nice. I mean, we have constant
>> arrays already, hence, it is possible.
>>
>> On 9/3/2016 5:00 PM, Chris Riley wrote:
>> > - Objects assigned to immutable properties would be possible to change,
>> so
>> > long as the same object remained assigned to the property.
>> >
>>
>> This would once more lead to mutability and the constraint of
>> immutability would be violated.
>>
>> On 9/3/2016 5:00 PM, Chris Riley wrote:
>> > From a developer adoption point of view, I think these two points are
>> > important to making immutable classes generally useful. Without 1, it
>> will
>> > be a nuisance to use 3rd party libraries esp those which retain
>> > compatibility for PHP < 7.2. Without 2 you block the ability to use
>> setter
>> > injection, which I personally would be in favour of if it meant that
>> devs
>> > stopped using it - it wouldn't - they would simply not use immutable
>> > classes, loosing the benefits thereof.
>> >
>>
>> The adoption of the feature will be halted until 7.2 is widely available
>> in bigger projects. That is most certainly right. However, we should aim
>> for the best, most useful, and future proof solution and not towards the
>> one that's adopted very fast but lacks some important constraints.
>> Having truly immutable objects is required in concurrent scenarios and
>> such scenarios are in the future for PHP and not in the past.
>>
>> Regarding setter injection: I do not see the need for it at all in the
>> context of immutable objects. In the end we are talking about value
>> objects here and they should not have any optional dependencies. Maybe
>> you could come up with a use case to illustrate the need?
>>
>> On 9/3/2016 5:00 PM, Chris Riley wrote:
>> > Dealing with the clone issue some of my ideas since then were:
>> >
>> > - Seal/Unseal (As per Larry's suggestion)
>> > - Parameters to __clone; in this instance the clone method would be
>> allowed
>> > to change properties of the object as well as the constructor. This
>> feels
>> > like it may breach the principal of least surprise as cloning an object
>> no
>> > longer guarantees an exact copy.
>> > - A new magic method __mutate($property, $newvalue) called instead of a
>> > fatal error when a property is changed. This probably lays too many
>> traps
>> > for developers for it to be a good idea.
>> > - Implicitly returning a new object whenever a property is changed.
>> Similar
>> > reservations to the above.
>> > - A new magic method __with($newInstance, $args) and a keyword with
>> that is
>> > used in place of clone eg $x = $y with ($arg1, $arg2); in this instance,
>> > __with receives a clone of $y (after calling __clone) and an array
>> [$arg1,
>> > $arg2] the with magic method is allowed to mutate $newInstance and must
>> > return it. This is currently my favoured solution
>> >
>>
>> How does one know which property is to be mutated in the __with method?
>> You should also not underestimate the performance hit and the branching
>> since you only want to change the properties that changed based on the
>> data from the passed array.
>>
>> I have a third proposal after giving this some more thought. Inspired by
>> Rust's approach to mark mutation explicitly.
>>
>>   final immutable class ValueObject {
>>
>> public $value;
>>
>> public mutator [function] withValue($clone, $value): static {
>>   $clone->value = $value;
>> }
>>
>>   }
>>
>>
> Providing `mutator` | `mut` keyword as method modifier sounds liek a good
> idea,
> althought passing `$clone` parameter as first additional param could break
> method declaration and would be misleading.
>
> Assuming mutator method is designed to  return mutated clone of immutable
> object
> having `$clone` variable could be handled internally without breaking
> method declaration.
>
> Such variable could be unlocked while in mutator method and locked on
> return.
> I was thinking about additional check if such mutator returns `$clone` but
> not `$this`
> but I don't see the need of it - assuming there is no what to change in
> some
> circumstances ther would be also possible to return `$this`.
>
> The return type declaration `self` could 

Re: [PHP-DEV] RFC - Immutable classes

2016-09-04 Thread Michał Brzuchalski
2016-09-04 10:55 GMT+02:00 Fleshgrinder :

> Hi Chris!
>
> On 9/3/2016 5:00 PM, Chris Riley wrote:
> > - Properties can be declared immutable. Immutable properties may only be
> > changed under two circumstances: a) In the objects constructor b) If they
> > are null (This enables setter injection if required)
> >
>
> The constraint b) would make the object mutable and defeat the purpose
> of the immutable modifier since any property could change at any time if
> it was NULL at the beginning. Requiring syncing in concurrent environments.
>
> On 9/3/2016 5:00 PM, Chris Riley wrote:
> > - Arrays assigned to immutable properties would not be possible to change
> >
>
> Array support would definitely be very nice. I mean, we have constant
> arrays already, hence, it is possible.
>
> On 9/3/2016 5:00 PM, Chris Riley wrote:
> > - Objects assigned to immutable properties would be possible to change,
> so
> > long as the same object remained assigned to the property.
> >
>
> This would once more lead to mutability and the constraint of
> immutability would be violated.
>
> On 9/3/2016 5:00 PM, Chris Riley wrote:
> > From a developer adoption point of view, I think these two points are
> > important to making immutable classes generally useful. Without 1, it
> will
> > be a nuisance to use 3rd party libraries esp those which retain
> > compatibility for PHP < 7.2. Without 2 you block the ability to use
> setter
> > injection, which I personally would be in favour of if it meant that devs
> > stopped using it - it wouldn't - they would simply not use immutable
> > classes, loosing the benefits thereof.
> >
>
> The adoption of the feature will be halted until 7.2 is widely available
> in bigger projects. That is most certainly right. However, we should aim
> for the best, most useful, and future proof solution and not towards the
> one that's adopted very fast but lacks some important constraints.
> Having truly immutable objects is required in concurrent scenarios and
> such scenarios are in the future for PHP and not in the past.
>
> Regarding setter injection: I do not see the need for it at all in the
> context of immutable objects. In the end we are talking about value
> objects here and they should not have any optional dependencies. Maybe
> you could come up with a use case to illustrate the need?
>
> On 9/3/2016 5:00 PM, Chris Riley wrote:
> > Dealing with the clone issue some of my ideas since then were:
> >
> > - Seal/Unseal (As per Larry's suggestion)
> > - Parameters to __clone; in this instance the clone method would be
> allowed
> > to change properties of the object as well as the constructor. This feels
> > like it may breach the principal of least surprise as cloning an object
> no
> > longer guarantees an exact copy.
> > - A new magic method __mutate($property, $newvalue) called instead of a
> > fatal error when a property is changed. This probably lays too many traps
> > for developers for it to be a good idea.
> > - Implicitly returning a new object whenever a property is changed.
> Similar
> > reservations to the above.
> > - A new magic method __with($newInstance, $args) and a keyword with that
> is
> > used in place of clone eg $x = $y with ($arg1, $arg2); in this instance,
> > __with receives a clone of $y (after calling __clone) and an array
> [$arg1,
> > $arg2] the with magic method is allowed to mutate $newInstance and must
> > return it. This is currently my favoured solution
> >
>
> How does one know which property is to be mutated in the __with method?
> You should also not underestimate the performance hit and the branching
> since you only want to change the properties that changed based on the
> data from the passed array.
>
> I have a third proposal after giving this some more thought. Inspired by
> Rust's approach to mark mutation explicitly.
>
>   final immutable class ValueObject {
>
> public $value;
>
> public mutator [function] withValue($clone, $value): static {
>   $clone->value = $value;
> }
>
>   }
>
>
Providing `mutator` | `mut` keyword as method modifier sounds liek a good
idea,
althought passing `$clone` parameter as first additional param could break
method declaration and would be misleading.

Assuming mutator method is designed to  return mutated clone of immutable
object
having `$clone` variable could be handled internally without breaking
method declaration.

Such variable could be unlocked while in mutator method and locked on
return.
I was thinking about additional check if such mutator returns `$clone` but
not `$this`
but I don't see the need of it - assuming there is no what to change in some
circumstances ther would be also possible to return `$this`.

The return type declaration `self` could increase readability, but should
not be required,
as some developers doesn't already use return types.


> A mutator function always receives the mutable clone as first argument
> and always returns that one. Users can have a return but 

Re: [PHP-DEV] RFC - Immutable classes

2016-09-04 Thread Fleshgrinder
Hi Chris!

On 9/3/2016 5:00 PM, Chris Riley wrote:
> - Properties can be declared immutable. Immutable properties may only be
> changed under two circumstances: a) In the objects constructor b) If they
> are null (This enables setter injection if required)
>

The constraint b) would make the object mutable and defeat the purpose
of the immutable modifier since any property could change at any time if
it was NULL at the beginning. Requiring syncing in concurrent environments.

On 9/3/2016 5:00 PM, Chris Riley wrote:
> - Arrays assigned to immutable properties would not be possible to change
>

Array support would definitely be very nice. I mean, we have constant
arrays already, hence, it is possible.

On 9/3/2016 5:00 PM, Chris Riley wrote:
> - Objects assigned to immutable properties would be possible to change, so
> long as the same object remained assigned to the property.
> 

This would once more lead to mutability and the constraint of
immutability would be violated.

On 9/3/2016 5:00 PM, Chris Riley wrote:
> From a developer adoption point of view, I think these two points are
> important to making immutable classes generally useful. Without 1, it will
> be a nuisance to use 3rd party libraries esp those which retain
> compatibility for PHP < 7.2. Without 2 you block the ability to use setter
> injection, which I personally would be in favour of if it meant that devs
> stopped using it - it wouldn't - they would simply not use immutable
> classes, loosing the benefits thereof.
> 

The adoption of the feature will be halted until 7.2 is widely available
in bigger projects. That is most certainly right. However, we should aim
for the best, most useful, and future proof solution and not towards the
one that's adopted very fast but lacks some important constraints.
Having truly immutable objects is required in concurrent scenarios and
such scenarios are in the future for PHP and not in the past.

Regarding setter injection: I do not see the need for it at all in the
context of immutable objects. In the end we are talking about value
objects here and they should not have any optional dependencies. Maybe
you could come up with a use case to illustrate the need?

On 9/3/2016 5:00 PM, Chris Riley wrote:
> Dealing with the clone issue some of my ideas since then were:
> 
> - Seal/Unseal (As per Larry's suggestion)
> - Parameters to __clone; in this instance the clone method would be allowed
> to change properties of the object as well as the constructor. This feels
> like it may breach the principal of least surprise as cloning an object no
> longer guarantees an exact copy.
> - A new magic method __mutate($property, $newvalue) called instead of a
> fatal error when a property is changed. This probably lays too many traps
> for developers for it to be a good idea.
> - Implicitly returning a new object whenever a property is changed. Similar
> reservations to the above.
> - A new magic method __with($newInstance, $args) and a keyword with that is
> used in place of clone eg $x = $y with ($arg1, $arg2); in this instance,
> __with receives a clone of $y (after calling __clone) and an array [$arg1,
> $arg2] the with magic method is allowed to mutate $newInstance and must
> return it. This is currently my favoured solution
> 

How does one know which property is to be mutated in the __with method?
You should also not underestimate the performance hit and the branching
since you only want to change the properties that changed based on the
data from the passed array.

I have a third proposal after giving this some more thought. Inspired by
Rust's approach to mark mutation explicitly.

  final immutable class ValueObject {

public $value;

public mutator [function] withValue($clone, $value): static {
  $clone->value = $value;
}

  }

A mutator function always receives the mutable clone as first argument
and always returns that one. Users can have a return but they must
return the clone (hence the static return type declaration).

  $vo1 = new ValueObject(1);
  $vo2 = $vo1->withValue(2);

Calls are of course without the clone as it is handled by the engine.
There is no special branching necessary and no performance hit at all
while the logic is kept in the place where it is required.

-- 
Richard "Fleshgrinder" Fussenegger



signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] RFC - Immutable classes

2016-09-03 Thread Chris Riley
On 2 September 2016 at 15:59, Silvio Marijić 
wrote:

> Michal I'm talking about __clone() callback after clone operation. But I
> agree with you about syntax part.
>
> 2016-09-02 16:46 GMT+02:00 Michał Brzuchalski <
> michal.brzuchal...@gmail.com>
> :
>
> > 02.09.2016 16:29 "Larry Garfield"  napisał(a):
> > >
> > > On 09/02/2016 09:06 AM, Silvio Marijić wrote:
> > >>
> > >> Well at the moment expection is thrown in case when you try to clone
> > >> immutable object. But you do seem to have valid point there regarding
> > >> __clone method. I'm definitely going to give it a thought.
> > >>
> > >> Best,
> > >> Silvio.
> > >>
> > >> 2016-09-02 15:52 GMT+02:00 André Rømcke :
> > >>
> > >>>
> >  On Sep 2, 2016, at 09:10 , Silvio Marijić  >
> > >>>
> > >>> wrote:
> > 
> >  Hi Fleshgrinder,
> > 
> >  Since Michal answered most of the questions, I'll just add some
> notes.
> >  Initially I added restrictions to abstract classes, but I did think
> > about
> >  that over the last couple of days and couldn't find any concrete
> > reason
> > >>>
> > >>> for
> > 
> >  that restriction, so I think I'm going to remove that. As far as
> > cloning,
> >  it is disabled for immutable objects, because you'll end up with the
> > copy
> >  of object that you can not modify. I did mention in Cons sections
> that
> >  cloning is disabled, maybe it should be made more clear.
> > >>>
> > >>>
> > >>> _If_ there are use-cases for it, wouldn’t it also be safe that the
> > clone
> > >>> is allowed to be modified during __clone() and afterwards sealed?
> Like
> > in
> > >>> __construct().
> > >>> And if you don’t want to allow cloning, throw in __clone.
> > >>>
> > >>> Best,
> > >>> André
> > >
> > >
> > > I'd have to agree here.  I love the idea of "lockable" immutable
> > objects.  However, the __clone() method has to be a modifiable area just
> > like __construct() or else it's effectively useless for anything more
> than
> > a trivial object.
> > >
> > > This was one of the main concerns with immutability in the PSR-7
> > discussions.  Consider this sample class, with 8 properties (entirely
> > reasonable for a complex value object):
> > >
> > > immutable class Record {
> > >   public $a;
> > >   public $b;
> > >   public $c;
> > >   public $d;
> > >   public $e;
> > >   public $f;
> > >   public $g;
> > >   public $h;
> > >
> > >   public function __construct($a, $b, $c, $d, $e, $f, $g, $h) {
> > > $this->a = $a;
> > > $this->b = $b;
> > > $this->c = $c;
> > > $this->d = $d;
> > > $this->e = $e;
> > > $this->f = $f;
> > > $this->g = $g;
> > > $this->h = $h;
> > >   }
> > > }
> > >
> > > Now I want a new value object that is the same, except that $d is
> > incremented by 2.  That is, I'm building up the value object over time
> > rather than knowing everything at construct time.  (This is exactly the
> use
> > case of PSR-7.)  I have to do this:
> > >
> > > $r1 = new Record(1, 2, 3, 4, 5, 6, 7, 8);
> > >
> > > $r2 - new Record($r1->a, $r1->b, $r1->c, $r1->d + 2, $1->e, $r1->f,
> > $r1->g, $r1->h);
> > >
> > > That's crazy clunky, and makes immutable objects not very useful.
> Imagine
> > a money object where you had to dissect it to its primitives, tweak one,
> > and then repackage it just to add a dollar figure to it.  That's not
> worth
> > the benefit of being immutable.
> > >
> > > The way PSR-7 addressed that (using fake-immutability, basically), was
> > this:
> > >
> > > class Response {
> > >   // ...
> > >
> > >   protected $statusCode;
> > >
> > >   public function withStatusCode($code) {
> > > $new = clone($this);
> > > $new->statusCode = $code;
> > > return $new;
> > >   }
> > > }
> > >
> >
> > I see only way in somehow invoking closere with cloning. That'll need
> > additional syntax. Clone is left side operator not a function - it's not
> > being called with parenthesis. If this was an object method accessible
> from
> > public it coud gace such closure injected...
> >
> > > That is, outside of the object there's no way to modify it in place,
> but
> > it becomes super easy to get a slightly-modified version of the object:
> > >
> > > $r2 = $r1->withStatusCode(418);
> > >
> > > And because of PHP's copy-on-write support, it's actually surprisingly
> > cheap.
> > >
> > > For language-level immutable objects, we would need some equivalent of
> > that behavior.  I'm not sure exactly what form it should take (explicit
> > lock/unlock commands is all I can think of off hand, which I dislike),
> but
> > that's the use case that would need to be addressed.
> > >
> > > --Larry Garfield
> > >
> > >
> > > --
> > > PHP Internals - PHP Runtime Development Mailing List
> > > To unsubscribe, visit: http://www.php.net/unsub.php
> > >
> >
>
>
>
> --
> Silvio Marijić
> Software Engineer
> 2e Systems
>

The issue with handling updates on clone to 

Re: [PHP-DEV] RFC - Immutable classes

2016-09-03 Thread Fleshgrinder
Hey guys :)

# Abstract Classes
Establishing a contract that any child class of an abstract class has to
be immutable is a totally valid use case in my opinion and it aids
consistency. Otherwise we have the same situation as with final which I
never understood. Actually, even interfaces could benefit from this
modifier.

# Clone
What Larry illustrated is exactly how I build immutable value objects
right now too. However, cloning as we have it is not what we want, we
want a mutable clone while cloning is not allowed to the outside world.
It simply makes no sense to clone a value object for the same reason as
it makes no sense to clone a string.

On a side note, I always change the visibility of the __clone callback
in my value objects to protected/private and disable cloning for the
outside world this way. Cloning a value object is a programming error
and not something that should be catchable and recoverable.

I see various ways to approach this topic and did not include anything
in the previous message because I wanted to think a bit more about it.

## Proposal 1
My first proposal would be to allow mutation within the class itself but
directly creating a copy to ensure integrity and immutability of the
current instance.

  final immutable class ValueObject {

public $value;

public function withValue($value) {
  $this->value = $value;

  return $this;
}

  }

The write is happening in a compatible context (within the class),
however, the $this variable contains a copy of the original now with the
changed value instead of the actual instance. Not returning it means
that it is simply lost and the state of the current instance is never
touched.

  public function withValue($value) {
if ($value !== null) {
  $this->value = $value;
}

return $this;
  }

If $value is null the same instance is returned as is since no write
happened.

The only thing I do not like about this approach is that it is implicit
and not explicit. At the same time it avoids all kinds of problems since
the engine handles everything for you and it requires less typing.

## Proposal 2
The __clone callback returns an instance that is mutable within the
class itself but not from the outside. This is pretty much like the
first proposal but making the clone operation explicit. Note that any
write to the current instance would always be an error here.

  public function withValue($value) {
if ($value !== null) {
  $copy = clone $this;
  $copy->value = $value;

  return $copy;
}

return $this;
  }

Significantly more typing and of course a source of error because the
engine does not take care of the work for you.

# Arrays and Resources
This definitely needs clarification in the RFC since it is a very
important restriction.

# Flyweight
Thinking about it, it's actually possible with the current
implementation to create it by simply leaving of the modifier from the
class.

  final class Flyweight {

private static $instances = [];

public immutable $value;

  }

Hence, forget about the remark.

# Dynamic Properties
Should definitely error on write and it should be explained in the RFC.

-- 
Richard "Fleshgrinder" Fussenegger



signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] RFC - Immutable classes

2016-09-02 Thread Silvio Marijić
Michal I'm talking about __clone() callback after clone operation. But I
agree with you about syntax part.

2016-09-02 16:46 GMT+02:00 Michał Brzuchalski 
:

> 02.09.2016 16:29 "Larry Garfield"  napisał(a):
> >
> > On 09/02/2016 09:06 AM, Silvio Marijić wrote:
> >>
> >> Well at the moment expection is thrown in case when you try to clone
> >> immutable object. But you do seem to have valid point there regarding
> >> __clone method. I'm definitely going to give it a thought.
> >>
> >> Best,
> >> Silvio.
> >>
> >> 2016-09-02 15:52 GMT+02:00 André Rømcke :
> >>
> >>>
>  On Sep 2, 2016, at 09:10 , Silvio Marijić 
> >>>
> >>> wrote:
> 
>  Hi Fleshgrinder,
> 
>  Since Michal answered most of the questions, I'll just add some notes.
>  Initially I added restrictions to abstract classes, but I did think
> about
>  that over the last couple of days and couldn't find any concrete
> reason
> >>>
> >>> for
> 
>  that restriction, so I think I'm going to remove that. As far as
> cloning,
>  it is disabled for immutable objects, because you'll end up with the
> copy
>  of object that you can not modify. I did mention in Cons sections that
>  cloning is disabled, maybe it should be made more clear.
> >>>
> >>>
> >>> _If_ there are use-cases for it, wouldn’t it also be safe that the
> clone
> >>> is allowed to be modified during __clone() and afterwards sealed? Like
> in
> >>> __construct().
> >>> And if you don’t want to allow cloning, throw in __clone.
> >>>
> >>> Best,
> >>> André
> >
> >
> > I'd have to agree here.  I love the idea of "lockable" immutable
> objects.  However, the __clone() method has to be a modifiable area just
> like __construct() or else it's effectively useless for anything more than
> a trivial object.
> >
> > This was one of the main concerns with immutability in the PSR-7
> discussions.  Consider this sample class, with 8 properties (entirely
> reasonable for a complex value object):
> >
> > immutable class Record {
> >   public $a;
> >   public $b;
> >   public $c;
> >   public $d;
> >   public $e;
> >   public $f;
> >   public $g;
> >   public $h;
> >
> >   public function __construct($a, $b, $c, $d, $e, $f, $g, $h) {
> > $this->a = $a;
> > $this->b = $b;
> > $this->c = $c;
> > $this->d = $d;
> > $this->e = $e;
> > $this->f = $f;
> > $this->g = $g;
> > $this->h = $h;
> >   }
> > }
> >
> > Now I want a new value object that is the same, except that $d is
> incremented by 2.  That is, I'm building up the value object over time
> rather than knowing everything at construct time.  (This is exactly the use
> case of PSR-7.)  I have to do this:
> >
> > $r1 = new Record(1, 2, 3, 4, 5, 6, 7, 8);
> >
> > $r2 - new Record($r1->a, $r1->b, $r1->c, $r1->d + 2, $1->e, $r1->f,
> $r1->g, $r1->h);
> >
> > That's crazy clunky, and makes immutable objects not very useful. Imagine
> a money object where you had to dissect it to its primitives, tweak one,
> and then repackage it just to add a dollar figure to it.  That's not worth
> the benefit of being immutable.
> >
> > The way PSR-7 addressed that (using fake-immutability, basically), was
> this:
> >
> > class Response {
> >   // ...
> >
> >   protected $statusCode;
> >
> >   public function withStatusCode($code) {
> > $new = clone($this);
> > $new->statusCode = $code;
> > return $new;
> >   }
> > }
> >
>
> I see only way in somehow invoking closere with cloning. That'll need
> additional syntax. Clone is left side operator not a function - it's not
> being called with parenthesis. If this was an object method accessible from
> public it coud gace such closure injected...
>
> > That is, outside of the object there's no way to modify it in place, but
> it becomes super easy to get a slightly-modified version of the object:
> >
> > $r2 = $r1->withStatusCode(418);
> >
> > And because of PHP's copy-on-write support, it's actually surprisingly
> cheap.
> >
> > For language-level immutable objects, we would need some equivalent of
> that behavior.  I'm not sure exactly what form it should take (explicit
> lock/unlock commands is all I can think of off hand, which I dislike), but
> that's the use case that would need to be addressed.
> >
> > --Larry Garfield
> >
> >
> > --
> > PHP Internals - PHP Runtime Development Mailing List
> > To unsubscribe, visit: http://www.php.net/unsub.php
> >
>



-- 
Silvio Marijić
Software Engineer
2e Systems


Re: [PHP-DEV] RFC - Immutable classes

2016-09-02 Thread Michał Brzuchalski
02.09.2016 16:29 "Larry Garfield"  napisał(a):
>
> On 09/02/2016 09:06 AM, Silvio Marijić wrote:
>>
>> Well at the moment expection is thrown in case when you try to clone
>> immutable object. But you do seem to have valid point there regarding
>> __clone method. I'm definitely going to give it a thought.
>>
>> Best,
>> Silvio.
>>
>> 2016-09-02 15:52 GMT+02:00 André Rømcke :
>>
>>>
 On Sep 2, 2016, at 09:10 , Silvio Marijić 
>>>
>>> wrote:

 Hi Fleshgrinder,

 Since Michal answered most of the questions, I'll just add some notes.
 Initially I added restrictions to abstract classes, but I did think
about
 that over the last couple of days and couldn't find any concrete reason
>>>
>>> for

 that restriction, so I think I'm going to remove that. As far as
cloning,
 it is disabled for immutable objects, because you'll end up with the
copy
 of object that you can not modify. I did mention in Cons sections that
 cloning is disabled, maybe it should be made more clear.
>>>
>>>
>>> _If_ there are use-cases for it, wouldn’t it also be safe that the clone
>>> is allowed to be modified during __clone() and afterwards sealed? Like
in
>>> __construct().
>>> And if you don’t want to allow cloning, throw in __clone.
>>>
>>> Best,
>>> André
>
>
> I'd have to agree here.  I love the idea of "lockable" immutable
objects.  However, the __clone() method has to be a modifiable area just
like __construct() or else it's effectively useless for anything more than
a trivial object.
>
> This was one of the main concerns with immutability in the PSR-7
discussions.  Consider this sample class, with 8 properties (entirely
reasonable for a complex value object):
>
> immutable class Record {
>   public $a;
>   public $b;
>   public $c;
>   public $d;
>   public $e;
>   public $f;
>   public $g;
>   public $h;
>
>   public function __construct($a, $b, $c, $d, $e, $f, $g, $h) {
> $this->a = $a;
> $this->b = $b;
> $this->c = $c;
> $this->d = $d;
> $this->e = $e;
> $this->f = $f;
> $this->g = $g;
> $this->h = $h;
>   }
> }
>
> Now I want a new value object that is the same, except that $d is
incremented by 2.  That is, I'm building up the value object over time
rather than knowing everything at construct time.  (This is exactly the use
case of PSR-7.)  I have to do this:
>
> $r1 = new Record(1, 2, 3, 4, 5, 6, 7, 8);
>
> $r2 - new Record($r1->a, $r1->b, $r1->c, $r1->d + 2, $1->e, $r1->f,
$r1->g, $r1->h);
>
> That's crazy clunky, and makes immutable objects not very useful. Imagine
a money object where you had to dissect it to its primitives, tweak one,
and then repackage it just to add a dollar figure to it.  That's not worth
the benefit of being immutable.
>
> The way PSR-7 addressed that (using fake-immutability, basically), was
this:
>
> class Response {
>   // ...
>
>   protected $statusCode;
>
>   public function withStatusCode($code) {
> $new = clone($this);
> $new->statusCode = $code;
> return $new;
>   }
> }
>

I see only way in somehow invoking closere with cloning. That'll need
additional syntax. Clone is left side operator not a function - it's not
being called with parenthesis. If this was an object method accessible from
public it coud gace such closure injected...

> That is, outside of the object there's no way to modify it in place, but
it becomes super easy to get a slightly-modified version of the object:
>
> $r2 = $r1->withStatusCode(418);
>
> And because of PHP's copy-on-write support, it's actually surprisingly
cheap.
>
> For language-level immutable objects, we would need some equivalent of
that behavior.  I'm not sure exactly what form it should take (explicit
lock/unlock commands is all I can think of off hand, which I dislike), but
that's the use case that would need to be addressed.
>
> --Larry Garfield
>
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>


Re: [PHP-DEV] RFC - Immutable classes

2016-09-02 Thread Silvio Marijić
Basically I'm concerned about __clone() since you can not pass parameters

2016-09-02 16:44 GMT+02:00 Silvio Marijić :

> Hi Larry,
> I'm aware of that but we do have make some strong constraints there
> otherwise we are undermining the strong guarantee of immutability. I would
> agree to allow object modification only and only *inside* __construct()
> and __clone methods. I'm trying to come up with idea how would that look
> like. If you guys have some suggestions, that would be great.
>
> 2016-09-02 16:27 GMT+02:00 Larry Garfield :
>
>> On 09/02/2016 09:06 AM, Silvio Marijić wrote:
>>
>>> Well at the moment expection is thrown in case when you try to clone
>>> immutable object. But you do seem to have valid point there regarding
>>> __clone method. I'm definitely going to give it a thought.
>>>
>>> Best,
>>> Silvio.
>>>
>>> 2016-09-02 15:52 GMT+02:00 André Rømcke :
>>>
>>>
 On Sep 2, 2016, at 09:10 , Silvio Marijić 
>
 wrote:

> Hi Fleshgrinder,
>
> Since Michal answered most of the questions, I'll just add some notes.
> Initially I added restrictions to abstract classes, but I did think
> about
> that over the last couple of days and couldn't find any concrete reason
>
 for

> that restriction, so I think I'm going to remove that. As far as
> cloning,
> it is disabled for immutable objects, because you'll end up with the
> copy
> of object that you can not modify. I did mention in Cons sections that
> cloning is disabled, maybe it should be made more clear.
>

 _If_ there are use-cases for it, wouldn’t it also be safe that the clone
 is allowed to be modified during __clone() and afterwards sealed? Like
 in
 __construct().
 And if you don’t want to allow cloning, throw in __clone.

 Best,
 André

>>>
>> I'd have to agree here.  I love the idea of "lockable" immutable
>> objects.  However, the __clone() method has to be a modifiable area just
>> like __construct() or else it's effectively useless for anything more than
>> a trivial object.
>>
>> This was one of the main concerns with immutability in the PSR-7
>> discussions.  Consider this sample class, with 8 properties (entirely
>> reasonable for a complex value object):
>>
>> immutable class Record {
>>   public $a;
>>   public $b;
>>   public $c;
>>   public $d;
>>   public $e;
>>   public $f;
>>   public $g;
>>   public $h;
>>
>>   public function __construct($a, $b, $c, $d, $e, $f, $g, $h) {
>> $this->a = $a;
>> $this->b = $b;
>> $this->c = $c;
>> $this->d = $d;
>> $this->e = $e;
>> $this->f = $f;
>> $this->g = $g;
>> $this->h = $h;
>>   }
>> }
>>
>> Now I want a new value object that is the same, except that $d is
>> incremented by 2.  That is, I'm building up the value object over time
>> rather than knowing everything at construct time.  (This is exactly the use
>> case of PSR-7.)  I have to do this:
>>
>> $r1 = new Record(1, 2, 3, 4, 5, 6, 7, 8);
>>
>> $r2 - new Record($r1->a, $r1->b, $r1->c, $r1->d + 2, $1->e, $r1->f,
>> $r1->g, $r1->h);
>>
>> That's crazy clunky, and makes immutable objects not very useful. Imagine
>> a money object where you had to dissect it to its primitives, tweak one,
>> and then repackage it just to add a dollar figure to it.  That's not worth
>> the benefit of being immutable.
>>
>> The way PSR-7 addressed that (using fake-immutability, basically), was
>> this:
>>
>> class Response {
>>   // ...
>>
>>   protected $statusCode;
>>
>>   public function withStatusCode($code) {
>> $new = clone($this);
>> $new->statusCode = $code;
>> return $new;
>>   }
>> }
>>
>> That is, outside of the object there's no way to modify it in place, but
>> it becomes super easy to get a slightly-modified version of the object:
>>
>> $r2 = $r1->withStatusCode(418);
>>
>> And because of PHP's copy-on-write support, it's actually surprisingly
>> cheap.
>>
>> For language-level immutable objects, we would need some equivalent of
>> that behavior.  I'm not sure exactly what form it should take (explicit
>> lock/unlock commands is all I can think of off hand, which I dislike), but
>> that's the use case that would need to be addressed.
>>
>> --Larry Garfield
>>
>>
>> --
>> PHP Internals - PHP Runtime Development Mailing List
>> To unsubscribe, visit: http://www.php.net/unsub.php
>>
>>
>
>
> --
> Silvio Marijić
> Software Engineer
> 2e Systems
>



-- 
Silvio Marijić
Software Engineer
2e Systems


Re: [PHP-DEV] RFC - Immutable classes

2016-09-02 Thread Silvio Marijić
Hi Larry,
I'm aware of that but we do have make some strong constraints there
otherwise we are undermining the strong guarantee of immutability. I would
agree to allow object modification only and only *inside* __construct() and
__clone methods. I'm trying to come up with idea how would that look like.
If you guys have some suggestions, that would be great.

2016-09-02 16:27 GMT+02:00 Larry Garfield :

> On 09/02/2016 09:06 AM, Silvio Marijić wrote:
>
>> Well at the moment expection is thrown in case when you try to clone
>> immutable object. But you do seem to have valid point there regarding
>> __clone method. I'm definitely going to give it a thought.
>>
>> Best,
>> Silvio.
>>
>> 2016-09-02 15:52 GMT+02:00 André Rømcke :
>>
>>
>>> On Sep 2, 2016, at 09:10 , Silvio Marijić 

>>> wrote:
>>>
 Hi Fleshgrinder,

 Since Michal answered most of the questions, I'll just add some notes.
 Initially I added restrictions to abstract classes, but I did think
 about
 that over the last couple of days and couldn't find any concrete reason

>>> for
>>>
 that restriction, so I think I'm going to remove that. As far as
 cloning,
 it is disabled for immutable objects, because you'll end up with the
 copy
 of object that you can not modify. I did mention in Cons sections that
 cloning is disabled, maybe it should be made more clear.

>>>
>>> _If_ there are use-cases for it, wouldn’t it also be safe that the clone
>>> is allowed to be modified during __clone() and afterwards sealed? Like in
>>> __construct().
>>> And if you don’t want to allow cloning, throw in __clone.
>>>
>>> Best,
>>> André
>>>
>>
> I'd have to agree here.  I love the idea of "lockable" immutable objects.
> However, the __clone() method has to be a modifiable area just like
> __construct() or else it's effectively useless for anything more than a
> trivial object.
>
> This was one of the main concerns with immutability in the PSR-7
> discussions.  Consider this sample class, with 8 properties (entirely
> reasonable for a complex value object):
>
> immutable class Record {
>   public $a;
>   public $b;
>   public $c;
>   public $d;
>   public $e;
>   public $f;
>   public $g;
>   public $h;
>
>   public function __construct($a, $b, $c, $d, $e, $f, $g, $h) {
> $this->a = $a;
> $this->b = $b;
> $this->c = $c;
> $this->d = $d;
> $this->e = $e;
> $this->f = $f;
> $this->g = $g;
> $this->h = $h;
>   }
> }
>
> Now I want a new value object that is the same, except that $d is
> incremented by 2.  That is, I'm building up the value object over time
> rather than knowing everything at construct time.  (This is exactly the use
> case of PSR-7.)  I have to do this:
>
> $r1 = new Record(1, 2, 3, 4, 5, 6, 7, 8);
>
> $r2 - new Record($r1->a, $r1->b, $r1->c, $r1->d + 2, $1->e, $r1->f,
> $r1->g, $r1->h);
>
> That's crazy clunky, and makes immutable objects not very useful. Imagine
> a money object where you had to dissect it to its primitives, tweak one,
> and then repackage it just to add a dollar figure to it.  That's not worth
> the benefit of being immutable.
>
> The way PSR-7 addressed that (using fake-immutability, basically), was
> this:
>
> class Response {
>   // ...
>
>   protected $statusCode;
>
>   public function withStatusCode($code) {
> $new = clone($this);
> $new->statusCode = $code;
> return $new;
>   }
> }
>
> That is, outside of the object there's no way to modify it in place, but
> it becomes super easy to get a slightly-modified version of the object:
>
> $r2 = $r1->withStatusCode(418);
>
> And because of PHP's copy-on-write support, it's actually surprisingly
> cheap.
>
> For language-level immutable objects, we would need some equivalent of
> that behavior.  I'm not sure exactly what form it should take (explicit
> lock/unlock commands is all I can think of off hand, which I dislike), but
> that's the use case that would need to be addressed.
>
> --Larry Garfield
>
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>


-- 
Silvio Marijić
Software Engineer
2e Systems


Re: [PHP-DEV] RFC - Immutable classes

2016-09-02 Thread Larry Garfield

On 09/02/2016 09:06 AM, Silvio Marijić wrote:

Well at the moment expection is thrown in case when you try to clone
immutable object. But you do seem to have valid point there regarding
__clone method. I'm definitely going to give it a thought.

Best,
Silvio.

2016-09-02 15:52 GMT+02:00 André Rømcke :




On Sep 2, 2016, at 09:10 , Silvio Marijić 

wrote:

Hi Fleshgrinder,

Since Michal answered most of the questions, I'll just add some notes.
Initially I added restrictions to abstract classes, but I did think about
that over the last couple of days and couldn't find any concrete reason

for

that restriction, so I think I'm going to remove that. As far as cloning,
it is disabled for immutable objects, because you'll end up with the copy
of object that you can not modify. I did mention in Cons sections that
cloning is disabled, maybe it should be made more clear.


_If_ there are use-cases for it, wouldn’t it also be safe that the clone
is allowed to be modified during __clone() and afterwards sealed? Like in
__construct().
And if you don’t want to allow cloning, throw in __clone.

Best,
André


I'd have to agree here.  I love the idea of "lockable" immutable 
objects.  However, the __clone() method has to be a modifiable area just 
like __construct() or else it's effectively useless for anything more 
than a trivial object.


This was one of the main concerns with immutability in the PSR-7 
discussions.  Consider this sample class, with 8 properties (entirely 
reasonable for a complex value object):


immutable class Record {
  public $a;
  public $b;
  public $c;
  public $d;
  public $e;
  public $f;
  public $g;
  public $h;

  public function __construct($a, $b, $c, $d, $e, $f, $g, $h) {
$this->a = $a;
$this->b = $b;
$this->c = $c;
$this->d = $d;
$this->e = $e;
$this->f = $f;
$this->g = $g;
$this->h = $h;
  }
}

Now I want a new value object that is the same, except that $d is 
incremented by 2.  That is, I'm building up the value object over time 
rather than knowing everything at construct time.  (This is exactly the 
use case of PSR-7.)  I have to do this:


$r1 = new Record(1, 2, 3, 4, 5, 6, 7, 8);

$r2 - new Record($r1->a, $r1->b, $r1->c, $r1->d + 2, $1->e, $r1->f, 
$r1->g, $r1->h);


That's crazy clunky, and makes immutable objects not very useful. 
Imagine a money object where you had to dissect it to its primitives, 
tweak one, and then repackage it just to add a dollar figure to it.  
That's not worth the benefit of being immutable.


The way PSR-7 addressed that (using fake-immutability, basically), was this:

class Response {
  // ...

  protected $statusCode;

  public function withStatusCode($code) {
$new = clone($this);
$new->statusCode = $code;
return $new;
  }
}

That is, outside of the object there's no way to modify it in place, but 
it becomes super easy to get a slightly-modified version of the object:


$r2 = $r1->withStatusCode(418);

And because of PHP's copy-on-write support, it's actually surprisingly 
cheap.


For language-level immutable objects, we would need some equivalent of 
that behavior.  I'm not sure exactly what form it should take (explicit 
lock/unlock commands is all I can think of off hand, which I dislike), 
but that's the use case that would need to be addressed.


--Larry Garfield

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] RFC - Immutable classes

2016-09-02 Thread Silvio Marijić
Well at the moment expection is thrown in case when you try to clone
immutable object. But you do seem to have valid point there regarding
__clone method. I'm definitely going to give it a thought.

Best,
Silvio.

2016-09-02 15:52 GMT+02:00 André Rømcke :

>
>
> > On Sep 2, 2016, at 09:10 , Silvio Marijić 
> wrote:
> >
> > Hi Fleshgrinder,
> >
> > Since Michal answered most of the questions, I'll just add some notes.
> > Initially I added restrictions to abstract classes, but I did think about
> > that over the last couple of days and couldn't find any concrete reason
> for
> > that restriction, so I think I'm going to remove that. As far as cloning,
> > it is disabled for immutable objects, because you'll end up with the copy
> > of object that you can not modify. I did mention in Cons sections that
> > cloning is disabled, maybe it should be made more clear.
>
>
> _If_ there are use-cases for it, wouldn’t it also be safe that the clone
> is allowed to be modified during __clone() and afterwards sealed? Like in
> __construct().
> And if you don’t want to allow cloning, throw in __clone.
>
> Best,
> André
>
>
> >
> > Best,
> > Silvio.
> >
> > 2016-09-02 4:23 GMT+02:00 Michał Brzuchalski :
> >
> >> Firstly, thanks for your interest.
> >> My answers are inline.
> >>
> >> 2016-09-01 23:48 GMT+02:00 Mathieu Rochette :
> >>
> >>>
> >>>
> >>> On 09/01/2016 09:12 PM, Fleshgrinder wrote:
>  On 9/1/2016 3:49 PM, Silvio Marijić wrote:
> > Hi Andre,
> >
> > Here is RFC https://wiki.php.net/rfc/immutability and you have link
> >> to
> > implementation github. Any suggestions and feedback are more then
> >>> welcome.
> >
> > Best,
> > Silvio
> >
>  Hi Silvio,
> 
>  very nice work you guys did here! :)
> >>> indeed! nice to see this going forward
> 
>  Abstract classes are not mentioned at all in the RFC. However, there
> is
>  a test case from which it is clear that abstract classes cannot be
>  immutable. Are there any reasons for this restrictions?
> 
>  What about array and resource values? Not mentioned in the RFC.
> >>> I guess they are not authorized in immutable classes as they are not
> >>> immutable themselves, but I think it could be explained
> >>>
> >>
> >> Yes that could be explained, they are actually not authorized because we
> >> cannot guarantee developer will use them internally only. So in case
> this
> >> property will interact with immutable object state should be also
> >> immutable.
> >>
> >>
> 
>  The fact that cloning is not possible should also be extended in the
>  RFC. I mean, it's clear to me but maybe not to others. Remember that
> >> the
>  RFC is the main source of information for the feature (e.g. to
> generate
>  documentation).
> >>> agreed, I don't get why it's not possible :/
> 
> >>>
> >>
> >> I think any RFC enchancements in this area is welcome.
> >>
> >>
>  Why the restrictions that all properties of an immutable class that
> >> take
>  objects must be immutable too? It's clear why an immutable property
> >> must
>  contain an immutable class but the inheritance from the class to the
>  properties is not consistent with how things work. An immutable class
>  might want to contain an internal cache (e.g. flyweight pattern).
> 
>   immutable final class Flyweight {
> 
> private static $instances = [];
> 
> public immutable $value;
> 
> private function __construct($value) {
>   $this->value = $value;
> }
> 
> public static function ENUM_ORD() {
>   if (isset(self::$instances[1]) === false) {
> self::$instances[1] = new self(1);
>   }
> 
>   return self::$instances[1];
> }
> 
>   }
> 
>   $o1 = Flyweight::ENUM_ORD();
>   $o2 = Flyweight::ENUM_ORD();
> 
>   var_dump($o1 === $o2); // bool(true)
> >>> I can understand the usecase, but then, how could  the language ensure
> >>> the class is immutable
> >>
> >>
> >> It cannot be ensured while non-immutable property will exists in
> immutable
> >> object.
> >>
> >>
> >>> side note: what about access (read & write) to undefined properties ?
> >>>
> >>
> >> You mean properties which are declared and default null and never
> changed
> >> during object instantiation?
> >>
> >>
> 
>  Note that we could add the restriction that an immutable class that
>  should be used in a threading context must contain only immutable
>  properties in the future when the need arises. However, for now I do
> >> not
>  see the need to inherit the modifier from the class to its properties
>  and I see use cases where the developer wants more control.
> >>>
> >>
> >> We agreed that it would be best for ensuring the object state is
> immutable
> >> (that implies it can be deeply frozen for 

Re: [PHP-DEV] RFC - Immutable classes

2016-09-02 Thread Silvio Marijić
>From point of immutability of object, there is no difference if property is
defined or not, so you are correct, last line in your code will throw an
error.

2016-09-02 11:06 GMT+02:00 Mathieu Rochette :

> thank you for the clarification, more questions inline :)
>
>
> On 09/02/2016 04:23 AM, Michał Brzuchalski wrote:
> > Firstly, thanks for your interest.
> > My answers are inline.
> >
> > 2016-09-01 23:48 GMT+02:00 Mathieu Rochette :
> >
> >>
> >> On 09/01/2016 09:12 PM, Fleshgrinder wrote:
> >>> On 9/1/2016 3:49 PM, Silvio Marijić wrote:
>  Hi Andre,
> 
>  Here is RFC https://wiki.php.net/rfc/immutability and you have link
> to
>  implementation github. Any suggestions and feedback are more then
> >> welcome.
>  Best,
>  Silvio
> 
> >>> Hi Silvio,
> >>>
> >>> very nice work you guys did here! :)
> >> indeed! nice to see this going forward
> >>> Abstract classes are not mentioned at all in the RFC. However, there is
> >>> a test case from which it is clear that abstract classes cannot be
> >>> immutable. Are there any reasons for this restrictions?
> >>>
> >>> What about array and resource values? Not mentioned in the RFC.
> >> I guess they are not authorized in immutable classes as they are not
> >> immutable themselves, but I think it could be explained
> >>
> > Yes that could be explained, they are actually not authorized because we
> > cannot guarantee developer will use them internally only. So in case this
> > property will interact with immutable object state should be also
> immutable.
> >
> >
> >>> The fact that cloning is not possible should also be extended in the
> >>> RFC. I mean, it's clear to me but maybe not to others. Remember that
> the
> >>> RFC is the main source of information for the feature (e.g. to generate
> >>> documentation).
> >> agreed, I don't get why it's not possible :/
> > I think any RFC enchancements in this area is welcome.
> >
> >
> >>> Why the restrictions that all properties of an immutable class that
> take
> >>> objects must be immutable too? It's clear why an immutable property
> must
> >>> contain an immutable class but the inheritance from the class to the
> >>> properties is not consistent with how things work. An immutable class
> >>> might want to contain an internal cache (e.g. flyweight pattern).
> >>>
> >>>   immutable final class Flyweight {
> >>>
> >>> private static $instances = [];
> >>>
> >>> public immutable $value;
> >>>
> >>> private function __construct($value) {
> >>>   $this->value = $value;
> >>> }
> >>>
> >>> public static function ENUM_ORD() {
> >>>   if (isset(self::$instances[1]) === false) {
> >>> self::$instances[1] = new self(1);
> >>>   }
> >>>
> >>>   return self::$instances[1];
> >>> }
> >>>
> >>>   }
> >>>
> >>>   $o1 = Flyweight::ENUM_ORD();
> >>>   $o2 = Flyweight::ENUM_ORD();
> >>>
> >>>   var_dump($o1 === $o2); // bool(true)
> >> I can understand the usecase, but then, how could  the language ensure
> >> the class is immutable
> >
> > It cannot be ensured while non-immutable property will exists in
> immutable
> > object.
> >
> >
> >> side note: what about access (read & write) to undefined properties ?
> >>
> > You mean properties which are declared and default null and never changed
> > during object instantiation?
> I meant properties which are not declared at all, eg:
>
> class foo {
> }
> $f = new foo();
> var_dump($f->bar);
> $f->bar = 'taz';
>
> I expect it to print null and throw an error on write access, but it's
> just to be sure. actually I guest it should be the same than with
> declared with default null and never changed during object instantiation
>
> >
> >
> >>> Note that we could add the restriction that an immutable class that
> >>> should be used in a threading context must contain only immutable
> >>> properties in the future when the need arises. However, for now I do
> not
> >>> see the need to inherit the modifier from the class to its properties
> >>> and I see use cases where the developer wants more control.
> > We agreed that it would be best for ensuring the object state is
> immutable
> > (that implies it can be deeply frozen for writes as deep as all his
> > properties
> > and properties object properties etc.)
> >
> >
> >>> The test cases cover the most stuff but not everything and could be
> >>> extended. There are other things with the PR but I will check it out
> and
> >>> create a PR against your branch with that so you can review it. (Might
> >>> take a while so bare with me.)
> >>>
> >> The RFC contains several grammatical issues. I could help you with that
> >>> too if you want.
> >>>
> > As abowe any RFC enchancements are welcome :)
> >
> >
> >>> There is a lot of diff noise in the ext/tokenizer/tokenizer_data.c
> file.
> >>>
> >> --
> >> Mathieu Rochette
> >>
> >>
> >> --
> >> PHP Internals - PHP Runtime Development Mailing List
> >> To unsubscribe, visit: 

Re: [PHP-DEV] RFC - Immutable classes

2016-09-02 Thread Mathieu Rochette
thank you for the clarification, more questions inline :)


On 09/02/2016 04:23 AM, Michał Brzuchalski wrote:
> Firstly, thanks for your interest.
> My answers are inline.
>
> 2016-09-01 23:48 GMT+02:00 Mathieu Rochette :
>
>>
>> On 09/01/2016 09:12 PM, Fleshgrinder wrote:
>>> On 9/1/2016 3:49 PM, Silvio Marijić wrote:
 Hi Andre,

 Here is RFC https://wiki.php.net/rfc/immutability and you have link to
 implementation github. Any suggestions and feedback are more then
>> welcome.
 Best,
 Silvio

>>> Hi Silvio,
>>>
>>> very nice work you guys did here! :)
>> indeed! nice to see this going forward
>>> Abstract classes are not mentioned at all in the RFC. However, there is
>>> a test case from which it is clear that abstract classes cannot be
>>> immutable. Are there any reasons for this restrictions?
>>>
>>> What about array and resource values? Not mentioned in the RFC.
>> I guess they are not authorized in immutable classes as they are not
>> immutable themselves, but I think it could be explained
>>
> Yes that could be explained, they are actually not authorized because we
> cannot guarantee developer will use them internally only. So in case this
> property will interact with immutable object state should be also immutable.
>
>
>>> The fact that cloning is not possible should also be extended in the
>>> RFC. I mean, it's clear to me but maybe not to others. Remember that the
>>> RFC is the main source of information for the feature (e.g. to generate
>>> documentation).
>> agreed, I don't get why it's not possible :/
> I think any RFC enchancements in this area is welcome.
>
>
>>> Why the restrictions that all properties of an immutable class that take
>>> objects must be immutable too? It's clear why an immutable property must
>>> contain an immutable class but the inheritance from the class to the
>>> properties is not consistent with how things work. An immutable class
>>> might want to contain an internal cache (e.g. flyweight pattern).
>>>
>>>   immutable final class Flyweight {
>>>
>>> private static $instances = [];
>>>
>>> public immutable $value;
>>>
>>> private function __construct($value) {
>>>   $this->value = $value;
>>> }
>>>
>>> public static function ENUM_ORD() {
>>>   if (isset(self::$instances[1]) === false) {
>>> self::$instances[1] = new self(1);
>>>   }
>>>
>>>   return self::$instances[1];
>>> }
>>>
>>>   }
>>>
>>>   $o1 = Flyweight::ENUM_ORD();
>>>   $o2 = Flyweight::ENUM_ORD();
>>>
>>>   var_dump($o1 === $o2); // bool(true)
>> I can understand the usecase, but then, how could  the language ensure
>> the class is immutable
>
> It cannot be ensured while non-immutable property will exists in immutable
> object.
>
>
>> side note: what about access (read & write) to undefined properties ?
>>
> You mean properties which are declared and default null and never changed
> during object instantiation?
I meant properties which are not declared at all, eg:

class foo {
}
$f = new foo();
var_dump($f->bar);
$f->bar = 'taz';

I expect it to print null and throw an error on write access, but it's
just to be sure. actually I guest it should be the same than with
declared with default null and never changed during object instantiation

>
>
>>> Note that we could add the restriction that an immutable class that
>>> should be used in a threading context must contain only immutable
>>> properties in the future when the need arises. However, for now I do not
>>> see the need to inherit the modifier from the class to its properties
>>> and I see use cases where the developer wants more control.
> We agreed that it would be best for ensuring the object state is immutable
> (that implies it can be deeply frozen for writes as deep as all his
> properties
> and properties object properties etc.)
>
>
>>> The test cases cover the most stuff but not everything and could be
>>> extended. There are other things with the PR but I will check it out and
>>> create a PR against your branch with that so you can review it. (Might
>>> take a while so bare with me.)
>>>
>> The RFC contains several grammatical issues. I could help you with that
>>> too if you want.
>>>
> As abowe any RFC enchancements are welcome :)
>
>
>>> There is a lot of diff noise in the ext/tokenizer/tokenizer_data.c file.
>>>
>> --
>> Mathieu Rochette
>>
>>
>> --
>> PHP Internals - PHP Runtime Development Mailing List
>> To unsubscribe, visit: http://www.php.net/unsub.php
>>
>>
>

-- 
Mathieu Rochette


-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] RFC - Immutable classes

2016-09-02 Thread Silvio Marijić
Hi Fleshgrinder,

Since Michal answered most of the questions, I'll just add some notes.
Initially I added restrictions to abstract classes, but I did think about
that over the last couple of days and couldn't find any concrete reason for
that restriction, so I think I'm going to remove that. As far as cloning,
it is disabled for immutable objects, because you'll end up with the copy
of object that you can not modify. I did mention in Cons sections that
cloning is disabled, maybe it should be made more clear.

Best,
Silvio.

2016-09-02 4:23 GMT+02:00 Michał Brzuchalski :

> Firstly, thanks for your interest.
> My answers are inline.
>
> 2016-09-01 23:48 GMT+02:00 Mathieu Rochette :
>
> >
> >
> > On 09/01/2016 09:12 PM, Fleshgrinder wrote:
> > > On 9/1/2016 3:49 PM, Silvio Marijić wrote:
> > >> Hi Andre,
> > >>
> > >> Here is RFC https://wiki.php.net/rfc/immutability and you have link
> to
> > >> implementation github. Any suggestions and feedback are more then
> > welcome.
> > >>
> > >> Best,
> > >> Silvio
> > >>
> > > Hi Silvio,
> > >
> > > very nice work you guys did here! :)
> > indeed! nice to see this going forward
> > >
> > > Abstract classes are not mentioned at all in the RFC. However, there is
> > > a test case from which it is clear that abstract classes cannot be
> > > immutable. Are there any reasons for this restrictions?
> > >
> > > What about array and resource values? Not mentioned in the RFC.
> > I guess they are not authorized in immutable classes as they are not
> > immutable themselves, but I think it could be explained
> >
>
> Yes that could be explained, they are actually not authorized because we
> cannot guarantee developer will use them internally only. So in case this
> property will interact with immutable object state should be also
> immutable.
>
>
> > >
> > > The fact that cloning is not possible should also be extended in the
> > > RFC. I mean, it's clear to me but maybe not to others. Remember that
> the
> > > RFC is the main source of information for the feature (e.g. to generate
> > > documentation).
> > agreed, I don't get why it's not possible :/
> > >
> >
>
> I think any RFC enchancements in this area is welcome.
>
>
> > > Why the restrictions that all properties of an immutable class that
> take
> > > objects must be immutable too? It's clear why an immutable property
> must
> > > contain an immutable class but the inheritance from the class to the
> > > properties is not consistent with how things work. An immutable class
> > > might want to contain an internal cache (e.g. flyweight pattern).
> > >
> > >   immutable final class Flyweight {
> > >
> > > private static $instances = [];
> > >
> > > public immutable $value;
> > >
> > > private function __construct($value) {
> > >   $this->value = $value;
> > > }
> > >
> > > public static function ENUM_ORD() {
> > >   if (isset(self::$instances[1]) === false) {
> > > self::$instances[1] = new self(1);
> > >   }
> > >
> > >   return self::$instances[1];
> > > }
> > >
> > >   }
> > >
> > >   $o1 = Flyweight::ENUM_ORD();
> > >   $o2 = Flyweight::ENUM_ORD();
> > >
> > >   var_dump($o1 === $o2); // bool(true)
> > I can understand the usecase, but then, how could  the language ensure
> > the class is immutable
>
>
> It cannot be ensured while non-immutable property will exists in immutable
> object.
>
>
> > side note: what about access (read & write) to undefined properties ?
> >
>
> You mean properties which are declared and default null and never changed
> during object instantiation?
>
>
> > >
> > > Note that we could add the restriction that an immutable class that
> > > should be used in a threading context must contain only immutable
> > > properties in the future when the need arises. However, for now I do
> not
> > > see the need to inherit the modifier from the class to its properties
> > > and I see use cases where the developer wants more control.
> >
>
> We agreed that it would be best for ensuring the object state is immutable
> (that implies it can be deeply frozen for writes as deep as all his
> properties
> and properties object properties etc.)
>
>
> > >
> > > The test cases cover the most stuff but not everything and could be
> > > extended. There are other things with the PR but I will check it out
> and
> > > create a PR against your branch with that so you can review it. (Might
> > > take a while so bare with me.)
> > >
> >
> > The RFC contains several grammatical issues. I could help you with that
> > > too if you want.
> > >
> >
>
> As abowe any RFC enchancements are welcome :)
>
>
> > > There is a lot of diff noise in the ext/tokenizer/tokenizer_data.c
> file.
> > >
> >
> > --
> > Mathieu Rochette
> >
> >
> > --
> > PHP Internals - PHP Runtime Development Mailing List
> > To unsubscribe, visit: http://www.php.net/unsub.php
> >
> >
>
>
> --
> regards / pozdrawiam,
> --
> Michał Brzuchalski
> brzuchalski.com
>




Re: [PHP-DEV] RFC - Immutable classes

2016-09-01 Thread Michał Brzuchalski
Firstly, thanks for your interest.
My answers are inline.

2016-09-01 23:48 GMT+02:00 Mathieu Rochette :

>
>
> On 09/01/2016 09:12 PM, Fleshgrinder wrote:
> > On 9/1/2016 3:49 PM, Silvio Marijić wrote:
> >> Hi Andre,
> >>
> >> Here is RFC https://wiki.php.net/rfc/immutability and you have link to
> >> implementation github. Any suggestions and feedback are more then
> welcome.
> >>
> >> Best,
> >> Silvio
> >>
> > Hi Silvio,
> >
> > very nice work you guys did here! :)
> indeed! nice to see this going forward
> >
> > Abstract classes are not mentioned at all in the RFC. However, there is
> > a test case from which it is clear that abstract classes cannot be
> > immutable. Are there any reasons for this restrictions?
> >
> > What about array and resource values? Not mentioned in the RFC.
> I guess they are not authorized in immutable classes as they are not
> immutable themselves, but I think it could be explained
>

Yes that could be explained, they are actually not authorized because we
cannot guarantee developer will use them internally only. So in case this
property will interact with immutable object state should be also immutable.


> >
> > The fact that cloning is not possible should also be extended in the
> > RFC. I mean, it's clear to me but maybe not to others. Remember that the
> > RFC is the main source of information for the feature (e.g. to generate
> > documentation).
> agreed, I don't get why it's not possible :/
> >
>

I think any RFC enchancements in this area is welcome.


> > Why the restrictions that all properties of an immutable class that take
> > objects must be immutable too? It's clear why an immutable property must
> > contain an immutable class but the inheritance from the class to the
> > properties is not consistent with how things work. An immutable class
> > might want to contain an internal cache (e.g. flyweight pattern).
> >
> >   immutable final class Flyweight {
> >
> > private static $instances = [];
> >
> > public immutable $value;
> >
> > private function __construct($value) {
> >   $this->value = $value;
> > }
> >
> > public static function ENUM_ORD() {
> >   if (isset(self::$instances[1]) === false) {
> > self::$instances[1] = new self(1);
> >   }
> >
> >   return self::$instances[1];
> > }
> >
> >   }
> >
> >   $o1 = Flyweight::ENUM_ORD();
> >   $o2 = Flyweight::ENUM_ORD();
> >
> >   var_dump($o1 === $o2); // bool(true)
> I can understand the usecase, but then, how could  the language ensure
> the class is immutable


It cannot be ensured while non-immutable property will exists in immutable
object.


> side note: what about access (read & write) to undefined properties ?
>

You mean properties which are declared and default null and never changed
during object instantiation?


> >
> > Note that we could add the restriction that an immutable class that
> > should be used in a threading context must contain only immutable
> > properties in the future when the need arises. However, for now I do not
> > see the need to inherit the modifier from the class to its properties
> > and I see use cases where the developer wants more control.
>

We agreed that it would be best for ensuring the object state is immutable
(that implies it can be deeply frozen for writes as deep as all his
properties
and properties object properties etc.)


> >
> > The test cases cover the most stuff but not everything and could be
> > extended. There are other things with the PR but I will check it out and
> > create a PR against your branch with that so you can review it. (Might
> > take a while so bare with me.)
> >
>
> The RFC contains several grammatical issues. I could help you with that
> > too if you want.
> >
>

As abowe any RFC enchancements are welcome :)


> > There is a lot of diff noise in the ext/tokenizer/tokenizer_data.c file.
> >
>
> --
> Mathieu Rochette
>
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>


-- 
regards / pozdrawiam,
--
Michał Brzuchalski
brzuchalski.com


Re: [PHP-DEV] RFC - Immutable classes

2016-09-01 Thread Mathieu Rochette


On 09/01/2016 09:12 PM, Fleshgrinder wrote:
> On 9/1/2016 3:49 PM, Silvio Marijić wrote:
>> Hi Andre,
>>
>> Here is RFC https://wiki.php.net/rfc/immutability and you have link to
>> implementation github. Any suggestions and feedback are more then welcome.
>>
>> Best,
>> Silvio
>>
> Hi Silvio,
>
> very nice work you guys did here! :)
indeed! nice to see this going forward
>
> Abstract classes are not mentioned at all in the RFC. However, there is
> a test case from which it is clear that abstract classes cannot be
> immutable. Are there any reasons for this restrictions?
>
> What about array and resource values? Not mentioned in the RFC.
I guess they are not authorized in immutable classes as they are not
immutable themselves, but I think it could be explained
>
> The fact that cloning is not possible should also be extended in the
> RFC. I mean, it's clear to me but maybe not to others. Remember that the
> RFC is the main source of information for the feature (e.g. to generate
> documentation).
agreed, I don't get why it's not possible :/
>
> Why the restrictions that all properties of an immutable class that take
> objects must be immutable too? It's clear why an immutable property must
> contain an immutable class but the inheritance from the class to the
> properties is not consistent with how things work. An immutable class
> might want to contain an internal cache (e.g. flyweight pattern).
>
>   immutable final class Flyweight {
>
> private static $instances = [];
>
> public immutable $value;
>
> private function __construct($value) {
>   $this->value = $value;
> }
>
> public static function ENUM_ORD() {
>   if (isset(self::$instances[1]) === false) {
> self::$instances[1] = new self(1);
>   }
>
>   return self::$instances[1];
> }
>
>   }
>
>   $o1 = Flyweight::ENUM_ORD();
>   $o2 = Flyweight::ENUM_ORD();
>
>   var_dump($o1 === $o2); // bool(true)
I can understand the usecase, but then, how could  the language ensure
the class is immutable

side note: what about access (read & write) to undefined properties ?
>
> Note that we could add the restriction that an immutable class that
> should be used in a threading context must contain only immutable
> properties in the future when the need arises. However, for now I do not
> see the need to inherit the modifier from the class to its properties
> and I see use cases where the developer wants more control.
>
> The test cases cover the most stuff but not everything and could be
> extended. There are other things with the PR but I will check it out and
> create a PR against your branch with that so you can review it. (Might
> take a while so bare with me.)
>
> The RFC contains several grammatical issues. I could help you with that
> too if you want.
>
> There is a lot of diff noise in the ext/tokenizer/tokenizer_data.c file.
>

-- 
Mathieu Rochette


-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] RFC - Immutable classes

2016-09-01 Thread Fleshgrinder
On 9/1/2016 3:49 PM, Silvio Marijić wrote:
> Hi Andre,
> 
> Here is RFC https://wiki.php.net/rfc/immutability and you have link to
> implementation github. Any suggestions and feedback are more then welcome.
> 
> Best,
> Silvio
> 

Hi Silvio,

very nice work you guys did here! :)

Abstract classes are not mentioned at all in the RFC. However, there is
a test case from which it is clear that abstract classes cannot be
immutable. Are there any reasons for this restrictions?

What about array and resource values? Not mentioned in the RFC.

The fact that cloning is not possible should also be extended in the
RFC. I mean, it's clear to me but maybe not to others. Remember that the
RFC is the main source of information for the feature (e.g. to generate
documentation).

Why the restrictions that all properties of an immutable class that take
objects must be immutable too? It's clear why an immutable property must
contain an immutable class but the inheritance from the class to the
properties is not consistent with how things work. An immutable class
might want to contain an internal cache (e.g. flyweight pattern).

  immutable final class Flyweight {

private static $instances = [];

public immutable $value;

private function __construct($value) {
  $this->value = $value;
}

public static function ENUM_ORD() {
  if (isset(self::$instances[1]) === false) {
self::$instances[1] = new self(1);
  }

  return self::$instances[1];
}

  }

  $o1 = Flyweight::ENUM_ORD();
  $o2 = Flyweight::ENUM_ORD();

  var_dump($o1 === $o2); // bool(true)

Note that we could add the restriction that an immutable class that
should be used in a threading context must contain only immutable
properties in the future when the need arises. However, for now I do not
see the need to inherit the modifier from the class to its properties
and I see use cases where the developer wants more control.

The test cases cover the most stuff but not everything and could be
extended. There are other things with the PR but I will check it out and
create a PR against your branch with that so you can review it. (Might
take a while so bare with me.)

The RFC contains several grammatical issues. I could help you with that
too if you want.

There is a lot of diff noise in the ext/tokenizer/tokenizer_data.c file.

-- 
Richard "Fleshgrinder" Fussenegger



signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] RFC - Immutable classes

2016-09-01 Thread Silvio Marijić
Hi Andre,

Here is RFC https://wiki.php.net/rfc/immutability and you have link to
implementation github. Any suggestions and feedback are more then welcome.

Best,
Silvio

2016-09-01 15:43 GMT+02:00 André Rømcke :

>
>
> > On Aug 8, 2016, at 19:19 , Michał Brzuchalski 
> wrote:
> >
> > @Fleshgrinder thanks,
> > my knowledge of C allowed me to implement some features experimentally.
> > When problem occurs then I'll find any needed help because I think this
> > feature is needed.
> > Personally I don't have wiki karma so help in writing RFC if you have
> karma
> > could help us very much.
>
>
> I would also like to contribute to help make this RFC happen, anything
> that needs help on in terms of doc or rfc wiki?
>
>
> Best,
> André (andrerom)




-- 
Silvio Marijić
Software Engineer
2e Systems


Re: [PHP-DEV] RFC - Immutable classes

2016-08-08 Thread Michał Brzuchalski
@Fleshgrinder thanks,
my knowledge of C allowed me to implement some features experimentally.
When problem occurs then I'll find any needed help because I think this
feature is needed.
Personally I don't have wiki karma so help in writing RFC if you have karma
could help us very much.

2016-08-08 19:16 GMT+02:00 Silvio Marijić :

> @Fleshgrinder, Thanks, every help is welcome.
>
> 2016-08-08 18:44 GMT+02:00 Fleshgrinder :
>
>> On 8/8/2016 5:00 PM, Silvio Marijić wrote:
>> > It's great that you are up of this.
>> > I think it will be great to see this one in action.
>> >
>> > I agree that we should separate them into separate RFC-s.
>> >
>> > 2016-08-08 15:51 GMT+02:00 Michał Brzuchalski :
>> >
>> >> It is great to hear somone is interested so why not. My lately
>> discussion
>> >> found usefull implementing 3 keywords, such as:
>> >> 1. *immutable* for the functionality you are currently working on.
>> >> 2. *sealed* for the above plus type not changeable.
>> >> 3. *final* for the above plus not being overridable.
>> >>
>> >> But all of them should be implemented in different RFC's starting from
>> >> Immutable because it's base point to toher two keywords.
>> >> Whole idea needs refreshing discussion to clarify idea so it can
>> success.
>> >>
>>
>> I would like to offer my support. I might not be as familiar as you guys
>> with the C source but if you need anything (e.g. documentation, RFC
>> writing, testing, ...) let me know.
>>
>> --
>> Richard "Fleshgrinder" Fussenegger
>>
>>
>
>
> --
> Silvio Marijić
> Software Engineer
> 2e Systems
>



-- 
pozdrawiam
--
Michał Brzuchalski


Re: [PHP-DEV] RFC - Immutable classes

2016-08-08 Thread Silvio Marijić
@Fleshgrinder, Thanks, every help is welcome.

2016-08-08 18:44 GMT+02:00 Fleshgrinder :

> On 8/8/2016 5:00 PM, Silvio Marijić wrote:
> > It's great that you are up of this.
> > I think it will be great to see this one in action.
> >
> > I agree that we should separate them into separate RFC-s.
> >
> > 2016-08-08 15:51 GMT+02:00 Michał Brzuchalski :
> >
> >> It is great to hear somone is interested so why not. My lately
> discussion
> >> found usefull implementing 3 keywords, such as:
> >> 1. *immutable* for the functionality you are currently working on.
> >> 2. *sealed* for the above plus type not changeable.
> >> 3. *final* for the above plus not being overridable.
> >>
> >> But all of them should be implemented in different RFC's starting from
> >> Immutable because it's base point to toher two keywords.
> >> Whole idea needs refreshing discussion to clarify idea so it can
> success.
> >>
>
> I would like to offer my support. I might not be as familiar as you guys
> with the C source but if you need anything (e.g. documentation, RFC
> writing, testing, ...) let me know.
>
> --
> Richard "Fleshgrinder" Fussenegger
>
>


-- 
Silvio Marijić
Software Engineer
2e Systems


Re: [PHP-DEV] RFC - Immutable classes

2016-08-08 Thread Fleshgrinder
On 8/8/2016 5:00 PM, Silvio Marijić wrote:
> It's great that you are up of this.
> I think it will be great to see this one in action.
> 
> I agree that we should separate them into separate RFC-s.
> 
> 2016-08-08 15:51 GMT+02:00 Michał Brzuchalski :
> 
>> It is great to hear somone is interested so why not. My lately discussion
>> found usefull implementing 3 keywords, such as:
>> 1. *immutable* for the functionality you are currently working on.
>> 2. *sealed* for the above plus type not changeable.
>> 3. *final* for the above plus not being overridable.
>>
>> But all of them should be implemented in different RFC's starting from
>> Immutable because it's base point to toher two keywords.
>> Whole idea needs refreshing discussion to clarify idea so it can success.
>>

I would like to offer my support. I might not be as familiar as you guys
with the C source but if you need anything (e.g. documentation, RFC
writing, testing, ...) let me know.

-- 
Richard "Fleshgrinder" Fussenegger



signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] RFC - Immutable classes

2016-08-08 Thread Silvio Marijić
It's great that you are up of this.
I think it will be great to see this one in action.

I agree that we should separate them into separate RFC-s.

2016-08-08 15:51 GMT+02:00 Michał Brzuchalski :

> It is great to hear somone is interested so why not. My lately discussion
> found usefull implementing 3 keywords, such as:
> 1. *immutable* for the functionality you are currently working on.
> 2. *sealed* for the above plus type not changeable.
> 3. *final* for the above plus not being overridable.
>
> But all of them should be implemented in different RFC's starting from
> Immutable because it's base point to toher two keywords.
> Whole idea needs refreshing discussion to clarify idea so it can success.
>
> 2016-08-08 15:23 GMT+02:00 Silvio Marijić :
>
>> @Michal Would you consider cooperating on implementing immutable and
>> sealed modifiers?
>>
>> 2016-08-08 15:20 GMT+02:00 Michał Brzuchalski :
>>
>>> @Silvio I've tried to implement final https://github.com/php/p
>>> hp-src/compare/master...brzuchal:final-properties but haven't found
>>> time to implement immutable and sealed, AFAIK I had problems with OPcache
>>> enabled, you need to remember to run every test after compile with opcache
>>> enabled in CLI.
>>>
>>> 2016-08-08 15:00 GMT+02:00 Silvio Marijić :
>>>
 @Michal, well no I did read it. I see that there is not much going on
 there since last year. Did you tried to implement it ?

 2016-08-08 14:49 GMT+02:00 Michał Brzuchalski :

>
> 2016-08-08 14:47 GMT+02:00 S.A.N :
>
>> May be better to do as immutable arrays?
>>
>> const = new Email;
>>
>> it will be a super global immutable instance of Email.
>>
>
> I think you've missunderstood concept of immutable classes.
>
>
> --
> pozdrawiam
> --
> Michał Brzuchalski
>



 --
 Silvio Marijić
 Software Engineer
 2e Systems

>>>
>>>
>>>
>>> --
>>> pozdrawiam
>>> --
>>> Michał Brzuchalski
>>>
>>
>>
>>
>> --
>> Silvio Marijić
>> Software Engineer
>> 2e Systems
>>
>
>
>
> --
> pozdrawiam
> --
> Michał Brzuchalski
>



-- 
Silvio Marijić
Software Engineer
2e Systems


Re: [PHP-DEV] RFC - Immutable classes

2016-08-08 Thread Michał Brzuchalski
It is great to hear somone is interested so why not. My lately discussion
found usefull implementing 3 keywords, such as:
1. *immutable* for the functionality you are currently working on.
2. *sealed* for the above plus type not changeable.
3. *final* for the above plus not being overridable.

But all of them should be implemented in different RFC's starting from
Immutable because it's base point to toher two keywords.
Whole idea needs refreshing discussion to clarify idea so it can success.

2016-08-08 15:23 GMT+02:00 Silvio Marijić :

> @Michal Would you consider cooperating on implementing immutable and
> sealed modifiers?
>
> 2016-08-08 15:20 GMT+02:00 Michał Brzuchalski :
>
>> @Silvio I've tried to implement final https://github.com/php/p
>> hp-src/compare/master...brzuchal:final-properties but haven't found time
>> to implement immutable and sealed, AFAIK I had problems with OPcache
>> enabled, you need to remember to run every test after compile with opcache
>> enabled in CLI.
>>
>> 2016-08-08 15:00 GMT+02:00 Silvio Marijić :
>>
>>> @Michal, well no I did read it. I see that there is not much going on
>>> there since last year. Did you tried to implement it ?
>>>
>>> 2016-08-08 14:49 GMT+02:00 Michał Brzuchalski :
>>>

 2016-08-08 14:47 GMT+02:00 S.A.N :

> May be better to do as immutable arrays?
>
> const = new Email;
>
> it will be a super global immutable instance of Email.
>

 I think you've missunderstood concept of immutable classes.


 --
 pozdrawiam
 --
 Michał Brzuchalski

>>>
>>>
>>>
>>> --
>>> Silvio Marijić
>>> Software Engineer
>>> 2e Systems
>>>
>>
>>
>>
>> --
>> pozdrawiam
>> --
>> Michał Brzuchalski
>>
>
>
>
> --
> Silvio Marijić
> Software Engineer
> 2e Systems
>



-- 
pozdrawiam
--
Michał Brzuchalski


Re: [PHP-DEV] RFC - Immutable classes

2016-08-08 Thread Silvio Marijić
@Michal Would you consider cooperating on implementing immutable and sealed
modifiers?

2016-08-08 15:20 GMT+02:00 Michał Brzuchalski :

> @Silvio I've tried to implement final https://github.com/php/
> php-src/compare/master...brzuchal:final-properties but haven't found time
> to implement immutable and sealed, AFAIK I had problems with OPcache
> enabled, you need to remember to run every test after compile with opcache
> enabled in CLI.
>
> 2016-08-08 15:00 GMT+02:00 Silvio Marijić :
>
>> @Michal, well no I did read it. I see that there is not much going on
>> there since last year. Did you tried to implement it ?
>>
>> 2016-08-08 14:49 GMT+02:00 Michał Brzuchalski :
>>
>>>
>>> 2016-08-08 14:47 GMT+02:00 S.A.N :
>>>
 May be better to do as immutable arrays?

 const = new Email;

 it will be a super global immutable instance of Email.

>>>
>>> I think you've missunderstood concept of immutable classes.
>>>
>>>
>>> --
>>> pozdrawiam
>>> --
>>> Michał Brzuchalski
>>>
>>
>>
>>
>> --
>> Silvio Marijić
>> Software Engineer
>> 2e Systems
>>
>
>
>
> --
> pozdrawiam
> --
> Michał Brzuchalski
>



-- 
Silvio Marijić
Software Engineer
2e Systems


Re: [PHP-DEV] RFC - Immutable classes

2016-08-08 Thread Michał Brzuchalski
@Silvio I've tried to implement final
https://github.com/php/php-src/compare/master...brzuchal:final-properties
but haven't found time to implement immutable and sealed, AFAIK I had
problems with OPcache enabled, you need to remember to run every test after
compile with opcache enabled in CLI.

2016-08-08 15:00 GMT+02:00 Silvio Marijić :

> @Michal, well no I did read it. I see that there is not much going on
> there since last year. Did you tried to implement it ?
>
> 2016-08-08 14:49 GMT+02:00 Michał Brzuchalski :
>
>>
>> 2016-08-08 14:47 GMT+02:00 S.A.N :
>>
>>> May be better to do as immutable arrays?
>>>
>>> const = new Email;
>>>
>>> it will be a super global immutable instance of Email.
>>>
>>
>> I think you've missunderstood concept of immutable classes.
>>
>>
>> --
>> pozdrawiam
>> --
>> Michał Brzuchalski
>>
>
>
>
> --
> Silvio Marijić
> Software Engineer
> 2e Systems
>



-- 
pozdrawiam
--
Michał Brzuchalski


Re: [PHP-DEV] RFC - Immutable classes

2016-08-08 Thread Silvio Marijić
@Michal, well no I did read it. I see that there is not much going on there
since last year. Did you tried to implement it ?

2016-08-08 14:49 GMT+02:00 Michał Brzuchalski :

>
> 2016-08-08 14:47 GMT+02:00 S.A.N :
>
>> May be better to do as immutable arrays?
>>
>> const = new Email;
>>
>> it will be a super global immutable instance of Email.
>>
>
> I think you've missunderstood concept of immutable classes.
>
>
> --
> pozdrawiam
> --
> Michał Brzuchalski
>



-- 
Silvio Marijić
Software Engineer
2e Systems


Re: [PHP-DEV] RFC - Immutable classes

2016-08-08 Thread Michał Brzuchalski
2016-08-08 14:47 GMT+02:00 S.A.N :

> May be better to do as immutable arrays?
>
> const = new Email;
>
> it will be a super global immutable instance of Email.
>

I think you've missunderstood concept of immutable classes.


-- 
pozdrawiam
--
Michał Brzuchalski


Re: [PHP-DEV] RFC - Immutable classes

2016-08-08 Thread S.A.N
May be better to do as immutable arrays?

const EmailObject = new Email;

It will be a super global immutable instance of Email.

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] RFC - Immutable classes

2016-08-08 Thread S.A.N
May be better to do as immutable arrays?

const = new Email;

it will be a super global immutable instance of Email.

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] RFC - Immutable classes

2016-08-08 Thread Michał Brzuchalski
Sure my final properties was first thought, lately in discuccion it turns
into immutable, sealed and final see here
https://marc.info/?l=php-internals=146005058530881=2
Have you also read about Immutable modifier from last year?
http://marc.info/?t=14476653941=1=2 it's exactly about immutable
classes!


2016-08-08 14:46 GMT+02:00 Silvio Marijić :

> Btw, I was not aware that there was already conversation on immutable
> classes.
>
> 2016-08-08 14:31 GMT+02:00 Silvio Marijić :
>
>> I see your standpoint, but I think it could cause confusion because of
>> final classes. I think "immutable" is more suited here.
>> What I try to achieve is something similar like case classes in Scala.
>>
>> Best regards,
>>
>> 2016-08-08 13:16 GMT+02:00 Michał Brzuchalski :
>>
>>> Hi Silvio,
>>>
>>> Look into my talk about final properties https://marc.info/?
>>> t=14597925583=1=2 maybe there would be something usefull.
>>> There is also talk about mutable and immutable properties and other
>>> class modifiers also about var and val.
>>> I'm not sure that it should be class midifier rather than proprty
>>> modifier keyword.
>>>
>>> regards,
>>> --
>>> Michał Brzuchalski
>>>
>>> 2016-08-08 12:31 GMT+02:00 Silvio Marijić :
>>>
 Hi,

 I would need your help with one idea. I'm working on one RFC that I'm
 would
 like to submit. Idea is that after you initialize object eg. after
 constructor returns, object would be locked, and you wouldn't be able to
 change properties on that object anymore. It would like this:

 >>>
 immutable class Email {
 >  public $email;
 >  public function __construct($email){
 >  $this->email = $email;
 >  }
 > }
 > $email = new Email("exam...@email.com");



 After instance of class is created, object is "frozen" so call like this

 $email->email = "n...@email.com";


 Would result in error.

 I have already implementation up to certain degree, but I need one
 advice
 from more experienced developers. Where is the place where I could put
 logic to lock object after the constructor has finished? Maybe in zend
 vm
 on ZEND_NEW token?

 Some constraints are needed:

1. Child class that extends immutable class must be defined as
 immutable
also.
2. If property on immutable class contains object, it must be
 instance
of immutable class.
3. You can not have immutability per property, it either whole class
 or
none.

 Thank you all in advance.

 --
 Silvio Marijić
 Software Engineer
 2e Systems

>>>
>>>
>>>
>>> --
>>> pozdrawiam
>>> --
>>> Michał Brzuchalski
>>>
>>
>>
>>
>> --
>> Silvio Marijić
>> Software Engineer
>> 2e Systems
>>
>
>
>
> --
> Silvio Marijić
> Software Engineer
> 2e Systems
>



-- 
pozdrawiam
--
Michał Brzuchalski


Re: [PHP-DEV] RFC - Immutable classes

2016-08-08 Thread Silvio Marijić
Btw, I was not aware that there was already conversation on immutable
classes.

2016-08-08 14:31 GMT+02:00 Silvio Marijić :

> I see your standpoint, but I think it could cause confusion because of
> final classes. I think "immutable" is more suited here.
> What I try to achieve is something similar like case classes in Scala.
>
> Best regards,
>
> 2016-08-08 13:16 GMT+02:00 Michał Brzuchalski :
>
>> Hi Silvio,
>>
>> Look into my talk about final properties https://marc.info/?
>> t=14597925583=1=2 maybe there would be something usefull.
>> There is also talk about mutable and immutable properties and other class
>> modifiers also about var and val.
>> I'm not sure that it should be class midifier rather than proprty
>> modifier keyword.
>>
>> regards,
>> --
>> Michał Brzuchalski
>>
>> 2016-08-08 12:31 GMT+02:00 Silvio Marijić :
>>
>>> Hi,
>>>
>>> I would need your help with one idea. I'm working on one RFC that I'm
>>> would
>>> like to submit. Idea is that after you initialize object eg. after
>>> constructor returns, object would be locked, and you wouldn't be able to
>>> change properties on that object anymore. It would like this:
>>>
>>> >>
>>> immutable class Email {
>>> >  public $email;
>>> >  public function __construct($email){
>>> >  $this->email = $email;
>>> >  }
>>> > }
>>> > $email = new Email("exam...@email.com");
>>>
>>>
>>>
>>> After instance of class is created, object is "frozen" so call like this
>>>
>>> $email->email = "n...@email.com";
>>>
>>>
>>> Would result in error.
>>>
>>> I have already implementation up to certain degree, but I need one advice
>>> from more experienced developers. Where is the place where I could put
>>> logic to lock object after the constructor has finished? Maybe in zend vm
>>> on ZEND_NEW token?
>>>
>>> Some constraints are needed:
>>>
>>>1. Child class that extends immutable class must be defined as
>>> immutable
>>>also.
>>>2. If property on immutable class contains object, it must be instance
>>>of immutable class.
>>>3. You can not have immutability per property, it either whole class
>>> or
>>>none.
>>>
>>> Thank you all in advance.
>>>
>>> --
>>> Silvio Marijić
>>> Software Engineer
>>> 2e Systems
>>>
>>
>>
>>
>> --
>> pozdrawiam
>> --
>> Michał Brzuchalski
>>
>
>
>
> --
> Silvio Marijić
> Software Engineer
> 2e Systems
>



-- 
Silvio Marijić
Software Engineer
2e Systems


Re: [PHP-DEV] RFC - Immutable classes

2016-08-08 Thread Silvio Marijić
I see your standpoint, but I think it could cause confusion because of
final classes. I think "immutable" is more suited here.
What I try to achieve is something similar like case classes in Scala.

Best regards,

2016-08-08 13:16 GMT+02:00 Michał Brzuchalski :

> Hi Silvio,
>
> Look into my talk about final properties https://marc.info/?
> t=14597925583=1=2 maybe there would be something usefull.
> There is also talk about mutable and immutable properties and other class
> modifiers also about var and val.
> I'm not sure that it should be class midifier rather than proprty modifier
> keyword.
>
> regards,
> --
> Michał Brzuchalski
>
> 2016-08-08 12:31 GMT+02:00 Silvio Marijić :
>
>> Hi,
>>
>> I would need your help with one idea. I'm working on one RFC that I'm
>> would
>> like to submit. Idea is that after you initialize object eg. after
>> constructor returns, object would be locked, and you wouldn't be able to
>> change properties on that object anymore. It would like this:
>>
>> >
>> immutable class Email {
>> >  public $email;
>> >  public function __construct($email){
>> >  $this->email = $email;
>> >  }
>> > }
>> > $email = new Email("exam...@email.com");
>>
>>
>>
>> After instance of class is created, object is "frozen" so call like this
>>
>> $email->email = "n...@email.com";
>>
>>
>> Would result in error.
>>
>> I have already implementation up to certain degree, but I need one advice
>> from more experienced developers. Where is the place where I could put
>> logic to lock object after the constructor has finished? Maybe in zend vm
>> on ZEND_NEW token?
>>
>> Some constraints are needed:
>>
>>1. Child class that extends immutable class must be defined as
>> immutable
>>also.
>>2. If property on immutable class contains object, it must be instance
>>of immutable class.
>>3. You can not have immutability per property, it either whole class or
>>none.
>>
>> Thank you all in advance.
>>
>> --
>> Silvio Marijić
>> Software Engineer
>> 2e Systems
>>
>
>
>
> --
> pozdrawiam
> --
> Michał Brzuchalski
>



-- 
Silvio Marijić
Software Engineer
2e Systems


Re: [PHP-DEV] RFC - Immutable classes

2016-08-08 Thread Michał Brzuchalski
Hi Silvio,

Look into my talk about final properties https://marc.info/?
t=14597925583=1=2 maybe there would be something usefull.
There is also talk about mutable and immutable properties and other class
modifiers also about var and val.
I'm not sure that it should be class midifier rather than proprty modifier
keyword.

regards,
--
Michał Brzuchalski

2016-08-08 12:31 GMT+02:00 Silvio Marijić :

> Hi,
>
> I would need your help with one idea. I'm working on one RFC that I'm would
> like to submit. Idea is that after you initialize object eg. after
> constructor returns, object would be locked, and you wouldn't be able to
> change properties on that object anymore. It would like this:
>
> 
> immutable class Email {
> >  public $email;
> >  public function __construct($email){
> >  $this->email = $email;
> >  }
> > }
> > $email = new Email("exam...@email.com");
>
>
>
> After instance of class is created, object is "frozen" so call like this
>
> $email->email = "n...@email.com";
>
>
> Would result in error.
>
> I have already implementation up to certain degree, but I need one advice
> from more experienced developers. Where is the place where I could put
> logic to lock object after the constructor has finished? Maybe in zend vm
> on ZEND_NEW token?
>
> Some constraints are needed:
>
>1. Child class that extends immutable class must be defined as immutable
>also.
>2. If property on immutable class contains object, it must be instance
>of immutable class.
>3. You can not have immutability per property, it either whole class or
>none.
>
> Thank you all in advance.
>
> --
> Silvio Marijić
> Software Engineer
> 2e Systems
>



-- 
pozdrawiam
--
Michał Brzuchalski


[PHP-DEV] RFC - Immutable classes

2016-08-08 Thread Silvio Marijić
Hi,

I would need your help with one idea. I'm working on one RFC that I'm would
like to submit. Idea is that after you initialize object eg. after
constructor returns, object would be locked, and you wouldn't be able to
change properties on that object anymore. It would like this:

  public $email;
>  public function __construct($email){
>  $this->email = $email;
>  }
> }
> $email = new Email("exam...@email.com");



After instance of class is created, object is "frozen" so call like this

$email->email = "n...@email.com";


Would result in error.

I have already implementation up to certain degree, but I need one advice
from more experienced developers. Where is the place where I could put
logic to lock object after the constructor has finished? Maybe in zend vm
on ZEND_NEW token?

Some constraints are needed:

   1. Child class that extends immutable class must be defined as immutable
   also.
   2. If property on immutable class contains object, it must be instance
   of immutable class.
   3. You can not have immutability per property, it either whole class or
   none.

Thank you all in advance.

-- 
Silvio Marijić
Software Engineer
2e Systems