Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:82360 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 67168 invoked from network); 10 Feb 2015 10:05:34 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 10 Feb 2015 10:05:34 -0000 Authentication-Results: pb1.pair.com header.from=pthreads@pthreads.org; sender-id=unknown Authentication-Results: pb1.pair.com smtp.mail=pthreads@pthreads.org; spf=permerror; sender-id=unknown Received-SPF: error (pb1.pair.com: domain pthreads.org from 209.85.220.41 cause and error) X-PHP-List-Original-Sender: pthreads@pthreads.org X-Host-Fingerprint: 209.85.220.41 mail-pa0-f41.google.com Received: from [209.85.220.41] ([209.85.220.41:45451] helo=mail-pa0-f41.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id F9/91-47508-CE7D9D45 for ; Tue, 10 Feb 2015 05:05:32 -0500 Received: by mail-pa0-f41.google.com with SMTP id kx10so16016881pab.0 for ; Tue, 10 Feb 2015 02:05:29 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=g8xdL5Zx7VsRzdapMwmZX6F048V5F+2/uoJ1TNhkPk8=; b=KmYc/PtvasPlmnv6JMsBW7SEjgEJ0t5L33PjZPdGkM4+b39PKF6G//FEsSQz4Or5SW A8WGCdJEYWPV6gltdLIgC/UL5NWwsAAgPOEkj8GxOt12jWTAkhpO2F6ZRmTD0Mq0YPnq eT/yh+QU2ajlfMycxsv0wplnTXEJmEqw4B16J0kTzAqdXLG+kBLFK3/zL5NrYor7ztBT vWJP8O0ffPXm5xBNqWpFRR7ehRHDMwtGLTLMR9BhYOSUzjt4IyubaTz23fUakwcItI4+ Arc6JQHczFomin2slOERt2GKO4CO2tM8plFU5InaDJI8PQmulQeCTddrbSv6DtYhgfyA ahHA== X-Gm-Message-State: ALoCoQn56zp55dbk1156BrTQGq+ok1UxLLR8J7ai9xDsysRRqrmDQU6Yw3Vuku9kD0JOMlUA/TfP MIME-Version: 1.0 X-Received: by 10.70.124.163 with SMTP id mj3mr35886433pdb.110.1423562729617; Tue, 10 Feb 2015 02:05:29 -0800 (PST) Received: by 10.70.49.100 with HTTP; Tue, 10 Feb 2015 02:05:29 -0800 (PST) X-Originating-IP: [109.145.22.92] In-Reply-To: <007901d04517$cd3c4d70$67b4e850$@tutteli.ch> References: <54D7ED22.3080001@gmail.com> <007901d04517$cd3c4d70$67b4e850$@tutteli.ch> Date: Tue, 10 Feb 2015 10:05:29 +0000 Message-ID: To: Robert Stoll Cc: Dmitry Stogov , Yasuo Ohgaki , PHP Internals , Stanislav Malyshev Content-Type: multipart/alternative; boundary=001a11c28f6cd09336050eb9062c Subject: Re: [PHP-DEV] Design by Contract From: pthreads@pthreads.org (Joe Watkins) --001a11c28f6cd09336050eb9062c Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable > $this->a =3D require(> 100); This is already valid-ish code .. On Tue, Feb 10, 2015 at 9:56 AM, Robert Stoll wrote: > We could provide an Invariant class in order to support invariant cases a= t > least to a certain degree: > http://3v4l.org/vjBRG > > Of course, that does not provide the same support as native invariants bu= t > maybe better than nothing. At least we would have a consistent Invariant > class throughout the code bases. > We could go even further and provide some syntactic sugar in order that > one does not need to write new Invariant(...) as in line 28 -- for instan= ce: > > $this->a =3D require(> 100); > > which is short for > > $this->a =3D new Invariant(function($value){return $value > 100;}, '$this= ->a > > 100'); > > Cheers, > Robert > > > -----Urspr=C3=BCngliche Nachricht----- > > Von: Dmitry Stogov [mailto:dmitry@zend.com] > > Gesendet: Dienstag, 10. Februar 2015 08:06 > > An: Joe Watkins > > Cc: Yasuo Ohgaki; PHP Internals; Stanislav Malyshev > > Betreff: Re: [PHP-DEV] Design by Contract > > > > good point, but I think we can do nothing about that. > > Anyway, it should be reflected in RFC. > > > > Dmitry. > > > > > > > > On Tue, Feb 10, 2015 at 9:59 AM, Joe Watkins > wrote: > > > > > 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 > wrote: > > > > > >> Hi, > > >> > > >> can I make some minor correction? > > >> > > >> Thanks. Dmitry. > > >> > > >> > > >> > > >> On Tue, Feb 10, 2015 at 9:25 AM, Yasuo Ohgaki > wrote: > > >> > > >>> Hi Dmitry, > > >>> > > >>> On Tue, Feb 10, 2015 at 1:43 PM, Dmitry Stogov > wrote: > > >>> > > >>>> On Feb 9, 2015 11:20 PM, "Yasuo Ohgaki" wrote= : > > >>>> > > > >>>> > Hi Dmitry and Joe, > > >>>> > > > >>>> > On Mon, Feb 9, 2015 at 8:27 PM, Dmitry Stogov > > >>>> 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 > > >>>> >> > > >>>> 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 us= e > > >>>> interface for DbC. > > >>>> > > > >>>> > > >>>> In D classes may have "invariant" constraints. We may use "require= " > > >>>> keyword for it. The constraints ineritance rules and order of call= s > > >>>> to constrains must be the same s in D. > > >>>> > > >>>> class Foo { > > >>>> private $sum =3D 0; > > >>>> require($this->sum >=3D 0); // invariant constraint will be > > >>>> called before and after every method > > >>>> function add($n) { > > >>>> $this->sum +=3D $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 productio= n > > >>>> (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 =3D 0; > > >>>> require($this->sum >=3D 0); // invariant constraint will be > > >>>> called before and after every method > > >>>> function add($n) { > > >>>> $this->sum +=3D $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. > > >>>> > > > >>>> > > >>>> > 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=3DOn/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=3D1 script.php > > >>>> > > > >>>> > should be used. > > >>>> > > > >>>> > > > >>>> > And finally, are we going to allow custom assertion error messag= e? > > >>>> 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", w= e > > >>>> > 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 th= e > 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 > > >>> yohgaki@ohgaki.net > > >>> > > >> > > >> > > > > > --001a11c28f6cd09336050eb9062c--