Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:82335 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 14341 invoked from network); 10 Feb 2015 06:59:32 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 10 Feb 2015 06:59:32 -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.49 cause and error) X-PHP-List-Original-Sender: pthreads@pthreads.org X-Host-Fingerprint: 209.85.220.49 mail-pa0-f49.google.com Received: from [209.85.220.49] ([209.85.220.49:61214] helo=mail-pa0-f49.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 64/07-47508-35CA9D45 for ; Tue, 10 Feb 2015 01:59:32 -0500 Received: by mail-pa0-f49.google.com with SMTP id fb1so24305982pad.8 for ; Mon, 09 Feb 2015 22:59:28 -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=FtdJcn6EYOGBDkS6fbLbXh61IlBVU62ToUbZrz4HfIs=; b=OhfyoifxkS3YaySp3+QkNluz2HUIVVHs5nDvjyVO0VWL79/q9iEQNpTYd9JPEyd+HZ B5uxq9ZqAoX6w4Db5PFUCkq6p3X5cD6tmaxoTI+zw2xww9F+LCV2umxouZipaqD0zioM xon0aRf/bu+i2T1dMC7ikgb5maUVnOONzsFqv3D1qsl3/LHxeA0ld1+BTZlD548GwULI rvpoyA8vGKzWcR+s0w/g9sTeLwoAprOBrTFmEzVwcGjxLvojbp5hSFK/XhXinalpYQGt /Y7euI4P/aLapb0VSWnnv5OroGqEDIkvFmwqmwKQ4WvJhI/UqUkSFoWUFTrShoIeyRWf /tLQ== X-Gm-Message-State: ALoCoQldptQKeBXUAe4h1uT5zhEO4x9gMlqKZ5gL2N/LqLD3lGaYFCiaMSsIgYB4Gb8upf2rQuWC MIME-Version: 1.0 X-Received: by 10.68.109.195 with SMTP id hu3mr5431953pbb.84.1423551568298; Mon, 09 Feb 2015 22:59:28 -0800 (PST) Received: by 10.70.49.100 with HTTP; Mon, 9 Feb 2015 22:59:28 -0800 (PST) X-Originating-IP: [109.145.22.92] In-Reply-To: References: <54D7ED22.3080001@gmail.com> Date: Tue, 10 Feb 2015 06:59:28 +0000 Message-ID: To: Dmitry Stogov Cc: Yasuo Ohgaki , PHP Internals , Stanislav Malyshev Content-Type: multipart/alternative; boundary=047d7b86f3568c5dcf050eb66d63 Subject: Re: [PHP-DEV] Design by Contract From: pthreads@pthreads.org (Joe Watkins) --047d7b86f3568c5dcf050eb66d63 Content-Type: text/plain; charset=UTF-8 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 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. >>> > >>> > >> > 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 >> yohgaki@ohgaki.net >> > > --047d7b86f3568c5dcf050eb66d63--