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 > > > |
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 |
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 |
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 ....> > > 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 |
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 |
>>> 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 |
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 |
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. > > :) > > I was too short on TreeModel knowledge to go forward but this didn't > break CodeCritic. -- Alain |
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 |
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 |
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 ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;. |
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 |
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 ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;. |
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 |
> 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 ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;. |
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 |
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. |
Free forum by Nabble | Edit this page |