Re: Design by Contract
| From: | Dmitry Stogov | Date: | Mon, 09 Feb 2015 11:27:43 +0000 |
| Subject: | Re: Design by Contract | ||
| References: | 1 2 3 4 5 6 7 8 9 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-82272@lists.php.net to get a copy of this message | ||
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 <pthreads@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.
>
> Cheers
> Joe
>
> On Mon, Feb 9, 2015 at 11:05 AM, Dmitry Stogov <dmitry@zend.com> wrote:
>
>> invariant is for classes only. It should be called before and/or after
>> each method to check object consistency.
>>
>> syntax with expressions may work if we put constraints before the
>> function body .
>>
>> function foo($a int): int
>> require(expr1)
>> require(expr2, msg)
>> return(expr3)
>> {
>> }
>>
>> Yasuo, I would suggest to describe both syntax options.
>>
>> Thanks. Dmitry.
>>
>> On Mon, Feb 9, 2015 at 1:46 PM, Joe Watkins <pthreads@pthreads.org>
>> wrote:
>>
>>> Morning Yasuo,
>>>
>>> Can you explain what invariant is for ?
>>>
>>> I prefer a list of contracts with a single expression, over blocks
>>> of expressions in one contract.
>>> An IDE can just as easy generate a block of code or set of
>>> contracts, so it's really just a matter of how complex it makes the
>>> implementation if you allow any block of code in the contract. I think it
>>> does make it unnecessarily complicated to implement, I can be wrong.
>>>
>>> If there is going to be two rfc's, I will vote no on the annotations
>>> based one, I'd rather no time was wasted on even writing it; Before you
>>> convince anyone that DBC is a good idea you have to convince them
>>> annotations is a good idea, many have tried and failed.
>>>
>>> Cheers
>>> Joe
>>>
>>> On Mon, Feb 9, 2015 at 10:34 AM, Yasuo Ohgaki <yohgaki@ohgaki.net>
>>> wrote:
>>>
>>>> Hi Dmitry and Joe,
>>>>
>>>> On Mon, Feb 9, 2015 at 6:01 PM, Dmitry Stogov <dmitry@zend.com> wrote:
>>>>
>>>>> Usage of "return" is a good idea.
>>>>> The more heads the better result :)
>>>>>
>>>>
>>>> Less additional reserved word :)
>>>> So I'll use "require" and "return" for D like RFC.
>>>> We haven't talk much about invariants. I'll write my idea.
>>>>
>>>> Current RFC is large enough already, I'll prepare new one.
>>>> We may decide what to do with 2 RFCs.
>>>>
>>>> We have choices for with block or without block. I prefer with block
>>>> version, since
>>>> assert expression could be messy. With block, IDE may do it's jobs.
>>>> i.e. Hide blocks.
>>>>
>>>> ==============================================
>>>> Function/Method
>>>>
>>>> [With block]
>>>> function foo()
>>>> require {
>>>> assert(assert-expr, 'msg');
>>>> assert(assert-expr, 'msg');
>>>> assert(assert-expr, 'msg');
>>>> }
>>>> return {
>>>> assert(assert-expr, 'msg');
>>>> assert(assert-expr, 'msg');
>>>> assert(assert-expr, 'msg');
>>>> }
>>>> invariant {
>>>> assert(assert-expr, 'msg');
>>>> assert(assert-expr, 'msg');
>>>> assert(assert-expr, 'msg');
>>>> }
>>>> {
>>>> // body
>>>> }
>>>>
>>>> _OR_
>>>>
>>>> [Without block]
>>>> function foo() {
>>>> require(assert-expr, 'msg');
>>>> require(assert-expr, 'msg');
>>>> require(assert-expr, 'msg');
>>>> invariant(assert-expr, 'msg');
>>>> invariant(assert-expr, 'msg');
>>>> invariant(assert-expr, 'msg');
>>>> return(assert-expr, 'msg');
>>>> return(assert-expr, 'msg');
>>>> return(assert-expr, 'msg');
>>>>
>>>> // function body
>>>> }
>>>>
>>>>
>>>> Currently, following code wouldn't work (PHP 7.0.0-dev)
>>>> ----------
>>>> assert(function() {return FALSE;}, 'AAAAA');
>>>> ----------
>>>>
>>>> For block version, which do you prefer, allow any PHP syntax or assert
>>>> only?
>>>> People may use anonymous function to do fancy jobs anyway if it's
>>>> supported.
>>>>
>>>> No block version only accepts EXPR obviously, but anonymous function
>>>> may
>>>> be used with this as well.
>>>>
>>>>
>>>> ==============================================
>>>> Class invariants
>>>>
>>>> [With block]
>>>> class Foo {
>>>> __invariants() {
>>>> assert(assert-expr, 'msg');
>>>> assert(assert-expr, 'msg');
>>>> assert(assert-expr, 'msg');
>>>> }
>>>> }
>>>>
>>>> _OR_
>>>>
>>>> [Without block]
>>>> class Foo {
>>>> __construct() {
>>>> invariant(assert-expr, 'msg'); // Only allow in __construct()?
>>>> Allowing invariant.
>>>> invariant(assert-expr, 'msg');
>>>> invariant(assert-expr, 'msg');
>>>> }
>>>> }
>>>>
>>>>
>>>> ==============================================
>>>> Global invariant
>>>>
>>>> I'm not sure if we should have
>>>>
>>>> function __invariants() {
>>>> assert(assert-expr, 'msg');
>>>> assert(assert-expr, 'msg');
>>>> assert(assert-expr, 'msg');
>>>> }
>>>>
>>>> _OR_
>>>>
>>>> invariant {
>>>> assert(assert-expr, 'msg');
>>>> assert(assert-expr, 'msg');
>>>> assert(assert-expr, 'msg');
>>>> }
>>>>
>>>> to assert global vars, whole app state, etc. It may be useful for unit
>>>> tests as well as app development.
>>>>
>>>>
>>>> I'll start working after I get comment from you.
>>>>
>>>> Regards,
>>>>
>>>> --
>>>> Yasuo Ohgaki
>>>> yohgaki@ohgaki.net
>>>>
>>>
>>>
>>
>