I'm not sure we can always enforce invariant contracts ... Evaluating invariant expressions on entry and exit is not enough, since a property can be changed without the use of a method.
Can or should, we do anything about that ? This should also be covered in the RFC, I think. Cheers Joe On Tue, Feb 10, 2015 at 6:49 AM, Dmitry Stogov <dmi...@zend.com> wrote: > Hi, > > can I make some minor correction? > > Thanks. Dmitry. > > > > On Tue, Feb 10, 2015 at 9:25 AM, Yasuo Ohgaki <yohg...@ohgaki.net> wrote: > >> Hi Dmitry, >> >> On Tue, Feb 10, 2015 at 1:43 PM, Dmitry Stogov <dmi...@zend.com> wrote: >> >>> On Feb 9, 2015 11:20 PM, "Yasuo Ohgaki" <yohg...@ohgaki.net> wrote: >>> > >>> > Hi Dmitry and Joe, >>> > >>> > On Mon, Feb 9, 2015 at 8:27 PM, Dmitry Stogov <dmi...@zend.com> wrote: >>> >> >>> >> yes. this may work. >>> >> probably better to put it after extends and implements. >>> >> >>> >> >>> >> Dmitry. >>> >> >>> >> On Mon, Feb 9, 2015 at 2:19 PM, Joe Watkins <pthre...@pthreads.org> >>> wrote: >>> >>> >>> >>> Could this be described as a requirement of the class ? >>> >>> >>> >>> class Mine >>> >>> require(invariant-expr) >>> >>> extends Something >>> >>> implements Someface { >>> >>> >>> >>> public function method($param) : return >>> >>> require(input-expr), >>> >>> return(output-expr) { >>> >>> >>> >>> } >>> >>> } >>> >>> >>> >>> To avoid invariant keyword maybe. >>> > >>> > >>> > This would work. >>> > If users have adopted DbC in some way, 'invariant' may be used already. >>> > >>> > I see two issues. >>> > >>> > Interface works, but most classes are class without interfaces. Then >>> users have to repeat >>> > require()/return() many times to check class state or have to use >>> interface for DbC. >>> > >>> >>> In D classes may have "invariant" constraints. We may use "require" >>> keyword for it. The constraints ineritance rules and order of calls to >>> constrains must be the same s in D. >>> >>> class Foo { >>> private $sum = 0; >>> require($this->sum >= 0); // invariant constraint will be called >>> before and after every method >>> function add($n) { >>> $this->sum += $n; >>> } >>> } >>> >> >> OK. I'll update the RFC. >> >> >>> > Since compiler does not know a method() is for DbC invariant, it will >>> be compiled and exists >>> > in production execution. >>> > >>> > Use of interface: >>> > - no additional keyword (pros) >>> > - requires interface for DbC, most classes does not require >>> interface (cons) >>> > - if interface is not used, user has to repeat invariant conditions >>> over and over (cons) >>> > - requires to define method that should not exist in production >>> (cons) >>> >>> I didn't understand you idea. >>> >> >> Joe's idea was to use Interface for invariant condition grouping. >> If we use your idea, issue is solved. >> >> class Foo { >>> private $sum = 0; >>> require($this->sum >= 0); // invariant constraint will be called >>> before and after every method >>> function add($n) { >>> $this->sum += $n; >>> } >>> } >>> >> Ok. >> >>> > >>> > New keyword: >>> > - does not require interface for efficient definition (pros). >>> > - new keyword (cons) >>> > >>> > It seems we are better to choose proper keyword for 'invariant'. >>> 'invariant' is not common, so 'invariant' >>> > may be good enough choice. Does anyone use 'invariant' as >>> function/method/class/constant names? >>> > If there is better name, suggestion is appreciated. >>> > >>> > On place closure call like javascript is not supported in PHP, but >>> function works with assert. >>> > >>> > <?php >>> > function foo() { return FALSE; } >>> > assert(foo()); >>> > ?> >>> > PHP Warning: assert(): Assertion failed in - on line 3 >>> > >>> > This wouldn't be changed for require()/return()/invariant()? >>> > >>> > We need a switch to change development/production. I'll use >>> "dbc=On/Off" for now. >>> > If you have any better idea, please let me know. (dbc will be >>> INI_SYSTEM) >>> >>> Check the "expectations" RFC. I think, it's going to be 3 state switch, >>> zero-cost disable, run-time disable, run-time enable. So, it may be >>> INI_ALL, but it won't be possible to switch from/to zero-cost at run-time. >>> >> >> Ok. >> >>> > >>> > For CLI, there will be no command line switch for dbc. It executes >>> script production mode by >>> > default. If user needs development mode >>> > >>> > php -d dbc=1 script.php >>> > >>> > should be used. >>> > >>> > >>> > And finally, are we going to allow custom assertion error message? e.g. >>> > >>> > require($a > 0, 'Parameter $a must be positive number'); >>> >>> I think, it may be useful. >>> >> Ok. I'll use it. >> >>> > >>> > Since this contract is definition like "implements"/"extends", we may >>> not allow >>> > custom error message. I'll write the RFC not to allow custom error >>> messages unless >>> > you dislike it. >>> > >>> > I think we have enough consensus/information to start writing the RFC. >>> > If I have any concern, I'll ask here. >>> >>> Ok, go forward :) >>> >> Updated wiki page. >> https://wiki.php.net/rfc/dbc2 >> >> If you would like to change something, please let me know. >> I don't think finished draft at all and I don't mind going back and forth. >> >> Regards, >> >> -- >> Yasuo Ohgaki >> yohg...@ohgaki.net >> > >