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 <[hidden email]>: > 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, [hidden email] wrote: > >> Em 15/10/2009 04:50, Stéphane Ducasse <[hidden email]> >> 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, [hidden email] 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 >> [hidden email] >> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project > > > _______________________________________________ > Pharo-project mailing list > [hidden email] > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project > _______________________________________________ Pharo-project mailing list [hidden email] 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) _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
In reply to this post by Stéphane Ducasse
On Fri, Oct 16, 2009 at 4:45 AM, Stéphane Ducasse <[hidden email]> wrote:
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 _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
In reply to this post by Stéphane Ducasse
2009/10/16 Stéphane Ducasse <[hidden email]>:
> >> 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 > [hidden email] > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project > _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
In reply to this post by Mariano Martinez Peck
Nicolas, many very good points.
Just to add food for thought... double dispatching is a technique that has the benefit of avoiding isXXXX messages completely allowing for maximum flexibility and if the message isn't understood, immediate feedback that the programmer has done something wrong (which can be fixed by implementing the appropriate dispatch method) ... better than an assertion failures perhaps... Of course, double dispatching is not without it's drawbacks. I prefer double dispatching to implementing isXXX messages, but then I'd like to eliminate Booleans, too:) Dale ----- "Nicolas Cellier" <[hidden email]> wrote: | 2009/10/16 Stéphane Ducasse <[hidden email]>: | > | >> 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 | > [hidden email] | > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project | > | | _______________________________________________ | Pharo-project mailing list | [hidden email] | http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
Hehe, yes, once I implemented a matlab like generalized access:
m(1) = 3.14; % single element m(1:5) = [2 3 9 7 1]; % a contiguous subspace m([1 2 5]) = -m([1 2 5]); % an arbitrary subspace m(:) = m(end:-1:1); % a whole subspace (colon = column matrix) m( m>2 ) = m( m> 2 ) - 2; % a mask of booleans m( m<0 ) = 0; % variant: fill a subspace with an element m( m>5 ) = []; % a remove operation To keep it extensible and avoid static type checks, i ended up with triple dispatching... Not the code I'm the most proud of. I must admit a static-type compiler can handle such situations better... Maybe some declarative rules rather than procedural would also help... Nicolas 2009/10/20 Dale Henrichs <[hidden email]>: > Nicolas, many very good points. > > Just to add food for thought... double dispatching is a technique that has the benefit of avoiding isXXXX messages completely allowing for maximum flexibility and if the message isn't understood, immediate feedback that the programmer has done something wrong (which can be fixed by implementing the appropriate dispatch method) ... better than an assertion failures perhaps... > > Of course, double dispatching is not without it's drawbacks. I prefer double dispatching to implementing isXXX messages, but then I'd like to eliminate Booleans, too:) > > Dale > ----- "Nicolas Cellier" <[hidden email]> wrote: > > | 2009/10/16 Stéphane Ducasse <[hidden email]>: > | > > | >> 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 > | > [hidden email] > | > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project > | > > | > | _______________________________________________ > | Pharo-project mailing list > | [hidden email] > | http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project > > _______________________________________________ > Pharo-project mailing list > [hidden email] > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
In reply to this post by Nicolas Cellier
> 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 _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
Free forum by Nabble | Edit this page |