2011/10/17 Levente Uzonyi <[email protected]> > On Sun, 16 Oct 2011, Stéphane Ducasse wrote: > > >> On Oct 16, 2011, at 10:33 PM, Nicolas Cellier wrote: >> >> Ah, I see, this sound appealing. >>> But I would object this: (I'm speaking of do:, not only to:do:) >>> 1) what the last value mean for unordered collections? >>> 2) for a SequenceableCollection, the behavior is already >>> (someCollection inject: nil into: [:void :each | aBlock value: each]) >>> 3) returning the last value in all implementors of #do: would cost >>> complexification of code and possibly slow down (non clean blocks) >>> >>> Is it really useful? >>> >> >> Not really I do not like the idea to rely on it. >> but in that case the code you be explicit >> >> #undefined/nil >> should be the last expression of the block. >> >> My point was: the semantics of a block is to return the last expression >> and we should be consistent with that. >> > > The block returns the last expression, but in this case a method returns > the value. Here's an example: > > (1 to: 10) collect: [ :each | each squared ]. > > You don't expect to get 100 as the result, do you? :) >
Just to hammer home the message. The below, which won't be inlined since the block argument is in a variable, | b | b := [:i| nil]. 1 to: 10 do: b of course answers 1, since Number methods for intervals to: stop do: aBlock "Normally compiled in-line, and therefore not overridable. Evaluate aBlock for each element of the interval (self to: stop by: 1)." | nextValue | nextValue := self. [nextValue <= stop] whileTrue: [aBlock value: nextValue. nextValue := nextValue + 1] which ends with an implicit ^self. > > Levente > > > >> Stef >> >> >>> Nicolas >>> >>> 2011/10/16 Stéphane Ducasse <[email protected]>: >>> >>>> for me the last expression of the block. >>>> >>>> Stef >>>> >>>>> Which return value would be useful? >>>>>>> >>>>>> >>>>>> That's not the right question. IMO the compiler should answer the >>>>>> same >>>>>> result as the non-inlined one when the return value is asked for. >>>>>> Arguably >>>>>> the non-inline version needs to be commented to specify that it >>>>>> returns the >>>>>> value it does (in this case self), and that the compiler's optimiser >>>>>> reflects this. >>>>>> >>>>>> >>>>> Agree, but I was wondering what useful object this common answer could >>>>> be? >>>>> >>>>> >>>>>>> Nicolas >>>>>>> >>>>>>> 2011/10/16 Stéphane Ducasse <[email protected]>: >>>>>>> >>>>>>>> A friend of mine ask me the following >>>>>>>> >>>>>>>> |result| >>>>>>>> result := String new. >>>>>>>> 1 to: 10 do: [:n | result := result, n printString, ' ']. >>>>>>>> I am trying to do or print this code. It prints 'nil' instead of a >>>>>>>> collection. Its an example from PBE book. >>>>>>>> do you know the reason? >>>>>>>> although this one's working: >>>>>>>> result := String new. >>>>>>>> (1 to: 10) do: [:n | result := result, n printString, ' ']. >>>>>>>> >>>>>>>> I checked the implementation >>>>>>>> Interval>>do: aBlock >>>>>>>> "Evaluate aBlock for each value of the interval. >>>>>>>> Implementation note: instead of repeatedly incrementing the value >>>>>>>> aValue := aValue + step. >>>>>>>> until stop is reached, >>>>>>>> We prefer to recompute value from start >>>>>>>> aValue := start + (index * step). >>>>>>>> This is better for floating points accuracy, while not degrading >>>>>>>> Integer >>>>>>>> and >>>>>>>> Fraction speed too much. >>>>>>>> Moreover, this is consistent with methods #at: and #size" >>>>>>>> | aValue index size | >>>>>>>> index := 0. >>>>>>>> size := self size. >>>>>>>> [index < size] >>>>>>>> whileTrue: [aValue := start + (index * step). >>>>>>>> index := index + 1. >>>>>>>> aBlock value: aValue] >>>>>>>> >>>>>>>> Number>>to: stop do: aBlock >>>>>>>> "Normally compiled in-line, and therefore not overridable. >>>>>>>> Evaluate aBlock for each element of the interval (self to: stop by: >>>>>>>> 1)." >>>>>>>> | nextValue | >>>>>>>> nextValue := self. >>>>>>>> [nextValue <= stop] >>>>>>>> whileTrue: >>>>>>>> [aBlock value: nextValue. >>>>>>>> nextValue := nextValue + 1] >>>>>>>> >>>>>>>> any further idea than := value is different from value: >>>>>>>> Stef >>>>>>>> >>>>>>> >>>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> best, >>>>>> Eliot >>>>>> >>>>>> >>>>> >>>> >>>> >>>> >>> >> >> -- best, Eliot
