Run time checking with design by contract assertions
Hi, I have downloaded a first version of IceCompiler, a small tool who allow run time checks embedding in pharo classes on Smalltalkhub at http://smalltalkhub.com/#!/~AlainRastoul/IceCompiler If some interested pharoers are willing to give me feedback on this package I would greatly appreciate. This is not an announce but a request for feedback to advanced pharo users , since it is an alpha version with probably killing side effects. There is no ConfigurationOf as of today(there will be), but there is no dependency and the package loads well in a fresh standard Pharo 5.0. Checks are written in standard smalltalk methods with design-by-contract style pragmas like <contract: invariant> <contract: #ensured appliedTo: #( #add: )> <contract: #required appliedTo: #( #add: )> Contract method calls are compiled in specified classes (with subclasses) in order to make bullet-proofing run test phases of Pharo code/image and to help in hard bug cases. Before trying this package, please read the comments on smalltalk hub page, because if misused it may break your image, and do not use on standard important classes (Array, String, Dictionary, Collection etc.) ... unless you like danger :) Many thanks in advance regards, Alain
This is cool. Having contract is really something I always wanted. I do not know if Ice refers to Eiffel compiler mode but this is nice. Le 25/2/16 23:48, Alain Rastoul a écrit :
Hi,
I have downloaded a first version of IceCompiler, a small tool who allow run time checks embedding in pharo classes on Smalltalkhub at
http://smalltalkhub.com/#!/~AlainRastoul/IceCompiler
If some interested pharoers are willing to give me feedback on this package I would greatly appreciate. This is not an announce but a request for feedback to advanced pharo users , since it is an alpha version with probably killing side effects. There is no ConfigurationOf as of today(there will be), but there is no dependency and the package loads well in a fresh standard Pharo 5.0.
Checks are written in standard smalltalk methods with design-by-contract style pragmas like
<contract: invariant> <contract: #ensured appliedTo: #( #add: )> <contract: #required appliedTo: #( #add: )>
Contract method calls are compiled in specified classes (with subclasses) in order to make bullet-proofing run test phases of Pharo code/image and to help in hard bug cases.
Before trying this package, please read the comments on smalltalk hub page, because if misused it may break your image, and do not use on standard important classes (Array, String, Dictionary, Collection etc.) ... unless you like danger :)
Many thanks in advance
regards,
Alain
Alain can you give two example how to use the contract: ? I would understand: <precondition: [can we pass a block here] > Stef Le 25/2/16 23:48, Alain Rastoul a écrit :
Hi,
I have downloaded a first version of IceCompiler, a small tool who allow run time checks embedding in pharo classes on Smalltalkhub at
http://smalltalkhub.com/#!/~AlainRastoul/IceCompiler
If some interested pharoers are willing to give me feedback on this package I would greatly appreciate. This is not an announce but a request for feedback to advanced pharo users , since it is an alpha version with probably killing side effects. There is no ConfigurationOf as of today(there will be), but there is no dependency and the package loads well in a fresh standard Pharo 5.0.
Checks are written in standard smalltalk methods with design-by-contract style pragmas like
<contract: invariant> <contract: #ensured appliedTo: #( #add: )> <contract: #required appliedTo: #( #add: )>
Contract method calls are compiled in specified classes (with subclasses) in order to make bullet-proofing run test phases of Pharo code/image and to help in hard bug cases.
Before trying this package, please read the comments on smalltalk hub page, because if misused it may break your image, and do not use on standard important classes (Array, String, Dictionary, Collection etc.) ... unless you like danger :)
Many thanks in advance
regards,
Alain
On 26/02/2016 10:16, stepharo wrote:
Alain
can you give two example how to use the contract: ?
I would understand:
<precondition: [can we pass a block here] >
Stef
Hi Stef, Yes this is completely inspired by Bertrand Meyer/Eiffel work. I did an help page on that in the package info description on smalltalkhub with more info, but here is an abstract: precondition, postconditions, invariants are smalltalk checking methods that returns true or false and check that the object will perform/has performed (pre/post) as expected and is in a coherent state (invariants) . This is not about program proof but run time checking. I first tried with a block expressed as text in pragma as you suggest (and as done in some frameworks with comments) but it was difficult to use MetaLink with that, and MetaLink is a powerfull tool I wouldn't (and probably couldn't!) rewrite Adding smalltalk methods is much more powerfull than simple text since it integrates well with standard tools (debugger, browsers etc). Those checks can be compiled in all the methods with the Icecompiler and removed by recompiling the class with the standard compiler. examples : an invariant (a condition that is *allways* true) on a MyCollection class would be expressed as a checkIndex method of class MyCollection like: checkIndex <contract: invariant> ^ firstIndex > 0 meaning : on every method call to MyCollection, firstIndex *must* be > 0 if firstIndex goes <= 0 then the collection has a broken state this will be checked before and after *every call* of *every method* of MyCollection (except in the constructor an in other contract methods). a pre condition to a call to add: method preAdd: anObject <contract: #required appliedTo: #( #add: )> ^ anObject ~= self meaning : you must not add a collection to itself (note: this is just an example and I am not sure of that, I think it does not make sense to add a collection to itself but may be this is allowed?) this will be checked before every call to MyCollection>>add: (note2: appliedTo: allows to apply this check to several specific methods - I didn't tested it yet but if it does not work then this is a bug) a post condition that would be checked after every call: postAdd: anObject <contract: #ensured appliedTo: #( #add: )> ^ self includes: anObject . woudl check that after adding an object to a Mycollection, the collection effectivly includes the object. If it does not, this is reported as an error. names (checkIndex, preAdd: , postAdd:) are not important, they are like other methods of MyCollection. The important thing is the 'appliedTo' part of the pragma who indicates to which methods the contract applies.
Hi Alain, Having contract is a valuable effort!
On Feb 26, 2016, at 11:12 AM, Alain Rastoul <alf.mmm.cat@gmail.com> wrote:
<contract: #ensured appliedTo: #( #add: )>
What does that mean? <contract: #ensured appliedTo: #( #add: )> Alexandre -- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
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 <alf.mmm.cat@gmail.com> 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
I still do not understand. I would imagine something like: foo <precondition: #invariant> <postcondition: #invariant> self bar But, all in all, what are we using pragmas here? I can always do: self assert: [ ⦠] description: ⦠Maybe we should specific a method called contractInvariant that is always executed before and after. Using Reflectivity. Alexandre
On Feb 26, 2016, at 11:50 AM, Alain Rastoul <alf.mmm.cat@gmail.com> wrote:
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 <alf.mmm.cat@gmail.com> 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
-- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
On 26/02/2016 12:30, Alexandre Bergel wrote:
I still do not understand. I would imagine something like:
foo <precondition: #invariant> <postcondition: #invariant> self bar
But, all in all, what are we using pragmas here? I can always do: self assert: [ ⦠] description: â¦
Maybe we should specific a method called contractInvariant that is always executed before and after. Using Reflectivity.
Alexandre
Assertions are used in standard java framework, but have hard side effects : stopping the program immediately. (cf http://www.oracle.com/us/technologies/java/assertions-139853.html "...The program will be aborted if the expression evaluates to false..") With java it is possible, since the IDE and program are separated. With Pharo you cannot, if you assert or throw an error in a sensible place, you are likely to hang your image or to go for multiple errors poping everywhere since you will break the state of an important object. Another thing is that with dbc paradigm (assertions about your code), there is no 'one invariant' but lots of, you will not be able to express them in a single method, even if you could it would be hundreds lines and you would have to copy them in all methods you will want to check. The complete horror to maintain when you change your code. The use of pragmas make it possible to activate or deactivate those contracts at compilation time, there will no overhead in standard execution without contracts. Think of the pragmas as a way to "inject" invariant compiled code into the compiled method for testing, then you recompile without for release. Adding invariants will have *big* performance impact, probably several orders of magnitude, I'll measure. The overhead will of course come from calls of the checking framework, but no doubt that with run-time reflexivity checking, you will have something as sluggish too and you'll want to deactivate them at compile time ... I'm ready to bet on that one beer ... :) -- Alain
Assertions are used in standard java framework, but have hard side effects : stopping the program immediately. (cf http://www.oracle.com/us/technologies/java/assertions-139853.html "...The program will be aborted if the expression evaluates to false..") With java it is possible, since the IDE and program are separated.
With Pharo you cannot, if you assert or throw an error in a sensible place, you are likely to hang your image or to go for multiple errors poping everywhere since you will break the state of an important object.
I do not think so. It is like putting a "self haltâ (or âHalt nowâ). It is all done using exceptions.
Another thing is that with dbc paradigm (assertions about your code), there is no 'one invariant' but lots of, you will not be able to express them in a single method, even if you could it would be hundreds lines and you would have to copy them in all methods you will want to check. The complete horror to maintain when you change your code.
I would not be that pessimistic.
The use of pragmas make it possible to activate or deactivate those contracts at compilation time, there will no overhead in standard execution without contracts. Think of the pragmas as a way to "inject" invariant compiled code into the compiled method for testing, then you recompile without for release.
Adding invariants will have *big* performance impact, probably several orders of magnitude, I'll measure. The overhead will of course come from calls of the checking framework, but no doubt that with run-time reflexivity checking, you will have something as sluggish too and you'll want to deactivate them at compile time â¦
currently, the class Object define the method: -=-=-=-=-=-=-=-=-= Object>>assert: aBlock "Throw an assertion error if aBlock does not evaluates to true. We check for true explicitly to make the assertion fail for non booleans" aBlock value == true ifFalse: [AssertionFailure signal: 'Assertion failedâ] -=-=-=-=-=-=-=-=-= It looks like a pretty convenient way to handle assertion. Nearly the same as in standard Java. Java offers the âassertâ keywords, that you can disable by setting adequate option in the JVM. If you want to disable the assertions in your class, you can simply redefine #asset: that does nothing. Sure, you can imagine a solution using pragmas, but sincerely, I do not think it will be more flexible than using #assert:. Again, Javaâs assertions are very similar to what we have now. However, I am pretty convinced there are great opportunities on writing assertions. It is really hard to write them, which is why not many are doing so. Cheers, Alexandre
--
Alain
-- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
On 26/02/2016 16:37, Alexandre Bergel wrote: ...
With Pharo you cannot, if you assert or throw an error in a sensible place, you are likely to hang your image or to go for multiple errors poping everywhere since you will break the state of an important object.
I do not think so. It is like putting a "self haltâ (or âHalt nowâ). It is all done using exceptions.
Yes, that's the point: they are lots of places where you simply cannot put self halt (timers, background processes - though in this case it works... debugger magic :), window resizing, mouse events )
Another thing is that with dbc paradigm (assertions about your code), there is no 'one invariant' but lots of, you will not be able to express them in a single method, even if you could it would be hundreds lines and you would have to copy them in all methods you will want to check. The complete horror to maintain when you change your code.
I would not be that pessimistic.
Even if you write dedicated check methods to avoid pollute your code, you will have to call all the logic of your controls in each method, and decide for each one what checks are applicable or not. Thinking about object state checks (invariants), I cannot imagine I'll have to add a: 'self checkThatxxx' in all the methods of my class... ...
Sure, you can imagine a solution using pragmas, but sincerely, I do not think it will be more flexible than using #assert:. Again, Javaâs assertions are very similar to what we have now. However, I am pretty convinced there are great opportunities on writing assertions. It is really hard to write them, which is why not many are doing so.
Thinking again about java asserts, they are more powerful framework who do not use assert but comments which is like using pragmas. http://www.javaworld.com/article/2074956/learn-java/icontract--design-by-con... (they are plenty others, look at the end of https://en.wikipedia.org/wiki/Design_by_contract in the language support) In fact you are pointing to at the whole benefit of contracts when you say that you can call assert or another method: of you own : the good thing is that they are not linked to your code logic, they are here to check things that you did not anticipate where they could happen. You express what is correct for each method on entry, exit, about the state of the object and the checks are injected into your code... And you see this method that you would never have thought it could do that in this improbable place ... :) It is just a different way of checking that things are running ok under the hood Ah, and I am not against asserts or breakpoints, using contracts does not forbid you to use assert: ... :) -- Alain
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
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
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.
:)
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
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
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 <alf.mmm.cat@gmail.com> 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 ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
Alexandre Bergel <alexandre.bergel@me.com> writes:
I still do not understand. I would imagine something like:
foo <precondition: #invariant> <postcondition: #invariant> self bar
I have the same feeling. It looks strange to me that the precondition itself decides where it applies. I have the impression that each method should list its preconditions. -- Damien Cassou http://damiencassou.seasidehosting.st "Success is the ability to go from one failure to another without losing enthusiasm." --Winston Churchill
On 26/02/2016 16:36, Damien Cassou wrote:
Alexandre Bergel <alexandre.bergel@me.com> writes:
I still do not understand. I would imagine something like:
foo <precondition: #invariant> <postcondition: #invariant> self bar
Hi Damien, Sorry for seeming pedantic but the concept is precise : when you express an invariant it must be true for all code of your class. (and they are several invariants for one class of course) 'Invariants' are conditions that do not change (hence the name) they are about object state, they are not post or pre conditions they are always true, in each methods, before and after if you specify in which methods they are true, it means they could be false in others and then they are not invariants by defintion ...
I have the same feeling. It looks strange to me that the precondition itself decides where it applies. I have the impression that each method should list its preconditions.
That said, I think your example would be: foo <precondition: myFooPrecondition> <postcondition: myFooPostcondition> or something like: foo <precondition: myFooPrecondition1, myFooPrecondition2 etc...> <postcondition: myFooPostcondition1, myFooPostcondition2 etc...> you would say in each method what check applies. That could be possible and the result would be the same IMHO a bit less flexible, but another option. Q: where would you define the invariants ? a method that is never call and is tagged ? myFooInvariant1 <invariant> -- Alain
Alain Rastoul <alf.mmm.cat@gmail.com> 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
Alexandre Bergel <alexandre.bergel@me.com> writes:
But, all in all, what are we using pragmas here? I can always do: self assert: [ ⦠] description: â¦
you can do that for preconditions, but for postconditions it is harder because there can be several exit points in a method. -- Damien Cassou http://damiencassou.seasidehosting.st "Success is the ability to go from one failure to another without losing enthusiasm." --Winston Churchill
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 <alf.mmm.cat@gmail.com> 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
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
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 <alf.mmm.cat@gmail.com> wrote:
<contract: #ensured appliedTo: #( #add: )>
What does that mean? <contract: #ensured appliedTo: #( #add: )>
Alexandre
In fact I think may be better to use #before and #after since it is what is used internally with MetaLink, it is clear and more developper friendly, with singular and plural forms : for contracts applied to only one method: <contract: #before method: #add:> <contract: #after method: #add:> for contracts applied to several methods: <contract: #before methods: #( #add: #addLast: #addIfNotPresent:)> <contract: #after methods: #( #add: #addLast: #addIfNotPresent:)> what do you think of that ? -- Alain
2016-02-25 23:48 GMT+01:00 Alain Rastoul <alf.mmm.cat@gmail.com>:
Hi,
I have downloaded a first version of IceCompiler, a small tool who allow run time checks embedding in pharo classes on Smalltalkhub at
http://smalltalkhub.com/#!/~AlainRastoul/IceCompiler
If some interested pharoers are willing to give me feedback on this package I would greatly appreciate. This is not an announce but a request for feedback to advanced pharo users , since it is an alpha version with probably killing side effects. There is no ConfigurationOf as of today(there will be), but there is no dependency and the package loads well in a fresh standard Pharo 5.0.
Checks are written in standard smalltalk methods with design-by-contract style pragmas like
<contract: invariant> <contract: #ensured appliedTo: #( #add: )> <contract: #required appliedTo: #( #add: )>
can you use symbols only for pragma arguments, please. <contract: #invariant> instead of <contract: invariant> I am about to change rbparser to only allow constant literal arguments
Contract method calls are compiled in specified classes (with subclasses) in order to make bullet-proofing run test phases of Pharo code/image and to help in hard bug cases.
Before trying this package, please read the comments on smalltalk hub page, because if misused it may break your image, and do not use on standard important classes (Array, String, Dictionary, Collection etc.) ... unless you like danger :)
Many thanks in advance
regards,
Alain
On 26/02/2016 11:23, Nicolai Hess wrote:
can you use symbols only for pragma arguments, please.
<contract: #invariant> instead of <contract: invariant>
I am about to change rbparser to only allow constant literal arguments
Yes, no problem I noticed it worked but was not sure it was right thank you for pointing that
On 25-02-16 23:48, Alain Rastoul wrote:
Hi,
I have downloaded a first version of IceCompiler, a small tool who allow run time checks embedding in pharo classes on Smalltalkhub at
How does this compare to the earlier uContracts work by Angelo Lozano, Kim Mens and Andy Kellens? Stephan
On 26/02/2016 13:15, Stephan Eggermont wrote:
How does this compare to the earlier uContracts work by Angelo Lozano, Kim Mens and Andy Kellens?
Stephan
Well, I didn't know about that package, it looks good. At least looking description on their web site, there is a cool integration with Moose/Famix. My package is at POC stage right now, probably far less elaborated and more oriented towards runtime checking and debugging than contract designing . Very interesting, I'll digg into that. Thank you for the pointer -- Alain
On 25/02/2016 23:48, Alain Rastoul wrote: @Stef, Alexandre, Damien, Nicolai, Stephan, Thank you for the discussions, pointing me errors and interesting link. I understood that the concept and/or it's implementation seems a bit obscure, partly because of the syntax I've chosen for pragmas. I will conform to some naming standards : #invariant/#pre/#post/on: will be clearer than #required/#ensured/appliedTo:. <contract: #invariant> ... <contract: #pre on: #aMethod> ... <contract: #pre on: #( #aMethod1 ... #aMethodn)> ... idem post: <contract: #post on: #aMethod> ... <contract: #post on: #( #aMethod1 ... #aMethodn)> ... I also note the suggestion of Damien (putting the pragma contracts in the methods) but I am not truly convinced and it would imply some rework, so I will not do that now - perhaps after a try. examples fooContract1 <contract: #invariant> ^ myState notNil. fooContract2 <contract: #post on: #foo> ... postAdd: anObject <contract: #post on: #(add: #addLast:)> ^ self includes: anObject etc. -- Alain
participants (6)
-
Alain Rastoul -
Alexandre Bergel -
Damien Cassou -
Nicolai Hess -
Stephan Eggermont -
stepharo