Run time checking with design by contract assertions

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
37 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Re: Run time checking with design by contract assertions

stepharo
You see if me and alex got confused and we know quite well what is
design by contract
then better changed the syntax

Stef

Le 26/2/16 11:50, Alain Rastoul a écrit :

> On 26/02/2016 11:26, Alexandre Bergel wrote:
>> Hi Alain,
>>
>> Having contract is a valuable effort!
>>
>>> On Feb 26, 2016, at 11:12 AM, Alain Rastoul <[hidden email]>
>>> wrote:
>>>
>>> <contract: #ensured appliedTo: #( #add: )>
>>
>> What does that mean?
>> <contract: #ensured appliedTo: #( #add: )>
>>
>> Alexandre
>>
> Hi Alexandre,
>
> a method with a pragma
> <contract: #ensured appliedTo: #( #add: ) >
> means it is a check that must be ensured by  (enforced by) the method
> to which it applies (here add:).
> The add: method of the object *must* verify this check, when the check
> is executed, it must return true.
>
> May be the terms I've choosed are confusing at first, but it was
> voluntary, preCondition, postCondition are too much program execution
> oriented IMHO, not enough assertive .
>
> btw it is easy to change:
> one could say here:
> <contract: postcondition on: #( #add: )>
>
> may be better ?
>
> or may be better to support both ... :)
>
>
> Alain
>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: Run time checking with design by contract assertions

stepharo
In reply to this post by Alain Rastoul-2
I like the idea that you package to postcondition, invariant and
precondition
not in the methods themselves but in separate methods.
I did not think about that but this is nice because you do not pollute
the code
and we could put them in a precondition protocols.

About the pragma why not

isEmpty

     <preconditionOf: #add:>

I think that it is nicer than

         <contract: #postcondition ....>


Now can you support the old value?

Stef

Reply | Threaded
Open this post in threaded view
|

Re: Run time checking with design by contract assertions

Alain Rastoul-2
In reply to this post by stepharo
On 26/02/2016 20:47, stepharo wrote:
> You see if me and alex got confused and we know quite well what is
> design by contract
> then better changed the syntax
>
> Stef
>

Yes, of course, that's what I thought.
This is done and on smalltalkhub now.

As soon as Marcus implement the return node in MetaLink as he said, I
add the ability to test the returned values.
There is lot left to do, I'll add more tests and refactor in the meanwhile.
I'm eager to see the result of this poc.
:)


--

Alain


Reply | Threaded
Open this post in threaded view
|

Re: Run time checking with design by contract assertions

Alain Rastoul-2
In reply to this post by stepharo
On 26/02/2016 20:51, stepharo wrote:
> I like the idea that you package to postcondition, invariant and
> precondition
> not in the methods themselves but in separate methods.
> I did not think about that but this is nice because you do not pollute
> the code
> and we could put them in a precondition protocols.
Yes that was the idea.
to think about what your code should do without being in code logic or
reading to much the code ie.
keep it separated from the implementation .
even with another browser like the tools pointed to by Stephan which
looks really cool (the screen shots a least)

>
> About the pragma why not
>
> isEmpty
>
>      <preconditionOf: #add:>
>
> I think that it is nicer than
>
>          <contract: #postcondition ....>
>
>
Yes  much nicer ...
And the same with <postconditionOf:..>
much clearer

> Now can you support the old value?

yes, I think no problem to support both
that's a part I'll refactor anyway, it is a bit ugly because I changed
several times and wanted to make my tests pass.

Another point is that I would like to use it on itself, see how it runs
on itself, but also how I can express it in terms of contracts ...

>
> Stef
>
>


--

Alain


Reply | Threaded
Open this post in threaded view
|

Re: Run time checking with design by contract assertions

Alain Rastoul-2
On 26/02/2016 21:23, Alain Rastoul wrote:
> On 26/02/2016 20:51, stepharo wrote:

>> Now can you support the old value?

Sorry I responded too quickly, I thought you where talking of the syntax
(no problem)
but you mean the value before the call I guess.
I didn't understood at first.
yes it should be possible too, a bit trickier, with an small extra cost
in performance but cool

--

Alain


Reply | Threaded
Open this post in threaded view
|

Re: Run time checking with design by contract assertions

stepharo

>>> Now can you support the old value?
>
> Sorry I responded too quickly, I thought you where talking of the
> syntax (no problem)
> but you mean the value before the call I guess.
> I didn't understood at first.
> yes it should be possible too, a bit trickier, with an small extra
> cost in performance but cool

You see this is a lot more difficult than it appears. ***Ideally*** old
should be a full copy of the object :)
But we can live with an approx solution.

In any case I would really love to see if we can have contracts in
classes in Pharo libraries and
see how it improves them.

I would like to see the performance penalties.
What we could have is the following:

     When we run the tests we run them twice
     One with contracts on and one without contracts.

     - first the results should be same :)
     - second the contracts should be working

     Then we could start to have test harnessing (I know that guys from
argentina did some libraries for that)
     and we could have better tests and find bugs in code by using the
contracts.

Stef

Reply | Threaded
Open this post in threaded view
|

Re: Run time checking with design by contract assertions

Alain Rastoul-2
On 26/02/2016 22:01, stepharo wrote:
>
> You see this is a lot more difficult than it appears. ***Ideally*** old
> should be a full copy of the object :)
> But we can live with an approx solution.

You are right, I didn't thought about this problem at all,
I was thinking about the way to connect the two objects wrapping the
method calls with MetaLink, and the implications in the workflow of the
compiler front-end  I did (rewrite several parts in fact).
I don't measure all the implications of making a deep copy, a shallow
copy or no copy (pointers only), but this could be a parameter at run-time
>
> In any case I would really love to see if we can have contracts in
> classes in Pharo libraries and
> see how it improves them.
>
> I would like to see the performance penalties.
> What we could have is the following:
>
The extra cost is almost only in what is done in the checks :

I did the small test of using a FakeOrderedCollection (the one in
IceCompiler-Core-Tests package) and adding  10K integer to it, with and
without contracts and I had terrible results : more than 2mn with
contract checking, less than 1s without (I don't remember the exact
values) without, but no surprise at all, all the cost was in the
collection>>includes: check done in the postCondition:
postAdd: anObject
        ^ self includes: anObject
who does a scan of the collection ....
The cost of MetaLink or IceContractor and co is neglectable for a
run-time check IMHO, abd  when releasing, all the code will be
recompiled without contract checking.
>      When we run the tests we run them twice
>      One with contracts on and one without contracts.
>
>      - first the results should be same :)
>      - second the contracts should be working
But this is done in the tests classes in the IceCompiler package with
very small runs and my intention is to add more tests.
I may be ashamed but you can look at the code... ( don't flame me please
, I'm no coder and I know I have to refactor lot of things) ... ;)

The approach I took is to have a blackbox to record test failures, no
assert, exceptions or whatever, I just record failures, because I wanted
to be non intrusive/agressive towards the system.
And this could be a parameter too.

I also recompiled the CriticBrowser with an invariant to see where
something was wrong with right-click/ban from selected package (DNU).
nb : the invariant was :

rulesModelChildrenUnderstandLeaves
        <contract: invariant>
        ^ rulesModel selectedItem ifNil: [ true ] ifNotNil: [ :rule | rule
respondsTo: #leaves ]

because the DNU was on 'leaves' not understood.

:)

I was too short on TreeModel knowledge to go forward but this didn't
break CodeCritic.



>
>      Then we could start to have test harnessing (I know that guys from
> argentina did some libraries for that)
>      and we could have better tests and find bugs in code by using the
> contracts.
>
> Stef
>
>


--

Alain


Reply | Threaded
Open this post in threaded view
|

Re: Run time checking with design by contract assertions

Alain Rastoul-2
On 26/02/2016 23:01, Alain Rastoul wrote:

> I also recompiled the CriticBrowser with an invariant to see where
> something was wrong with right-click/ban from selected package (DNU).
> nb : the invariant was :
>
> rulesModelChildrenUnderstandLeaves
>      <contract: invariant>
>      ^ rulesModel selectedItem ifNil: [ true ] ifNotNil: [ :rule | rule
> respondsTo: #leaves ]
>
> because the DNU was on 'leaves' not understood.
>
> :)
>
forgot to say that I had several stack traces recorded in the black box ...

> I was too short on TreeModel knowledge to go forward but this didn't
> break CodeCritic.



--

Alain


Reply | Threaded
Open this post in threaded view
|

Re: Run time checking with design by contract assertions

Alain Rastoul-2
On 26/02/2016 23:06, Alain Rastoul wrote:
> On 26/02/2016 23:01, Alain Rastoul wrote:
>> I also recompiled the CriticBrowser with an invariant to see where
>> something was wrong with right-click/ban from selected package (DNU).

Thought there is still something related to ast/recompilation I have to
investigate : It start with a DNU in IRTranslatorV2 with a packageCount
not found that it should find,

the second time you open Critic Browser it is ok


If you want to try this, with IceCompiler package  installed
copy paste the following in a playground and do in sequence:

" 1. add the invariant method I gave to CriticBrowser (may be it is
completely false but whatever) :

rulesModelChildrenUnderstandLeaves

        <contract: invariant>
       
        ^ rulesModel selectedItem ifNil: [ true ] ifNotNil: [ :rule | rule
respondsTo: #leaves ].
       

then
"

"2 .recompile CriticBrowser with the invariant:"
IceCompiler compile: CriticBrowser .

"3. open an inspector on the blacbox"
IceReporter open .


" 4. do CriticBrowser stuff here
  4.1 open CritiBrowser on my package,
first time DNU to investigate related to Metalink ast recompilation I guess
close it

   4.2 then second time, opening CriticBrowser is ok

   4.3 then right click on rule, select 'ban from selected package'
=> DNU"

"5.refresh the blackbox, you will see the traces of contract failures"

"6. clean the CriticBrowser compiled methods from contracts (ie recompile)"
IceCompiler clean: CriticBrowser



fun
:)

--

Alain


Reply | Threaded
Open this post in threaded view
|

Re: Run time checking with design by contract assertions

Damien Cassou-2
In reply to this post by Alain Rastoul-2
Alain Rastoul <[hidden email]> writes:

> Q: where would you define the invariants ?
>
> a method that is never call and is tagged ?
>
> myFooInvariant1
> <invariant>

indeed.

--
Damien Cassou
http://damiencassou.seasidehosting.st

"Success is the ability to go from one failure to another without
losing enthusiasm." --Winston Churchill

Reply | Threaded
Open this post in threaded view
|

Re: Run time checking with design by contract assertions

abergel
In reply to this post by stepharo
> Now can you support the old value?

Yes, that is a crucial point. This is a feature that having Object>>assert: aBlock cannot easily emulate

Alexandre
--
_,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:
Alexandre Bergel  http://www.bergel.eu
^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.




Reply | Threaded
Open this post in threaded view
|

Re: Run time checking with design by contract assertions

Alain Rastoul-2
On 28/02/2016 20:59, Alexandre Bergel wrote:
> Yes, that is a crucial point. This is a feature that having Object>>assert: aBlock cannot easily emulate
Hi Alexandre
yes it is possible, with the limitation pointed to by Stef: deep copy is
a complex thing and I don't measure the implications.
I can't figure out the result of a stack deep copy (ie a thiscontext
object), thinking just about this one, they are others.
May be DeepCopier would help ?

They are other situations leading to unpredictable results.
(Object>>#value)
        ast link: (
                MetaLink new
                metaObject: true;
                control: #after;
                arguments: #( ) ;
                selector: #value ) .
hangs the vm immediatly -it's like sawing off the branch on which we are
sitting.
This situation that can be protected with a simple fencing mechanism
(avoiding checking of some classes and/or methods), but more complex
cases will show off.

More investigations are needed here,
but even not perfect, this would still be a valuable tool IMHO


--

Alain


Reply | Threaded
Open this post in threaded view
|

Re: Run time checking with design by contract assertions

abergel
Having a solid Design by Contract mechanism is notoriously difficult to have. What you can do, is to have a shallow copy for now. If necessary, you may have a bounded deep copy. But do not use #deepCopy. They are many objects where you cannot do a #deepCopy, because it will copy the whole image, and it does not handle cycles.

Cheers,
Alexandre


> On Feb 29, 2016, at 8:31 AM, Alain Rastoul <[hidden email]> wrote:
>
> On 28/02/2016 20:59, Alexandre Bergel wrote:
>> Yes, that is a crucial point. This is a feature that having Object>>assert: aBlock cannot easily emulate
> Hi Alexandre
> yes it is possible, with the limitation pointed to by Stef: deep copy is a complex thing and I don't measure the implications.
> I can't figure out the result of a stack deep copy (ie a thiscontext object), thinking just about this one, they are others.
> May be DeepCopier would help ?
>
> They are other situations leading to unpredictable results.
> (Object>>#value)
> ast link: (
> MetaLink new
> metaObject: true;
> control: #after;
> arguments: #( ) ;
> selector: #value ) .
> hangs the vm immediatly -it's like sawing off the branch on which we are sitting.
> This situation that can be protected with a simple fencing mechanism (avoiding checking of some classes and/or methods), but more complex cases will show off.
>
> More investigations are needed here,
> but even not perfect, this would still be a valuable tool IMHO
>
>
> --
>
> Alain
>
>

--
_,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:
Alexandre Bergel  http://www.bergel.eu
^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.




Reply | Threaded
Open this post in threaded view
|

Re: Run time checking with design by contract assertions

Alain Rastoul-2
On 29/02/2016 09:27, Alexandre Bergel wrote:
> Having a solid Design by Contract mechanism is notoriously difficult to have. What you can do, is to have a shallow copy for now. If necessary, you may have a bounded deep copy. But do not use #deepCopy. They are many objects where you cannot do a #deepCopy, because it will copy the whole image, and it does not handle cycles.
Hi Alexandre

Thank you for your response, and sorry for responding late, I couldn't
take time, my bad.
Yes you are definitely right, design by contract implementation is
difficult, there is lot of papers and research done by brilliant people
on the subject, that's why I classified this work under POC on the
readme page of smalltalkhub.
I have no pretention to do a perfect dbc implmentation, I just want to
see at first  stage if a simple implementation based on the MetaLink can
work.
And it currently works, with some limitations : no returned value
support, no old value support (for now), and some work to do on pragma
syntax (like postconditionOf: suggested by Stef).
I should be able to work on those points in few weeks.

About old value support, right, no doubt that deepCopy will not work,
but a shallow copy will certainly not pass checks too .
Experimenting with that I found Object>>veryDeepCopy with DeepCopier,
and that lot of classes implements veryDeepCopyWith: deepCopier
Also it seems that it handles several  cases without hanging ...
Do you have any opinion or advices on that ?
Did you use it ?
Thanks


--

Alain


Reply | Threaded
Open this post in threaded view
|

Re: Run time checking with design by contract assertions

abergel
> Experimenting with that I found Object>>veryDeepCopy with DeepCopier, and that lot of classes implements veryDeepCopyWith: deepCopier
> Also it seems that it handles several  cases without hanging ...
> Do you have any opinion or advices on that ?
> Did you use it ?

I would do a recursive copy with a fixed amount of recursion. So, this is not a shallowCopy, and not a deepCopy, but somewhere in between. And the end user can decide.

Alexandre
--
_,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:
Alexandre Bergel  http://www.bergel.eu
^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.




Reply | Threaded
Open this post in threaded view
|

Re: Run time checking with design by contract assertions

Alain Rastoul-2
On 02/03/2016 21:29, Alexandre Bergel wrote:
> I would do a recursive copy with a fixed amount of recursion. So, this is not a shallowCopy, and not a deepCopy, but somewhere in between. And the end user can decide.
thank you for advice, kinda what I thought
:)


--

Alain


Reply | Threaded
Open this post in threaded view
|

Re: Run time checking with design by contract assertions

stepharo
In reply to this post by Alain Rastoul-2


Le 2/3/16 20:00, Alain Rastoul a écrit :
> I have no pretention to do a perfect dbc implmentation, I just want to
> see at first  stage if a simple implementation based on the MetaLink
> can work.

Yes incremental and working is better than excellent and not finished.


12