On Sun, Oct 16, 2011 at 10:09 AM, Nicolas Cellier < nicolas.cellier.aka.nice@gmail.com> wrote:
Well, the inlined to:do: doesn't behave the same as non inlined one:
|result| result := String new. 1 to: 10 do: [:n | result := result, n printString, ' '] yourself.
--> 1
The inlined byte code is explicitely returning nil (at byte 60)
(Compiler new compileNoPattern: '|result| result := String new. 1 to: 10 do: [:n | result := result, n printString, '' '']' in: Object context: nil notifying: nil ifFail: nil) generateWithTempNames.
37 <40> pushLit: String 38 <CC> send: new 39 <68> popIntoTemp: 0 40 <76> pushConstant: 1 41 <69> popIntoTemp: 1 42 <11> pushTemp: 1 43 <24> pushConstant: 10 44 <B4> send: <= 45 <AC 0D> jumpFalse: 60 47 <10> pushTemp: 0 48 <11> pushTemp: 1 49 <D2> send: printString 50 <E1> send: , 51 <23> pushConstant: ' ' 52 <E1> send: , 53 <68> popIntoTemp: 0 54 <11> pushTemp: 1 55 <76> pushConstant: 1 56 <B0> send: + 57 <69> popIntoTemp: 1 58 <A3 EE> jumpTo: 42 60 <73> pushConstant: nil 61 <7C> returnTop
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.
Nicolas
2011/10/16 Stéphane Ducasse <stephane.ducasse@inria.fr>:
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