Hi folks:During this week someone wanted to use SqueakDBX in Squeak 3.8 and at the same time another person (thanks Marcelo Cortez!!!) has ported it to Dolphin. And I found something weird in TestCase >> assert: In Squeak 3.10 TestCase >> assert: aBooleanOrBlock Squeak 3.8, Dolphin and VAST (I don't know others) have: TestCase >> assert: aBoolean So...is there a reason of doing that? Is this expected? cheers mariano
In Squeak 3.10 TestCase >> assert: aBooleanOrBlock
Squeak 3.8, Dolphin and VAST (I don't know others) have: TestCase >> assert: aBoolean
So...is there a reason of doing that? Is this expected?
I do not see any particular reason. But having Object>>assert: aBlock is important, since one can simply redefine assert: in a class to supress all assertions. Alexandre -- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
Em 14/10/2009 17:11, Alexandre Bergel <alexandre@bergel.eu> escreveu:
In Squeak 3.10 TestCase >> assert: aBooleanOrBlock Squeak 3.8, Dolphin and VAST (I don't know others) have: TestCase
assert: aBoolean So...is there a reason of doing that? Is this expected?
I do not see any particular reason. But having Object>>assert: aBlock is important, since one can simply redefine assert: in a class to supress all assertions.
Which begs the question: then why the same method is re-implemented in TestCase anyway?
csrabak@bol.com.br wrote:
Em 14/10/2009 17:11, Alexandre Bergel <alexandre@bergel.eu> escreveu:
In Squeak 3.10 TestCase >> assert: aBooleanOrBlock Squeak 3.8, Dolphin and VAST (I don't know others) have: TestCase
assert: aBoolean So...is there a reason of doing that? Is this expected? I do not see any particular reason. But having Object>>assert: aBlock is important, since one can simply redefine assert: in a class to supress all assertions.
Which begs the question: then why the same method is re-implemented in TestCase anyway?
...just thinking 'aloud'... TestCase>>assert:, by convention, accepts a Boolean, and could be extended to also accept a block (and apparently has been so extended in Squeak). Object>>assert: *should* accept a block, and it isn't really useful for it to accept a Boolean. As Alexandre says, you can suppress assertions by redefining #assert:. One could also make Object>>assert: depend on some variable somewhere to determine whether to actually run the assertion blocks. Then you can turn assertions on and off system-wide, and not be running that assertion code in the blocks all the time. If you accepted a boolean, you'd be running the assertion expression whether assertions were turned on or not, which is undesirable. It's not too nice if Object>>assert: and TestCase>>assert: take different kinds of arguments TestCase>>assert: takes a Boolean. I suspect that's too widely used to change. I don't know how widely used Object>>assert: is. Perhaps we could have a different selector for that which takes a block. Maybe a selector that implies more strongly that its argument should be a block. Our test framework (which I believe predates SUnit) uses #run:forResult:, with a block for the first argument and the expected result of evaluating the block as the second argument. I like this for a couple of reasons -- run: strongly implies that it should take a block argument, and giving the expected result separately allows failure messages of the form "Expected <a>; got <b>" which is handy anytime but *really* useful when failures are not easily reproducible. Regards, -Martin P.S. -- the following is marginally related: In performance-critical code that is executed *very* frequently, even making a message send and checking whether assertions are turned on or not can have too much impact. In those situations, I banish all assertions to a subclass, which has methods of this general form: someMethod | result | self assert: [assertions appropriate on entry to this method]. result := super someMethod. self assert: [assertions appropriate on exit from this method]. ^result. Then to turn assertions on or off, I have code that can change the class of the instances, and switch whether new instances are of the no-assertions class or the with-assertions subclass. This allows the application to run at full speed when assertions are turned off, a real advantage in some cases. This also separates the normal code from the assertion code, which has both advantages and disadvantages.
Em 14/10/2009 20:59, Martin McClure <martin@hand2mouse.com> escreveu:
csrabak@bol.com.br wrote: > Em 14/10/2009 17:11, Alexandre Bergel escreveu: > >>> In Squeak 3.10 TestCase >> assert: aBooleanOrBlock Squeak >>> 3.8, Dolphin and VAST (I don't know others) have: TestCase >>>>> assert: aBoolean So...is there a reason of doing that? Is >>> this expected? >> I do not see any particular reason. But having >> Object>>assert: aBlock is important, since one can simply >> redefine assert: in a class to supress all assertions. > Which begs the question: then why the same method is > re-implemented in TestCase anyway?
...just thinking 'aloud'...
TestCase>>assert:, by convention, accepts a Boolean, and could be extended to also accept a block (and apparently has been so extended in Squeak).
I see. I _think_ the idea of having it more 'compatible' with other dialects changing it back to accept a Boolean and keeping TestCase>>should: aBlock is a better way.
Object>>assert: *should* accept a block, and it isn't really useful for it to accept a Boolean.
I was keeping with your and Alexandre's reasoning, but when I look for HierarchyImplementors of #assert: starting from Object the only one I get (in a Pharo1.0beta dev image updated to 10470) are: Object>>assert: {error handling} TestCase>>assert: {accessing} So in Pharo we brought a functionality very up in the hierarchy.
As Alexandre says, you can suppress assertions by redefining #assert:. One could also make Object>>assert: depend on some variable somewhere to determine whether to actually run the assertion blocks. Then you can turn assertions on and off system-wide, and not be running that assertion code in the blocks all the time. If you accepted a boolean, you'd be running the assertion expression whether assertions were turned on or not, which is undesirable.
It's not too nice if Object>>assert: and TestCase>>assert: take different kinds of arguments
TestCase>>assert: takes a Boolean. I suspect that's too widely used to change.
I agrre as I wrote above, for blocks we have TestCase>>should:.
I don't know how widely used Object>>assert: is. Perhaps we could have a different selector for that which takes a block.
I don't either, but I find strange the complete hierarchy of classes of Pharo having a method assert: available. Perhaps I'm blindfolded and Pharo and Squeak have found a wider use for assertions?
Maybe a selector that implies more strongly that its argument should be a block.
I think TestCase>>should: suffices for that.
Our test framework (which I believe predates SUnit) uses #run:forResult:, with a block for the first argument and the expected result of evaluating the block as the second argument. I like this for a couple of reasons -- run: strongly implies that it should take a block argument, and giving the expected result separately allows failure messages of the form "Expected ; got " which is handy anytime but *really* useful when failures are not easily reproducible.
Yes, I see, but I think this is lateral to this discussion!
Regards,
-Martin
P.S. -- the following is marginally related:
In performance-critical code that is executed *very* frequently, even making a message send and checking whether assertions are turned on or not can have too much impact. In those situations, I banish all assertions to a subclass, which has methods of this general form:
someMethod | result | self assert: [assertions appropriate on entry to this method]. result := super someMethod. self assert: [assertions appropriate on exit from this method]. ^result.
Then to turn assertions on or off, I have code that can change the class of the instances, and switch whether new instances are of the no-assertions class or the with-assertions subclass.
This allows the application to run at full speed when assertions are turned off, a real advantage in some cases. This also separates the normal code from the assertion code, which has both advantages and disadvantages.
I really don't follow this, are you using assertions for checking invariants a la Eiffel?
csrabak@bol.com.br wrote:
TestCase>>assert:, by convention, accepts a Boolean, and could be extended to also accept a block (and apparently has been so extended in Squeak).
I see. I _think_ the idea of having it more 'compatible' with other dialects changing it back to accept a Boolean and keeping TestCase>>should: aBlock is a better way.
Agreed. [...]
I don't know how widely used Object>>assert: is. Perhaps we could have a different selector for that which takes a block.
I don't either, but I find strange the complete hierarchy of classes of Pharo having a method assert: available. Perhaps I'm blindfolded and Pharo and Squeak have found a wider use for assertions?
Ah, sorry for the confusion. What I'm talking about here (and I assumed Alexandre was as well, but I could be mistaken) is indeed the use of #assert: or some other message to test runtime invariants. So you'd put something like: self assert: [startIndex < endIndex]. somewhere in the main code of your application, not in test code. The nice thing about using blocks is that the assertion code inside the block doesn't run if global assertions are turned off, or if (as Alexandre suggests) you temporarily override #assert: in your class to do nothing. It's this rather separate use that I was suggesting might want a different selector, and gave #run:forResult: as one possible example. Regards, -Martin
I don't know how widely used Object>>assert: is. Perhaps we could have a different selector for that which takes a block.
I don't either, but I find strange the complete hierarchy of classes of Pharo having a method assert: available. Perhaps I'm blindfolded and Pharo and Squeak have found a wider use for assertions?
Ah, sorry for the confusion. What I'm talking about here (and I assumed Alexandre was as well, but I could be mistaken) is indeed the use of #assert: or some other message to test runtime invariants. So you'd put something like: [...]
This is exactly what I had in mind I regularly use assert: to describe invariant, pre and postcondition. This complement testing pretty well in my opinion. Cheers, Alexandre -- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
Alexandre Bergel wrote:
Ah, sorry for the confusion. What I'm talking about here (and I assumed Alexandre was as well, but I could be mistaken) is indeed the use of #assert: or some other message to test runtime invariants. So you'd put something like: [...]
This is exactly what I had in mind I regularly use assert: to describe invariant, pre and postcondition. This complement testing pretty well in my opinion.
Agreed. I prefer, though, to use BlockClosure>>assert, so usage becomes something like: [2 + 2 = 5] assert. I see that this is already implemented, based on Object>>assert: There are inconsistencies that bother me. * TestCase>>assert: in most Smalltalks accepts only a boolean. In Pharo, it accepts either a boolean or a block. This makes tests less portable. * TestCase>>assert:equals: (a very useful method) does not accept a block. Anyone used to giving blocks to #assert: would probably expect this method to accept a block. * Object assert: accepts a boolean or a block. I don't know of any standard for this. * BlockClosure>>assert does not take any arguments, so I feel it is very clean. Proposed changes: (based on earlier discussion plus personal opinion) TestCase>>assert: should only accept a boolean. This brings compatibility with other Smalltalks, and consistency with TestCase>>assert:equals:. Object>>assert: should be removed/deprecated in favor of BlockClosure>>assert. This removes confusion with TestCase>>assert:. Object>>assert:description: and Object>>assert:descriptionBlock: should be removed/deprecated in favor of (new) BlockClosure>>assertWithDescription:, which accepts either a block or a string. This provides convenient invariant and pre/post condition testing. Opinions? -Martin
Agreed. I prefer, though, to use BlockClosure>>assert, so usage becomes something like:
[2 + 2 = 5] assert.
I see that this is already implemented, based on Object>>assert:
I agree this is more concise, there is no reference to "self" to formulate the assertion. Having to use "self" in "self assert:" has more to do with an unnecessary convention than bringing a real value. In that case, disabling assertion has to be done by modifying BlockClosure>>assert.
There are inconsistencies that bother me.
* TestCase>>assert: in most Smalltalks accepts only a boolean. In Pharo, it accepts either a boolean or a block. This makes tests less portable.
* TestCase>>assert:equals: (a very useful method) does not accept a block. Anyone used to giving blocks to #assert: would probably expect this method to accept a block.
The method assert:equals: should accept a block in my opinion. TestCase>>assert:equals: may be rewritten as: assert: expectedAsBlockOrValue equals: actualAsBlockOrValue | v1 v2 | v1 := expectedAsBlockOrValue value. v2 := actualAsBlockOrValue value. ^ self assert: (v1 = v2) description: (self comparingStringBetween: v1 and: v2)
* Object assert: accepts a boolean or a block. I don't know of any standard for this.
No standard as far as I know
* BlockClosure>>assert does not take any arguments, so I feel it is very clean.
But you need to modify it to cancel runtime checks
Proposed changes: (based on earlier discussion plus personal opinion)
TestCase>>assert: should only accept a boolean. This brings compatibility with other Smalltalks, and consistency with TestCase>>assert:equals:.
assert:equals: could also be updated. Some test units in the image use [] as arguments to assert: and deny:. StringTest is one of them.
Object>>assert: should be removed/deprecated in favor of BlockClosure>>assert. This removes confusion with TestCase>>assert:.
Ideally, this is valuable. However, there is a number of tests that use Object>>assert: (and not only my code :-). ZipEncoderTree is an example
Object>>assert:description: and Object>>assert:descriptionBlock: should be removed/deprecated in favor of (new) BlockClosure>>assertWithDescription:, which accepts either a block or a string. This provides convenient invariant and pre/post condition testing.
#assertWithDescription: is useful yes. Alexandre -- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
There are inconsistencies that bother me.
* TestCase>>assert: in most Smalltalks accepts only a boolean. In Pharo, it accepts either a boolean or a block. This makes tests less portable.
+1
* TestCase>>assert:equals: (a very useful method) does not accept a block. Anyone used to giving blocks to #assert: would probably expect this method to accept a block.
+1 consistency is nice.
* Object assert: accepts a boolean or a block. I don't know of any standard for this.
me neither
* BlockClosure>>assert does not take any arguments, so I feel it is very clean.
+1
Proposed changes: (based on earlier discussion plus personal opinion)
TestCase>>assert: should only accept a boolean. This brings compatibility with other Smalltalks, and consistency with TestCase>>assert:equals:.
+ 1
Object>>assert: should be removed/deprecated in favor of BlockClosure>>assert. This removes confusion with TestCase>>assert:.
deprecation!
Object>>assert:description: and Object>>assert:descriptionBlock: should be removed/deprecated in favor of (new) BlockClosure>>assertWithDescription:, which accepts either a block or a string. This provides convenient invariant and pre/post condition testing.
Let us do that. Any taker? Stef
Opinions?
-Martin
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
On Fri, Oct 16, 2009 at 4:45 AM, Stéphane Ducasse <stephane.ducasse@inria.fr
wrote:
There are inconsistencies that bother me.
* TestCase>>assert: in most Smalltalks accepts only a boolean. In Pharo, it accepts either a boolean or a block. This makes tests less portable.
+1
* TestCase>>assert:equals: (a very useful method) does not accept a block. Anyone used to giving blocks to #assert: would probably expect this method to accept a block.
+1 consistency is nice.
* Object assert: accepts a boolean or a block. I don't know of any standard for this.
me neither
* BlockClosure>>assert does not take any arguments, so I feel it is very clean.
+1
Proposed changes: (based on earlier discussion plus personal opinion)
TestCase>>assert: should only accept a boolean. This brings compatibility with other Smalltalks, and consistency with TestCase>>assert:equals:.
+ 1
Object>>assert: should be removed/deprecated in favor of BlockClosure>>assert. This removes confusion with TestCase>>assert:.
deprecation!
Object>>assert:description: and Object>>assert:descriptionBlock: should be removed/deprecated in favor of (new) BlockClosure>>assertWithDescription:, which accepts either a block or a string. This provides convenient invariant and pre/post condition testing.
Let us do that. Any taker?
I don't have time right now for this, but at least I created the ticket: http://code.google.com/p/pharo/issues/detail?id=1329 Cheers, mariano
Stef
Opinions?
-Martin
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
The idea is that one day or later we will have to think about the benefit of pre and post condition. So assert: in object makes a lot of sense. Now indeed it would be good that all the tests use assert: without block and use should: for that case. Stef On Oct 15, 2009, at 3:55 AM, csrabak@bol.com.br wrote:
I don't either, but I find strange the complete hierarchy of classes of Pharo having a method assert: available. Perhaps I'm blindfolded and Pharo and Squeak have found a wider use for assertions?
Why not rename Object>>assert: to should:, so it avoids breaking polymorphism, and keep TestCase>>assert: reserved for a boolean argument to stay compatible with SUnit in other dialects? On the negative side, it might not be as intuitive using should: for pre/post-assertions, as well as inconvenient to remember the difference between assert: and should: in TestCases. Not big enough negatives to outweigh the benefits though, imo. Cheers, Henry Stéphane Ducasse skrev:
The idea is that one day or later we will have to think about the benefit of pre and post condition. So assert: in object makes a lot of sense.
Now indeed it would be good that all the tests use assert: without block and use should: for that case.
Stef On Oct 15, 2009, at 3:55 AM, csrabak@bol.com.br wrote:
I don't either, but I find strange the complete hierarchy of classes of Pharo having a method assert: available. Perhaps I'm blindfolded and Pharo and Squeak have found a wider use for assertions?
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Henrik Johansen wrote:
Why not rename Object>>assert: to should:, so it avoids breaking polymorphism, and keep TestCase>>assert: reserved for a boolean argument to stay compatible with SUnit in other dialects?
On the negative side, it might not be as intuitive using should: for pre/post-assertions, as well as inconvenient to remember the difference between assert: and should: in TestCases. Not big enough negatives to outweigh the benefits though, imo.
Henry, Sorry, I hadn't read this mail before making a proposal. I agree that renaming Object>>assert: to #should: would be an improvement. But I still think it's probably better to remove it altogether and send #assert to a block. It may just be me, but I've always felt that as a selector 'should' doesn't really communicate the intent as well as 'assert'. Regards, -Martin
Hi martin I agree should: is not that communicating. I would favor [] assert [] assertWithDescription: 'funky preconditions' Stef On Oct 15, 2009, at 8:35 PM, Martin McClure wrote:
Henrik Johansen wrote:
Why not rename Object>>assert: to should:, so it avoids breaking polymorphism, and keep TestCase>>assert: reserved for a boolean argument to stay compatible with SUnit in other dialects?
On the negative side, it might not be as intuitive using should: for pre/post-assertions, as well as inconvenient to remember the difference between assert: and should: in TestCases. Not big enough negatives to outweigh the benefits though, imo.
Henry,
Sorry, I hadn't read this mail before making a proposal.
I agree that renaming Object>>assert: to #should: would be an improvement. But I still think it's probably better to remove it altogether and send #assert to a block. It may just be me, but I've always felt that as a selector 'should' doesn't really communicate the intent as well as 'assert'.
Regards,
-Martin
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Em 15/10/2009 04:50, Stéphane Ducasse <stephane.ducasse@inria.fr> escreveu: I see. Eiffel ideas cross breeding Pharo Smalltalk!
The idea is that one day or later we will have to think about the benefit of pre and post condition. So assert: in object makes a lot of sense.
Now indeed it would be good that all the tests use assert: without block and use should: for that case.
Stef On Oct 15, 2009, at 3:55 AM, csrabak@bol.com.br wrote:
> I don't either, but I find strange the complete hierarchy of > classes of Pharo having a method assert: available. Perhaps > I'm blindfolded and Pharo and Squeak have found a wider use > for assertions?
I like the ability I have to generate big and interesting threads from a little question hahaha. On Thu, Oct 15, 2009 at 8:55 PM, <csrabak@bol.com.br> wrote:
Em 15/10/2009 04:50, Stéphane Ducasse <stephane.ducasse@inria.fr> escreveu:
I see. Eiffel ideas cross breeding Pharo Smalltalk!
The idea is that one day or later we will have to think about the benefit of pre and post condition. So assert: in object makes a lot of sense.
Now indeed it would be good that all the tests use assert: without block and use should: for that case.
Stef On Oct 15, 2009, at 3:55 AM, csrabak@bol.com.br wrote:
> I don't either, but I find strange the complete hierarchy of > classes of Pharo having a method assert: available. Perhaps > I'm blindfolded and Pharo and Squeak have found a wider use > for assertions?
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Yes and this is really important because pre and post are valuable for software engineering quality promotion. Stef On Oct 16, 2009, at 1:55 AM, csrabak@bol.com.br wrote:
Em 15/10/2009 04:50, Stéphane Ducasse <stephane.ducasse@inria.fr> escreveu:
I see. Eiffel ideas cross breeding Pharo Smalltalk!
The idea is that one day or later we will have to think about the benefit of pre and post condition. So assert: in object makes a lot of sense.
Now indeed it would be good that all the tests use assert: without block and use should: for that case.
Stef On Oct 15, 2009, at 3:55 AM, csrabak@bol.com.br wrote:
I don't either, but I find strange the complete hierarchy of classes of Pharo having a method assert: available. Perhaps I'm blindfolded and Pharo and Squeak have found a wider use for assertions?
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
However, would you really try to apply this kind of rule to the whole Smalltalk Kernel ? That would be interesting because these rules have a cost in - speed - readability of code - extensibility of code 1) Speed: every little method calls a little method, calls a little method ... At which level do you put the tests ? How many times is the same test applied thru the call chain ? 2) Readability: 3 lines of assertions for two lines of code is too much to my taste. Opinions may vary... 3) Extensibility of code: you'll have to care not to restrict future extensions too much. Pushed to the limits, this ressembles static typing (fortunately we shall use message isInteger rather than isKindOf: Integer). I think Smalltalk quality is based on a completly different plane Nicolas 2009/10/16 Stéphane Ducasse <stephane.ducasse@inria.fr>:
Yes and this is really important because pre and post are valuable for software engineering quality promotion.
Stef
On Oct 16, 2009, at 1:55 AM, csrabak@bol.com.br wrote:
Em 15/10/2009 04:50,  Stéphane Ducasse <stephane.ducasse@inria.fr> escreveu:
I see. Â Eiffel ideas cross breeding Pharo Smalltalk!
  The idea  is that one day or  later we will have  to think about   the benefit  of pre  and post condition.  So assert:  in object   makes a lot of sense.
  Now  indeed it  would be  good that  all the  tests  use assert:   without block and use should: for that case.
  Stef On Oct 15, 2009, at 3:55 AM, csrabak@bol.com.br wrote:
I don't either,  but I find strange the  complete hierarchy of classes of  Pharo having  a method assert:  available. Perhaps I'm blindfolded  and Pharo and  Squeak have found a  wider use for assertions?
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
However, would you really try to apply this kind of rule to the whole Smalltalk Kernel ? That would be interesting because these rules have a cost in - speed - readability of code - extensibility of code
1) Speed: every little method calls a little method, calls a little method ... At which level do you put the tests ? How many times is the same test applied thru the call chain ?
First preconditions in eiffel have different level of execution you can completely disable them. Once the new compiler is in pharo and the default compiler we could do really cool on the fly recompilation and have a large range of choices. Then we can use preconditions to generate tests or as one of my friend did in eiffel and java generate tests that you trash after and enhance the robustness of the preconditions. I read the PhD of benoit baudry and once you read the conclusions and the results it is clear that preconditions have really good properties. Now we have to be smart enough to understand how we can take advantage of them in our setup.
2) Readability: 3 lines of assertions for two lines of code is too much to my taste. Opinions may vary...
It is a question of balance. Not everything is black or white.
3) Extensibility of code: you'll have to care not to restrict future extensions too much. Pushed to the limits, this ressembles static typing (fortunately we shall use message isInteger rather than isKindOf: Integer).
Again it is a question of balance and usage. We should decouple the tool from its usage. I think that we should learn from it.
I think Smalltalk quality is based on a completly different plane
You mean not checkable documentation, absence of documentation, lack of static typing to document (because what would be good is to have a pluggable type system)
2009/10/16 Stéphane Ducasse <stephane.ducasse@inria.fr>:
I think Smalltalk quality is based on a completly different plane
First, my reference about quality is not Squeak, I rather mean st-80 from ParcPlace :) At least it used to have - more generous class and method comments - less bugs and obscure code (certainly because less code too !) - a certain homogeneity (less programmers ?) So were is the Smalltalk quality ? - the ability to test code as soon as written - the ability to write small and simple code, - the ability to write readable code, - the ability to extend code Are these essential properties in the quality standards used in static typing ?
You mean not checkable documentation, absence of documentation, lack of static typing to document (because what would be good is to have a pluggable type system)
I agree, lack of type can be seen as a weakness for documenting APIs. As a workaround, we use funny parameter names (anArrayOfStrings). Or we add a method comment (hem... at least we should). I agree, all these comments will become false when code is changed, and the quality will decrease... As false as an outdated assertion... but silent... Maybe it's worse ? Browsing senders, or inspecting the signature of message sent to, or inserting a halt is sometimes our solutions... I agree, this is not ideal. So yes, assertions as a public declaration of API could be good for documenting. And a good description of assertion failure can also provide informative feedback to the user (more than a Debugger ?) What I do not like is defensive assertions as a potential barrier to extendability, because they correspond to a static view of code, a snapshot of current state. Smalltalk state does and will change. The image is living, and class structure not written on stone. Rapidly changing code is definitely not accepted as a quality standard... In a rapidly changing image, assertions could be a supplementary drag against change... Suppose I have a method accepting a String parameter P: p. [p isString] assertWithDescription: 'method xxx only accept a String as parameter P'. Now maybe the method would have worked with a Text. I have been too restrictive: [p isCharacters] assertWithDescription: 'method xxx only accept characters'. Now someone introduce WideString, and my code only work with ByteString. [p isCharacters and: [p asString isByteString]] assertWithDescription: 'method xxx only accept byte characters'. Yes, but the method does not work with empty String, I add: [p notEmpty] assertWithDescription: 'method xxx only accept non empty strings'. Nor does it with some control characters: self assertPHasValidCharacters: p. Fortunately someone then correct the WideString case, now I can retract isByteString. Unfortunately, p will be stored in an inst. var. with many public interfaces... Each time, I have to change all the false assertions in all senders of the core method that are in the public API... And maybe some of these public APIs are driven by other public APIs (you meet this in Smalltalk, didn't you?) To avoid this I create a specific method assertPIsValid: p | sender | sender := thisContext sender homeContext selector. [p isCharacters] assertWithDescription: 'method ' , sender , ' only accept characters'. [p asString isByteString] assertWithDescription: 'method ' , sender , ' only accept byte characters'. [p notEmpty] assertWithDescription: 'method ' , sender , ' only accept non empty strings'. self assertPHasValidCharacters: p from: sender. But now, I can't see the assumption from within public API. I have to browse implementors of assertPIsValid:, so I loose the immediate documentation... And one day, a brilliant programmer decide a ReadStream on characters would also be a good parameter P, with a minor change in the core method... Arghh, I don't want to advance the stream yet and do all my static checks... In order to maximize extendability, can't we use extensible assertions like sending a message? If we end up with [p isAGoodParameterPForMyMessage] assert. then I don't buy it ;) Maybe you have some better ideas about optional types as a specification... Semi-automatic RoelTyper like helper tools? Nicolas
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
First, my reference about quality is not Squeak, I rather mean st-80 from ParcPlace :)
:)
At least it used to have - more generous class and method comments - less bugs and obscure code (certainly because less code too !) - a certain homogeneity (less programmers ?)
Yes!
So were is the Smalltalk quality ? - the ability to test code as soon as written - the ability to write small and simple code, - the ability to write readable code, - the ability to extend code Are these essential properties in the quality standards used in static typing ?
But contracts and pre and cons are not linked with static typing.
You mean not checkable documentation, absence of documentation, lack of static typing to document (because what would be good is to have a pluggable type system)
I agree, lack of type can be seen as a weakness for documenting APIs. As a workaround, we use funny parameter names (anArrayOfStrings). Or we add a method comment (hem... at least we should). I agree, all these comments will become false when code is changed, and the quality will decrease...
No this is not only that is that if you have precondition you localize the origin of bugs.
As false as an outdated assertion... but silent... Maybe it's worse ? Browsing senders, or inspecting the signature of message sent to, or inserting a halt is sometimes our solutions... I agree, this is not ideal.
So yes, assertions as a public declaration of API could be good for documenting.
I'm not sure that this is what I implied. For me pre and post are a nice way to specify the responsibility of the caller and the callee.
And a good description of assertion failure can also provide informative feedback to the user (more than a Debugger ?)
What I do not like is defensive assertions as a potential barrier to extendability, because they correspond to a static view of code, a snapshot of current state.
I agree. I would avoid to have self assert: [aParam isKindOf: Point]
Smalltalk state does and will change. The image is living, and class structure not written on stone. Rapidly changing code is definitely not accepted as a quality standard...
In a rapidly changing image, assertions could be a supplementary drag against change... Suppose I have a method accepting a String parameter P: p. [p isString] assertWithDescription: 'method xxx only accept a String as parameter P'. Now maybe the method would have worked with a Text. I have been too restrictive: [p isCharacters] assertWithDescription: 'method xxx only accept characters'. Now someone introduce WideString, and my code only work with ByteString. [p isCharacters and: [p asString isByteString]] assertWithDescription: 'method xxx only accept byte characters'. Yes, but the method does not work with empty String, I add: [p notEmpty] assertWithDescription: 'method xxx only accept non empty strings'.
I would prefer to have [p isStringable] string implements Stringable Text implements Stringable I think that this is not because we have a dynamically typed language that we should forget consistent/compatible types (expressed via an agreement on common protocol).
Maybe you have some better ideas about optional types as a specification... Semi-automatic RoelTyper like helper tools?
Do not confuse preconditions and type annotation. For me precondition is also about the object state before the method execution. So what we should do is learn what could be good. Stef
This is a facility... If you want to be portable, don't use it. Maybe (self should: aBlock) is portable if you really want a block... Nicolas 2009/10/14 Mariano Martinez Peck <marianopeck@gmail.com>:
Hi folks:During this week someone wanted to use SqueakDBX in Squeak 3.8 and at the same time another person (thanks Marcelo Cortez!!!) has ported it to Dolphin. And I found something weird in TestCase >> assert:
In Squeak 3.10Â TestCase >> assert: aBooleanOrBlock
Squeak 3.8, Dolphin and VAST (I don't know others) have:
TestCase >> assert: aBoolean
So...is there a reason of doing that? Is this expected?
cheers
mariano
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Early sunit i believe had self should: [1 = 2] vs self assert: 1 = 2. Perhaps as Alex says the api has moved... cheers, Mike
Em 14/10/2009 17:06, Mariano Martinez Peck <marianopeck@gmail.com> escreveu:
Hi folks:During this week someone wanted to use SqueakDBX in Squeak 3.8 and at the same time another person (thanks Marcelo Cortez!!!) has ported it to Dolphin. And I found something weird in TestCase >> assert:
In Squeak 3.10 TestCase >> assert: aBooleanOrBlock
Squeak 3.8, Dolphin and VAST (I don't know others) have:
TestCase >> assert: aBoolean
So...is there a reason of doing that? Is this expected?
FWIW in VW it's also TestCase>>assert: aBoolean, and there is not an Object>>assert: method there.
participants (8)
-
Alexandre Bergel -
csrabak@bol.com.br -
Henrik Johansen -
Mariano Martinez Peck -
Martin McClure -
Michael Roberts -
Nicolas Cellier -
Stéphane Ducasse