I will try to explain but that’s not so clear for me too.

 

The theory (from Eiffel guru) states that, to respect this fucking LSP rule, 
the pre-conditions to check when entering a method must be less strict than 
when entering its parent method. Don’t ask why, I don’t understand the reason 
very well. But that’s his rule, and everyone seems to respect it.

 

In your RFC, you say that, when we enter a method, we must check its 
pre-conditions, as well as the ones of every parents. As you can only add 
conditions, compared to what you would do for the parent, the checks can only 
be stricter (more conditions).

 

The logic described in the D documentation is : if a method defines 
pre-conditions, check them and stop (don’t check parent’s pre-conditions). If 
the method does not define pre-conditions, go down one level and check if 
parent method defines some. As soon as a method defining pre-conditions is 
found, these are checked and control is returned without going further. This 
way, it is still the developer’s responsibility to loosen conditions in derived 
classes but it is possible. If you check every parent’s pre-conditions, it is 
just *not* possible.

 

I am not sure I am clear.

 

I chose not to follow exactly this logic as I think we can do it more ‘PHP way’ 
(something like the way constructors and destructors explicitly call their 
parent methods). My logic is : if the method we are entering has no 
pre-conditions, we don’t check anything (don’t search a parent method). If it 
defines some, we execute them. I introduce a ‘special’ condition : the 
‘@parent’ pseudo-condition means ‘go down checking my parent’s conditions’. 
This way, similar to ‘parent::__construct()’ logic allows the developer to 
decide if he wants to check parent’s conditions or not.

 

Example :

 

/**

* @requires ($a < $b)

* @requires @parent   <- Go checking parent’s pre-conditions

* @requires …

 

For better consistence, I chose to implement the same for post-conditions and 
invariants, but I am not sure I will keep

the same logic.

 

The only thing that remains not clear for me is the role of conditions defined 
in interfaces, as the D documentation says that they can be defined but it does 
not explain when they are checked. I assume this is considered as a parent but 
the order matters in pre-conditions as we only execute the first conditions we 
find. I think I’ll assume that ‘@parent’ means ‘check the conditions defined in 
the parent method and the method of the interface that defines it’. 
Unfortunately, interfaces have parents too and can define methods with same 
name. So, it’s the same sort of problems as multiple inheritance. I will need 
to make a choice here. The simplest one would be ‘no support for DbC in 
interfaces’.

 

 

De : yohg...@gmail.com [mailto:yohg...@gmail.com] De la part de Yasuo Ohgaki
Envoyé : samedi 14 février 2015 05:16
À : francois
Cc : Dmitry Stogov; Joe Watkins; Stanislav Malyshev; PHP Internals
Objet : Re: [PHP-DEV] Design by Contract

 

Hi Francois,

 

On Sat, Feb 14, 2015 at 12:53 PM, Yasuo Ohgaki <yohg...@ohgaki.net> wrote:

On Sat, Feb 14, 2015 at 12:03 PM, François Laupretre <franc...@php.net> wrote:

> For method calls, overridden method should not evaluate parents contract on 
> entry.
> It should be evaluated when parent method is called.

I already told you : the logic you are using for pre-conditions is NOT 
compatible with Eiffel and D logic, although this is what you're supposed to 
mimic. It is actually the opposite. Is it a wanted behavior ? because you 
should be aware that it does not respect the LS principle.


Did you mean "Least Concern Principle" here?


I'm lost here. Eiffel does not even allow method overriding. Therefore, child 
class's method contract 

will never evaluated unless it is explicitly called. Semantics is basically the 
same as what I wrote. 

(Eiffel requires to drop parent method by "redefine" or rename parent method by 
"rename" when 

the same method name is needed)

 

I agree that Eiffel's approach is stricter with respect to least concern 
principle.

It's just not suitable for PHP, is it?

 

Similar argument can be done for D's invariant. D dropped invariant from class 
in favor of

immutables. Immutable is better for least concern, but we don't have immutables 
now.

Even if we have it, people would like to manage object state. We may have both.

 

Anyway, could you explain what kind of issues we may have?

 

Regards,




--
Yasuo Ohgaki 
yohg...@ohgaki.net

Reply via email to