On 03/11/2012 03:21 AM, Damian Conway wrote:
> Carl asked:
> 
>>    class A {
>>        method foo($x) {
>>            PRE { $x < 10 }
>>            # ...
>>        }
>>    }
>>
>>    class B is A {
>>        method foo($a, $b, $c) {
>>            PRE { [>] $a, $b, $c }
>>            # ...
>>        }
>>    }
>>
>> When C<B.foo> is called, are both C<PRE> blocks meant to be run?
> 
> No. Contractual constraints are only inherited by methods of the
> same signature.

And here the problem already starts. Signatures with where-blocks can't
by compared by a Turing machine. At least we know which signatures we
can compare and which we can't. So we need to think about that case too.

> BTW, that example isn't Liskov substitutable, so it really doesn't
> matter what it does under DbC. ;-)
> 
> Also, it would be much better if such cases issued a warning in Perl 6,
> rather than just silently hiding the inherited method and thereby
> breaking the shared polymorphic interface of the hierarchy.

+1

Though of course then we need a mechanism to silence that warning.


> For a start, PRE- and POST- inheritance should only occur when a derived
> method does indeed have the same signature as some base method, and then
> only from that identically signatured method. Secondly, PREs have to be
> inherited disjunctively (i.e. be allowed to weaken), rather than being
> conjunctively accumulated (i.e. being forced to to strengthened).
> 
> 
>> In fact, method-level C<PRE> and C<POST> cease to be a concept, C<PRE>
>> and C<POST> submethods can be handled delicately in a corner of the
>> MOP somewhere, the abomination that is C<CALL-VIA-DBC> goes away, and
>> all that we're really left with are block-level C<PRE> and C<POST>
>> phasers, which already seem like they could work.
>>
>> So, what do y'all think?
> 
> 
> I think this is probably the only reasonable way forward at the moment.
> What we've proposed as a DbC mechanism in the spec can't be implemented
> for all the reasons Carl enumerated so well.
> 
> However, I'd also want the spec to remove all reference to DbC when talking
> about PRE and POST. Or, better still, to state explicitly that PRE and
> POST do *not* have DbC semantics when applied to methods (perhaps even
> using some of the examples above to illustrate why not).
> 
> And if we are ever to properly supply DbC, then I think we'd also want
> to explicitly reserve--but not spec--the phaser names REQUIRE and ENSURE
> for possible later use (either in-core or via a future 'use contracts'
> pragma or module that some heroic soul may attempt write. ;-)

I think we reserve all-caps names anyway, though I can't find the
reference to it right now.

> 
> On the other hand, because DbC "requires" and "ensures" are really
> much more like (inheritable) traits of a method's signature,
> rather than phasers tied to the method's block, it seems likely that
> any eventual DbC mechanism should not use phasers at all. So perhaps
> we ought to reserve the traits 'will require' and 'will ensure' so that the
> eventual DbC mechanism could be specified like so:
> 
>     class A {
>         method foo(Num $x --> Num $result)
>           will require { $x < 10 }
>           will ensure  { $result > $x }
>         {
>             return 2 * $x;
>         }
>     }
> 
>     class B is A {
>         method foo(Num $x --> Num)
>           will require { $x < 100 }
>         {
>             return $x+1;
>         }
>    }

Just a small syntax nit: I think your example of 'will require BLOCK' is
a violation of the rule that we shouldn't have two terms in a row.
Probably better to go with 'requires' and 'ensures' traits right away:

method foo(Num $x --> Num $result)
  requires { $x < 10 }
  ensures  { $result > $x }
  {
     return 2 * $x;
  }


> And, yes, this does indeed imply a syntax for optionally naming the
> return value in a signature (which syntax seems to fall out quite
> naturally in any case).

Or we simply reuse the convention from POST and CATCH that the
interesting value (either exception or return value) is passed in as $_.

Reply via email to