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
>>
>
>

Reply via email to