Hi,
I'm wondering why the following code does not compile and answers 'Nothing more expected': test:=OrderedCollection with: 'first'. test add: 'second'; size negated It seems we can't send another message to size ! Can somebody explain this to me please ? -- Damien |
On Thu, 17 Aug 2006 11:12:36 +0200, Damien Cassou wrote:
> Hi, > > I'm wondering why the following code does not compile and answers > 'Nothing more expected': > > test:=OrderedCollection with: 'first'. > test > add: 'second'; > size negated > (test add: 'second'; size) negated is what you can do with the result of your cascaded messages. > It seems we can't send another message to size ! Sure, you can. But when you cascade messages, you have two receivers: the cascade receiver and the cascade result. Think that the compiler wants you to tell which one you mean. > Can somebody explain this to me please ? HTH. /Klaus |
Klaus D. Witzel wrote:
> On Thu, 17 Aug 2006 11:12:36 +0200, Damien Cassou wrote: > >> test:=OrderedCollection with: 'first'. >> test >> add: 'second'; >> size negated >> > > (test add: 'second'; size) negated is what you can do with the result of > your cascaded messages. Maybe my example was not clear enough: test:= MyObjectModel test getAllChanges; storageStrategy storeNow; readyToContinue I think it is clear that #storeNow is sent to the result of 'test storageStrategy'. And #readyToContinue should still be sent to 'test' so brackets are not possible in this example. |
Damien Cassou a écrit :
> Klaus D. Witzel wrote: >> On Thu, 17 Aug 2006 11:12:36 +0200, Damien Cassou wrote: >> >>> test:=OrderedCollection with: 'first'. >>> test >>> add: 'second'; >>> size negated >>> >> >> (test add: 'second'; size) negated is what you can do with the result >> of your cascaded messages. > > > Maybe my example was not clear enough: > > test:= MyObjectModel > test > getAllChanges; > storageStrategy storeNow; > readyToContinue > > I think it is clear that #storeNow is sent to the result of 'test > storageStrategy'. And #readyToContinue should still be sent to 'test' so > brackets are not possible in this example. I think storeNow is sent to storageStrategy, then the returned object from this message call, which should be a message symbol, is sent to test. May be it should be written test:= MyObjectModel (test getAllChanges; storageStrategy) storeNow. test readyToContinue Hilaire |
Hilaire Fernandes wrote:
> Damien Cassou a écrit : >> Klaus D. Witzel wrote: >>> On Thu, 17 Aug 2006 11:12:36 +0200, Damien Cassou wrote: >>> >>>> test:=OrderedCollection with: 'first'. >>>> test >>>> add: 'second'; >>>> size negated >>>> >>> (test add: 'second'; size) negated is what you can do with the result >>> of your cascaded messages. >> >> Maybe my example was not clear enough: >> >> test:= MyObjectModel >> test >> getAllChanges; >> storageStrategy storeNow; >> readyToContinue >> >> I think it is clear that #storeNow is sent to the result of 'test >> storageStrategy'. And #readyToContinue should still be sent to 'test' so >> brackets are not possible in this example. > > > I think storeNow is sent to storageStrategy, then the returned object > from this message call, which should be a message symbol, is sent to test. > May be it should be written > > test:= MyObjectModel > (test > getAllChanges; > storageStrategy) storeNow. > test readyToContinue I know how to make it work in fact. What I don't understand is why the smalltalk doesn't allow this kind of construction. |
In reply to this post by Damien Cassou-3
On Thu, 17 Aug 2006 12:07:54 +0200, Damien Cassou wrote:
> Klaus D. Witzel wrote: >> On Thu, 17 Aug 2006 11:12:36 +0200, Damien Cassou wrote: >> >>> test:=OrderedCollection with: 'first'. >>> test >>> add: 'second'; >>> size negated >>> >> (test add: 'second'; size) negated is what you can do with the result >> of your cascaded messages. > > Maybe my example was not clear enough: No it was crystal clear. > test:= MyObjectModel > test > getAllChanges; > storageStrategy storeNow; > readyToContinue test getAllChanges; ifNotNil: [test storageStrategy storeNow]; readyToContinue does not compile (lack of support from parser/compiler) but | test | test := nil. test yourself; ifNotNilDo: [:ignored | test yourself isNil]; yourself does. > I think it is clear that #storeNow is sent to the result of 'test > storageStrategy'. And #readyToContinue should still be sent to 'test' See above, it is. > so brackets are not possible in this example. Brackets are but parentheses aren't, in your 2nd example. /Klaus |
In reply to this post by Damien Cassou-3
> >> test:= MyObjectModel
> >> test > >> getAllChanges; > >> storageStrategy storeNow; > >> readyToContinue > >> > I know how to make it work in fact. What I don't understand is why the > smalltalk doesn't allow this kind of construction. Because it is ambiguous. How should the compiler know if it should send #readyToContinue to 'test' or the result of 'test storageStrategy'? Lukas -- Lukas Renggli http://www.lukas-renggli.ch |
In reply to this post by Klaus D. Witzel
Instead of #ifNotNilDo: you can use #in: but there are no examples in the
image for using #in: for cascading. /Klaus On Thu, 17 Aug 2006 12:34:26 +0200, Klaus wrote: > On Thu, 17 Aug 2006 12:07:54 +0200, Damien Cassou wrote: >> Klaus D. Witzel wrote: >>> On Thu, 17 Aug 2006 11:12:36 +0200, Damien Cassou wrote: >>> >>>> test:=OrderedCollection with: 'first'. >>>> test >>>> add: 'second'; >>>> size negated >>>> >>> (test add: 'second'; size) negated is what you can do with the result >>> of your cascaded messages. >> >> Maybe my example was not clear enough: > > No it was crystal clear. > >> test:= MyObjectModel >> test >> getAllChanges; >> storageStrategy storeNow; >> readyToContinue > > test > getAllChanges; > ifNotNil: [test storageStrategy storeNow]; > readyToContinue > > does not compile (lack of support from parser/compiler) but > > | test | > test := nil. > test > yourself; > ifNotNilDo: [:ignored | test yourself isNil]; > yourself > > does. > >> I think it is clear that #storeNow is sent to the result of 'test >> storageStrategy'. And #readyToContinue should still be sent to 'test' > > See above, it is. > >> so brackets are not possible in this example. > > Brackets are but parentheses aren't, in your 2nd example. > > /Klaus > > > |
In reply to this post by Lukas Renggli
On Thu, 17 Aug 2006 12:43:54 +0200, Lukas Renggli wrote:
>> >> test:= MyObjectModel >> >> test >> >> getAllChanges; >> >> storageStrategy storeNow; >> >> readyToContinue >> >> >> I know how to make it work in fact. What I don't understand is why the >> smalltalk doesn't allow this kind of construction. > > Because it is ambiguous. How should the compiler know if it should > send #readyToContinue to 'test' or the result of 'test > storageStrategy'? It would be interesting to find a language construct which does support Damien's expression. Not that I want everybody to write as much cascades as possible but, I want to be able to do so. /Klaus > Lukas > > |
> > Because it is ambiguous. How should the compiler know if it should
> > send #readyToContinue to 'test' or the result of 'test > > storageStrategy'? > > It would be interesting to find a language construct which does support > Damien's expression. Not that I want everybody to write as much cascades > as possible but, I want to be able to do so. I think #in: is a good solution for that particular problem. I use it sometimes with Seaside and script.aculo.us, both frameworks make extensive use of cascades to build and configure html-tags and JavaScript objects. An example: The CSS class 'red' is only added, if a specific condition is met. html div id: 'foo'; class: 'border'; in: [ :tag | condition ifTrue: [ tag class: 'red' ] ]; with: 'contents' However, as the code doesn't make me feel cosy I added a helper method to the receiver of the cascade. After the refactoring (yeah, a refactoring, not an change ... I finally got it, yeah, yeah, ...) it looks like: html div idd: 'foo'; class: 'border'; class: 'red' if: condition; with: 'contents' Such a refactoring can be always applied and is probably better practice than to start using blocks ... Lukas -- Lukas Renggli http://www.lukas-renggli.ch |
This is one of the best examples of a) lack of *language* support; b)
quick&dirty solution using blocks; c) refactoring; sequence that I've ever seen :) Thank you for posting this one, Damien & Lukas. /Klaus On Thu, 17 Aug 2006 13:14:35 +0200, Lukas Renggli wrote: >> > Because it is ambiguous. How should the compiler know if it should >> > send #readyToContinue to 'test' or the result of 'test >> > storageStrategy'? >> >> It would be interesting to find a language construct which does support >> Damien's expression. Not that I want everybody to write as much cascades >> as possible but, I want to be able to do so. > > I think #in: is a good solution for that particular problem. I use it > sometimes with Seaside and script.aculo.us, both frameworks make > extensive use of cascades to build and configure html-tags and > JavaScript objects. > > An example: The CSS class 'red' is only added, if a specific condition > is met. > > html div > id: 'foo'; > class: 'border'; > in: [ :tag | condition ifTrue: [ tag class: 'red' ] ]; > with: 'contents' > > However, as the code doesn't make me feel cosy I added a helper method > to the receiver of the cascade. After the refactoring (yeah, a > refactoring, not an change ... I finally got it, yeah, yeah, ...) it > looks like: > > html div > idd: 'foo'; > class: 'border'; > class: 'red' if: condition; > with: 'contents' > > Such a refactoring can be always applied and is probably better > practice than to start using blocks ... > > Lukas > |
In reply to this post by Klaus D. Witzel
Klaus D. Witzel wrote:
> On Thu, 17 Aug 2006 12:07:54 +0200, Damien Cassou wrote: >> Klaus D. Witzel wrote: >>> On Thu, 17 Aug 2006 11:12:36 +0200, Damien Cassou wrote: >>> >>>> test:=OrderedCollection with: 'first'. >>>> test >>>> add: 'second'; >>>> size negated >>>> >>> (test add: 'second'; size) negated is what you can do with the >>> result of your cascaded messages. >> >> Maybe my example was not clear enough: > > No it was crystal clear. > >> test:= MyObjectModel >> test >> getAllChanges; >> storageStrategy storeNow; >> readyToContinue > > test > getAllChanges; > ifNotNil: [test storageStrategy storeNow]; > readyToContinue > > does not compile (lack of support from parser/compiler) but > > | test | > test := nil. > test > yourself; > ifNotNilDo: [:ignored | test yourself isNil]; > yourself > > does. > >> I think it is clear that #storeNow is sent to the result of 'test >> storageStrategy'. And #readyToContinue should still be sent to 'test' > > See above, it is. > >> so brackets are not possible in this example. > > Brackets are but parentheses aren't, in your 2nd example. Stop confusing me ;-) Just before writing the mail, I had a look at my dictionary because I've never managed to know how those following symbols are called in english: () [] {} My dictionary told me: () brackets or parenthesis (for US) [] square brackets {} braces or curly brackets When I said: 'so brackets are not possible in this example', I meant parenthesis :-) Two minutes ago, I verified in wikipedia and it seems that 'Bracket' is the superclass of Parenthesis. Which one is correct :-) ? |
On Thu, 17 Aug 2006 15:54:43 +0200, Damien Cassou wrote:
> Klaus wrote: >>> so brackets are not possible in this example. >> Brackets are but parentheses aren't, in your 2nd example. > > Stop confusing me ;-) Just before writing the mail, I had a look at my > dictionary because I've never managed to know how those following > symbols are called in english: > > () [] {} > > My dictionary told me: > > () brackets or parenthesis (for US) > [] square brackets > {} braces or curly brackets > > When I said: 'so brackets are not possible in this example', I meant > parenthesis :-) > > Two minutes ago, I verified in wikipedia and it seems that 'Bracket' is > the superclass of Parenthesis. > > Which one is correct :-) ? The comments in Smalltalk code are correct. But if in doubt, the Blue Book ultimatively is correct: you will find parentheses and brackets explained in chapter #2, Expression Syntax. This way all Smalltalkers can talk about the same things using the same names, even if none of them has ever seen *your* dictionary and even if the wikipedia server is down ;-) /Klaus |
In reply to this post by Lukas Renggli
Cascading allows a sequence of message sends to be 'stacked up' for
sending to the same receiver. If you look at the EBNF spec (as shown in the Blue Book) for cascading you will see that it allows for receiver message send; message send; .... A message send is a *single* message send to receiver and so the final 'size negated' in the original example given clearly doesn't count. I suspect there is a tendency to allow some C-think to creep in and treat the semi-colon as some sort of statement separator. Note that you *can* do things like |test| test:=OrderedCollection with: 'first'. test add: 'second', 'third'; size because the 'second','third' is not a message send to 'test' but a separate clause that gets evaluated earlier. tim -- tim Rowledge; [hidden email]; http://www.rowledge.org/tim Java: the best argument for Smalltalk since C++ |
In reply to this post by Damien Cassou-3
Hi tim,
It has nothing to deal with C, but rather with streaming... Streaming has a natural correspondance with cascading messages. But in situations when you just want to make code a little bit complex, you are forced to insert variables and make code less readable than would be a simple cascade... That's the only reason. Lukas provided a brilliant illustrating example. Nicolas Le Jeudi 17 Août 2006 18:49, tim Rowledge a écrit : > Cascading allows a sequence of message sends to be 'stacked up' for > sending to the same receiver. If you look at the EBNF spec (as shown > in the Blue Book) for cascading you will see that it allows for > receiver > message send; > message send; > .... > A message send is a *single* message send to receiver and so the > final 'size negated' in the original example given clearly doesn't > count. I suspect there is a tendency to allow some C-think to creep > in and treat the semi-colon as some sort of statement separator. > Note that you *can* do things like > > |test| > > test:=OrderedCollection with: 'first'. > test > add: 'second', 'third'; > size > because the 'second','third' is not a message send to 'test' but a > separate clause that gets evaluated earlier. > > tim > -- > tim Rowledge; [hidden email]; http://www.rowledge.org/tim > Java: the best argument for Smalltalk since C++ ________________________________________________________________________ iFRANCE, exprimez-vous ! http://web.ifrance.com |
In reply to this post by Lukas Renggli
Lukas Renggli wrote:
>> >> test:= MyObjectModel >> >> test >> >> getAllChanges; >> >> storageStrategy storeNow; >> >> readyToContinue >> >> >> I know how to make it work in fact. What I don't understand is why the >> smalltalk doesn't allow this kind of construction. > > Because it is ambiguous. How should the compiler know if it should > send #readyToContinue to 'test' or the result of 'test > storageStrategy'? You mean something like: test:= MyObjectModel test getAllChanges; storageStrategy storeNow; readyToContinue Yes, you are perfectly right. Thank you |
In reply to this post by Lukas Renggli
> html div
> id: 'foo'; > class: 'border'; > in: [ :tag | condition ifTrue: [ tag class: 'red' ] ]; > with: 'contents' > That's a nice trick Lucas, now I have to go rewrite a bunch of code, damn! |
In reply to this post by Lukas Renggli
yes much nicer to read
On 17 août 06, at 13:14, Lukas Renggli wrote: > html div > idd: 'foo'; > class: 'border'; > class: 'red' if: condition; > with: 'contents' > > Such a refactoring can be always applied and is probably better > practice than to start using blocks ... |
Free forum by Nabble | Edit this page |