# DbC for PHP?

- Thread: https://externals.io/message/71659
- Original archive: https://news-web.php.net/php.internals/71659
- Started by Yasuo Ohgaki on 2014-01-28T07:05:01+00:00
- Messages: 8
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #71659 — Yasuo Ohgaki — 2014-01-28T07:05:01+00:00

URL: https://externals.io/message/71659#71659

Hi all,

I'm wandering if we could have DbC (Design by Contract) for PHP 6.
http://en.wikipedia.org/wiki/Design_by_contract

There is user land implementation already.
https://gitorious.org/higher-order-php/php-contracts/source/5b0a53b9732f0e4dbe79345212c84c74526def3b:

It could be done with dbc mode INI switch as follows.

When dbc=on, automatically includes

include __dbc_ . __SCRIPT_NAME__;

 when a script is loaded. No error if there is not the script.
When function/method is called

__dbc_pre_. __FUNCTION__() is called before calling function().
__dbc_post_.___FUNCTION__() is called after function() call.

No error if there is not the function.

Class methods would be more complex, but basic idea is the same.
Issue would be what we should do with $this with class methods.

Automatic namespace might be nice to have for both function and class.

When dbc=off, these would be skipped at all.

It does not sacrifice performance at all for production while it could catch
various errors during development. It could do more complex assertion
than `assert()` and it could check post condition that is difficult to achieve
by `assert()`. User could have their own strong type safety as long as they
have strict input validation. It could be used as complement of annotation.

Just an idea.
Any comments?

Regards,

--
Yasuo Ohgaki
yohgaki@ohgaki.net

---

## #71660 — Sebastian Krebs — 2014-01-28T08:36:08+00:00

URL: https://externals.io/message/71659#71660 · In reply to: #71659

2014-01-28 Yasuo Ohgaki <yohgaki@ohgaki.net>

> Hi all,
>
> I'm wandering if we could have DbC (Design by Contract) for PHP 6.
> http://en.wikipedia.org/wiki/Design_by_contract
>
> There is user land implementation already.
>
> https://gitorious.org/higher-order-php/php-contracts/source/5b0a53b9732f0e4dbe79345212c84c74526def3b
> :
>
> It could be done with dbc mode INI switch as follows.
>
> When dbc=on, automatically includes
>
> include __dbc_ . __SCRIPT_NAME__;
>
>  when a script is loaded. No error if there is not the script.
> When function/method is called
>
> __dbc_pre_. __FUNCTION__() is called before calling function().
> __dbc_post_.___FUNCTION__() is called after function() call.
>
> No error if there is not the function.
>

Couldn't you achieve the same with `assert()`?


>
> Class methods would be more complex, but basic idea is the same.
> Issue would be what we should do with $this with class methods.
>
> Automatic namespace might be nice to have for both function and class.
>
> When dbc=off, these would be skipped at all.
>
> It does not sacrifice performance at all for production while it could
> catch
> various errors during development. It could do more complex assertion
> than `assert()` and it could check post condition that is difficult to
> achieve
> by `assert()`. User could have their own strong type safety as long as they
> have strict input validation. It could be used as complement of annotation.
>
> Just an idea.
> Any comments?
>
> Regards,
>
> --
> Yasuo Ohgaki
> yohgaki@ohgaki.net
>



-- 
github.com/KingCrunch

---

## #71665 — Alexander Lisachenko — 2014-01-28T11:05:11+00:00

URL: https://externals.io/message/71659#71665 · In reply to: #71660

Hello!

Design by Contract can be achieved with Aspect-Oriented technology, as it
provides set of hooks, such as before method execution, after method
execution, around method execution, etc. Logic of contract can be easily
defined as an aspect - class that will receive a control before or after
method execution to check the contract. For example, we can introduce an
annotation as a contract for method and just verify (eval) this contract
during method execution.

Here is my one-minute implementation with Go! AOP framework. First step is
to define an empty Contract annotation:

use Doctrine\Common\Annotations\Annotation;

/**
 * @Annotation
 * @Target("METHOD")
 */
class Contract extends Annotation
{
}

Next step is to create an aspect, that will be called before each method
that has "Contract" annotation:

class ContractAspect implements Aspect
{
    /**
     * Verify a contract for a methods annotated with Contract annotation
     *
     * @param MethodInvocation $invocation
     * @Before("@annotation(Annotation\Contract)")
     */
    public function beforeContract(MethodInvocation $invocation)
    {
        $__parameters = $invocation->getMethod()->getParameters();
        $__argumentNames = array_map(function (\ReflectionParameter
$parameter) {
            return $parameter->name;
        }, $__parameters);
        $__parameters = array_combine($__argumentNames,
$invocation->getArguments());

        extract($__parameters, EXTR_SKIP);
        $contract =
$invocation->getMethod()->getAnnotation(Contract::class);
        $result = eval("return {$contract->value}; ?>");
        if (!$result) {
            $obj  = $invocation->getThis();
            $objName = is_object($obj) ? get_class($obj) : $obj;
            $methodName = $invocation->getMethod()->name;
            throw new \LogicException("Contract {$contract->value} violated
for {$objName}->{$methodName}");
        }
    }
}

And now it's possible to use this annotation anywhere to define a contract
for method:

use Annotation\Contract;

class Test
{
    /**
     * @Contract("strlen($foo) > 6")
     */
    public function bar($foo)
    {
        echo $foo;
    }
}

// test.php
$foo = new Test;
$foo->bar('1234567'); // no error
$foo->bar('12'); // LogicException: Contract strlen($foo) > 6 violated for
Test->bar;

What do you think about such implementation of contracts? Feedback is
appreciated.

2014-01-28 Sebastian Krebs <krebs.seb@gmail.com>

> 2014-01-28 Yasuo Ohgaki <yohgaki@ohgaki.net>
>
> > […]
> https://gitorious.org/higher-order-php/php-contracts/source/5b0a53b9732f0e4dbe79345212c84c74526def3b
> > […]
>
> Couldn't you achieve the same with `assert()`?
>
>
> > […]
> annotation.
> > […]
>
>
>
> --
> github.com/KingCrunch

---

## #71712 — Yasuo Ohgaki — 2014-01-29T04:18:05+00:00

URL: https://externals.io/message/71659#71712 · In reply to: #71660

Hi Sebastian,

On Tue, Jan 28, 2014 at 5:36 PM, Sebastian Krebs <krebs.seb@gmail.com>wrote:

> I'm wandering if we could have DbC (Design by Contract) for PHP 6.
> > […]
>
> Couldn't you achieve the same with `assert()`?
>

Assert can be used for DbC and there are such implementations.

Precondition is easy with `assert()`, but post condition is rather difficult
since
we need `assert()` before every 'return'. This could damage production code
(code executed on production environment) and contract readability. It
increases
chances of omitting post condition check by mistake.

Similar mistake may happen with this.
We may better to have option to warn non existent pre/post check.


Like Alexander explained, pure OO code can use DbC. It may be enough
for people who are interested in DbC.

This is just an idea. It's simple, powerful and easy to adopt. Since there
is no DbC code in production code, it's fast while `assert()` need
compilation
overhead. It does not matter much with opcache, though.

With this approach, user has to look up contract in other file. This is
disadvantage over other methods.

I wander how many of us are interested in such feature.

Regards,

--
Yasuo Ohgaki
yohgaki@ohgaki.net

---

## #71719 — Ivan Enderlin @ Hoa — 2014-01-29T08:48:14+00:00

URL: https://externals.io/message/71659#71719 · In reply to: #71659

> Hi all,
Hello :-),


> I'm wandering if we could have DbC (Design by Contract) for PHP 6.
> http://en.wikipedia.org/wiki/Design_by_contract
>
> There is user land implementation already.
> https://gitorious.org/higher-order-php/php-contracts/source/5b0a53b9732f0e4dbe79345212c84c74526def3b:
>
> It could be done with dbc mode INI switch as follows.
>
> When dbc=on, automatically includes
>
> include __dbc_ . __SCRIPT_NAME__;
>
>   when a script is loaded. No error if there is not the script.
> When function/method is called
>
> __dbc_pre_. __FUNCTION__() is called before calling function().
> __dbc_post_.___FUNCTION__() is called after function() call.
>
> No error if there is not the function.
What kind of errord would you like to print? “The precondition has 
failed”, ok but why? With what data?


> Class methods would be more complex, but basic idea is the same.
> Issue would be what we should do with $this with class methods.
>
> Automatic namespace might be nice to have for both function and class.
>
> When dbc=off, these would be skipped at all.
>
> It does not sacrifice performance at all for production while it could catch
> various errors during development. It could do more complex assertion
> than `assert()`
So the pre- and postconditions must be predicates, i.e. computing a boolean.


> and it could check post condition that is difficult to achieve
> by `assert()`. User could have their own strong type safety as long as they
> have strict input validation. It could be used as complement of annotation.
>
> Just an idea.
> Any comments?
What about invariants which is the third part of DbC?


Did you heard about Praspel [1]. Praspel is a BISL (Behavioral Interface 
Specification Language), i.e. a specification language for 
contract-based testing I develop in my PhD thesis (in INRIA 
laboratories). You will find some materials here [2]. I recommend you to 
start by the presentations/keynotes. The idea is to allow the user to 
write contracts (precondition, postcondition, exceptional postcondition, 
invariant, behavior etc.), and we exploit them in order to generate 
(unit) tests automatically.

I'm reaching the end of my PhD and I'm currently writing the 
documentation and finalizing the tools. Today, we are able to:
     (1) generate very different kinds of data (strings with regexs or 
grammars thanks to grammar-based testing algorithms [3, 4], arrays 
thanks to an array-solver [5] etc.)
     (2) verify a contract with a Runtime Assertion Checker (please, see 
articles or directly the code [6])
     (3) automatically generate (unit) tests that are executable with 
atoum's API [7, 8]

We are preparing videos and documentations in order to promote it up to 
June. I suggest to read the presentations, you will get an overview of 
all the work.

I think DbC must stay annotations, so in comments of the code. If 
contracts would be part of the PHP grammar, it would be disappointed for 
everyone because there is no unique way to express a contract: either 
with the language syntax itself (such as JML [9]) or with a dedicated 
language, such as Praspel. Both have pros and cons that I won't describe 
here (except if you ask).
However, having the Aspect Oriented Programming paradigm would be very 
appreciated. It would avoid a lot of instrumentations and static analyzes.


Regards.

[1] https://en.wikipedia.org/wiki/Praspel
[2] http://hoa-project.net/En/Literature.html#Research
[3] http://keynote.hoa-project.net/Amost12/EDGB12.pdf
[4] https://github.com/hoaproject/Compiler (documentation is under 
translation)
[5] http://keynote.hoa-project.net/Cstva13/EGB13.pdf
[6] https://github.com/hoaproject/Praspel/tree/master/AssertionChecker
[7] http://atoum.org/
[8] https://github.com/hoaproject/Hoathis-Atoum
[9] https://en.wikipedia.org/wiki/Java_Modeling_Language

-- 
Ivan Enderlin
Developer of Hoa
http://hoa-project.net/

PhD. student at DISC/Femto-ST (Vesontio) and INRIA (Cassis)
http://disc.univ-fcomte.fr/ and http://www.inria.fr/

Member of HTML and WebApps Working Group of W3C
http://w3.org/

---

## #71721 — Sebastian Krebs — 2014-01-29T11:09:39+00:00

URL: https://externals.io/message/71659#71721 · In reply to: #71712

2014-01-29 Yasuo Ohgaki <yohgaki@ohgaki.net>

> Hi Sebastian,
>
> On Tue, Jan 28, 2014 at 5:36 PM, Sebastian Krebs <krebs.seb@gmail.com>wrote:
>
> > […]
>
> Assert can be used for DbC and there are such implementations.
>
> Precondition is easy with `assert()`, but post condition is rather difficult
> since
> we need `assert()` before every 'return'.
>

Well .. Yeah. But that is difficult?


> This could damage production code
> (code executed on production environment) and contract readability. It
> increases
> chances of omitting post condition check by mistake.
>

This is possible with every implementation...


>
> Similar mistake may happen with this.
> We may better to have option to warn non existent pre/post check.
>
>
> Like Alexander explained, pure OO code can use DbC. It may be enough
> for people who are interested in DbC.
>
> This is just an idea. It's simple, powerful and easy to adopt. Since there
> is no DbC code in production code, it's fast while `assert()` need
> compilation
> overhead. It does not matter much with opcache, though.
>

No, at least not measurable. You can disable it. In that case it behaves
like an empty function body.


>
> With this approach, user has to look up contract in other file. This is
> disadvantage over other methods.
>
> I wander how many of us are interested in such feature.
>
> Regards,
>
> --
> Yasuo Ohgaki
> yohgaki@ohgaki.net
>
>


-- 
github.com/KingCrunch

---

## #71751 — Yasuo Ohgaki — 2014-01-29T20:31:46+00:00

URL: https://externals.io/message/71659#71751 · In reply to: #71719

Hi Ivan,

On Wed, Jan 29, 2014 at 5:48 PM, Ivan Enderlin @ Hoa <
ivan.enderlin@hoa-project.net> wrote:

> I think DbC must stay annotations, so in comments of the code. If
> contracts would be part of the PHP grammar, it would be disappointed for
> everyone because there is no unique way to express a contract: either with
> the language syntax itself (such as JML [9]) or with a dedicated language,
> such as Praspel. Both have pros and cons that I won't describe here (except
> if you ask).
> However, having the Aspect Oriented Programming paradigm would be very
> appreciated. It would avoid a lot of instrumentations and static analyzes.
>

This idea is a too simple and leaving almost all to user land scripts.

I agree that DbC must stay annotations. It's easier to write/read/maintain.
Unfortunately, annotation RFC is not accepted.

I agree that comprehensive implementation should be chosen if it's possible.
Thank you for your inputs!

[1] https://en.wikipedia.org/wiki/Praspel
[2] http://hoa-project.net/En/Literature.html#Research
[3] http://keynote.hoa-project.net/Amost12/EDGB12.pdf
[4] https://github.com/hoaproject/Compiler (documentation is under
translation)
[5] http://keynote.hoa-project.net/Cstva13/EGB13.pdf
[6] https://github.com/hoaproject/Praspel/tree/master/AssertionChecker
[7] http://atoum.org/
[8] https://github.com/hoaproject/Hoathis-Atoum
[9] https://en.wikipedia.org/wiki/Java_Modeling_Language

I'll read them later.

Regards,

--
Yasuo Ohgaki
yohgaki@ohgaki.net

---

## #71759 — Rowan Collins — 2014-01-29T22:13:28+00:00

URL: https://externals.io/message/71659#71759 · In reply to: #71665

> Here is my one-minute implementation with Go! AOP framework.
[...]
>
> class Test
> {
>      /**
>       * @Contract("strlen($foo) > 6")
>       */
>      public function bar($foo)
>      {
>          echo $foo;
>      }
> }

So, dozens of lines of boilerplate, Reflection, and other obscure 
features (including, presumably, a userland implementation of 
annotations) and the end result is ... an assertion. The pre-condition 
is not being added as an aspect, it's hard-coded right there next to the 
function, doing exactly the same thing as adding this single line at the 
top of the function:

assert('strlen($foo) > 6');

Post-conditions are a little trickier: they require a 
single-point-of-return (something which has its advocates anyway, and 
could easily be enforced as a project coding standard) and potentially 
introduce an intermediate variable that could otherwise be skipped. But 
this seems like a lot of overhead to work around that.

Now, I realise that this was a simple example, but I would be interested 
to see what such an approach could actually offer in return for its 
complexity.

Regards,

-- 
Rowan Collins
[IMSoP]
