Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:81958 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 53423 invoked from network); 5 Feb 2015 18:58:51 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 5 Feb 2015 18:58:51 -0000 Authentication-Results: pb1.pair.com smtp.mail=dmitry@zend.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=dmitry@zend.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain zend.com designates 209.85.220.175 as permitted sender) X-PHP-List-Original-Sender: dmitry@zend.com X-Host-Fingerprint: 209.85.220.175 mail-vc0-f175.google.com Received: from [209.85.220.175] ([209.85.220.175:37871] helo=mail-vc0-f175.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 73/19-27691-96DB3D45 for ; Thu, 05 Feb 2015 13:58:51 -0500 Received: by mail-vc0-f175.google.com with SMTP id la4so3381301vcb.6 for ; Thu, 05 Feb 2015 10:58:47 -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=k+kVGZ93xPaYsHp8UCnR3dmd1DTWIMyRi9PVVjjKXKE=; b=BoyZW8UKo1k4oRZb+ArM6nxmqVKcK+c4Mr2L5YTukxM+Uf8LsGO3nfJXKDngsmY/tO 10jY06rLa24duhnuA9NuxM0BUCkzJSL7xM4kTaiXxyD9a8KcC2koArxcOvhw9xxJnxpJ wkyyo0ZD+8cyxGeAlBjB8VNlvgJSpRluES1cnhDY4c09U4HpewFBfxXmhvC38qaCCHRH hoGpvYNS5wJx5CtflPEarPU3P0cb6ea9uigNSuOnCzxg597XosdDwYub4N/UykrvGSTg y/w8z54WoZyw0pvgjXoFr3CX58w7W4vYcttpfB4gGJhrKVi6QBR+9sbIFFzctlPgyKGe 7j6w== X-Gm-Message-State: ALoCoQnNa38n7a+YnGkGC5mJePmfdzkKN908rExeYjNrZf61owRObxGYALNh8s5mznSuv2UQvx5/vBzk9nD4Y6Ozo9yderrnelLf19/9FqDpHqkh56DEmx+Y3A9QRBBsZaUFO9vvesS/ddNxSUe57ecP2bJkD/A//w== MIME-Version: 1.0 X-Received: by 10.220.5.195 with SMTP id 3mr3569409vcw.21.1423162727026; Thu, 05 Feb 2015 10:58:47 -0800 (PST) Received: by 10.52.74.73 with HTTP; Thu, 5 Feb 2015 10:58:46 -0800 (PST) In-Reply-To: References: <01d601d04146$6fbda4c0$4f38ee40$@tekwire.net> <020c01d0414b$2c3a1120$84ae3360$@tekwire.net> <023201d0415e$5731d800$05958800$@tekwire.net> Date: Thu, 5 Feb 2015 22:58:46 +0400 Message-ID: To: Yasuo Ohgaki Cc: =?UTF-8?Q?Fran=C3=A7ois_Laupretre?= , Pierre Joye , PHP internals Content-Type: multipart/alternative; boundary=001a11c3ef80cd6dc1050e5be41e Subject: Re: [PHP-DEV] Design by Contract From: dmitry@zend.com (Dmitry Stogov) --001a11c3ef80cd6dc1050e5be41e Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable If we allow any statements in require/ensure, then we should use {} instead of() function foo($a, $b) reuire { ... } ensure($ret) { ... } { } my idea was to restrict constraint code to expression. in this case () would be enough. it should be possible to use few constraint expressions. we may also add error messages like in assert(). function add($a, $b) require(is_numeric($a) && $a >=3D 0, "some error message") require(is_numerc($b) && $b >=3D 0, "another error message") ensure($ret >=3D 0, "yet another error message) { return $a + $b; } both proposals may work, of course. I don't think we should chose "right" approach right now. It's better to collect few possible solutions e.g. statements, expressions, doc-comments, attributes... then describe their pros and cons to select the best one Thanks. Dmitry. Thanks. Dmitry. On Thu, Feb 5, 2015 at 8:54 PM, Yasuo Ohgaki wrote: > Hi Francois, > > On Fri, Feb 6, 2015 at 1:18 AM, Yasuo Ohgaki wrote: > >> >> On Fri, Feb 6, 2015 at 1:11 AM, Fran=C3=A7ois Laupretre >> wrote: >> >>> > De : yohgaki@gmail.com [mailto:yohgaki@gmail.com] De la part de Yasuo >>> Ohgaki >>> >>> > We don't have to integrate DbC into phpdoc. phpdoc may have >>> integration of new DbC syntax. >>> > I think it's helpful even if phpdoc copies post/pre condition as >>> document. >>> > >>> > There are too many possibility for DbC syntax. >>> > We are better to choose something in common among languages. >>> >>> No. The more I detail the concept, the more I read alternative >>> proposals, the more I consider extending phpdoc is the best solution. A= s I >>> explain in the RFC, both concepts are closely related, and that's the o= nly >>> solution I've seen so far that preserves BC. I could add that it propos= es a >>> solution to issues not even detected nor discussed in alternative >>> proposals, like the syntax for return value, separate check for argumen= ts >>> returned by ref, built-in type checks, etc. Before we choose an alterna= tive >>> syntax, I think we should have good reasons, not 'Hey, that's how it's = done >>> in D !'. If there's a good reason to copy D or Eiffel syntax, let's ado= pt >>> it, but I haven't read any good reason so far. And D is not so widely u= sed >>> so there's no user habit. We can copy the concept without copying the >>> syntax. >>> >>> I think we're going too fast here. Before giving up and switching to >>> another syntax, can you give me a little time to present what I have in >>> mind. I started writing it yesterday evening and it will be ready >>> tomorrow morning (UTC). Then, we can make a decision. >>> >> >> I didn't notice you have updated the RFC sorry. Sure, I'll read it and >> respond. >> > > https://wiki.php.net/rfc/dbc > > Thank you for your time. It's based on annotation approach. This kind of > implementation requires a lot of work... > > I have more simpler approach in my mind based on current PHP language > not to invent new language. I'll use syntax something similar to Dmitry > proposed. > > Let me explain my original thought. > > Since we have reserved __functionname(), __some_functioname() should not > have > BC issues. > ---------------- > function foo($param) > require ( // Compiled as __require_foo($param) > // Any PHP code is allowed and works just like PHP function. > // Abuse is possible. Users have freedom shoot their own foot. > assert('is_string($param'); > if (strlen($param) > 100) { > echo "String is more than 100\n"; > return FALSE; // return value is ignored. > } > ) > ensure ( // Compiled as __ensure_foo($__return_value) > // Same as require. Any PHP code > assert('is_int($__return_value)'); // $__return_value is the return val= ue > assert($__return_value > 0); > ) > invariant ( // Check conditions always true. It may be __invariant_foo() > // Question is should this have foo() scope? > // Same as require/ensure. Any PHP code. > // invariant() exists not to repeat require()/ensure() > ) > // Function body > { > // BODY > } > ---------------------- > > Zend engine has 2 execute() > > - execute() - Just execute foo() > - execute_dev() - Call functions as follows > > __require_foo($param) > __invariant() > foo() > __invariant() > __ensure_foo($__return_value) > > > With this approach, parser and compiler needs little modification and > execute_dev() can handle additional functions while execute() only > executes foo(). execute_dev() is simple because it just calls plain PHP > functions if they exists. > > Is there is syntax error or assertion error. Error messages look like > > PHP Warning: assert(): asdfasdf failed in __require_foo() on line 2 > > This is simple yet useful/easy to use/powerful/flexible/fast. > Any checks can be done with PHP syntax. I think assert() should be used > usually, though. > > I thought to use require{} rather than require() because {} seemed > natural for function. > > This is my thought. It's almost D. > I don't know about AST much, so AST may be better/easier than having > 2 execute(). > > Regards, > > -- > Yasuo Ohgaki > yohgaki@ohgaki.net > > --001a11c3ef80cd6dc1050e5be41e--