[Pharo-project] Fwd: trying to understand loops in pharo
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
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? 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
I usually run a little on the cowardly side and try to avoid depending on most-recently-evaluated behavior, because it is easy to break it in subsequent revision. However, I *think* that the value of the most-recently-evaluated expression is what one expects in situations like this. #inject:into: is where I typically encounter it. HTH, Bill ________________________________________ From: pharo-project-bounces@lists.gforge.inria.fr [pharo-project-bounces@lists.gforge.inria.fr] On Behalf Of Nicolas Cellier [nicolas.cellier.aka.nice@gmail.com] Sent: Sunday, October 16, 2011 1:09 PM To: Pharo-project@lists.gforge.inria.fr Subject: Re: [Pharo-project] Fwd: trying to understand loops in pharo 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? 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
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
2011/10/16 Eliot Miranda <eliot.miranda@gmail.com>:
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.
Agree, but I was wondering what useful object this common answer could be?
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
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 <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
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? Nicolas 2011/10/16 Stéphane Ducasse <stephane.ducasse@inria.fr>:
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 <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
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. Stef
Nicolas
2011/10/16 Stéphane Ducasse <stephane.ducasse@inria.fr>:
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 <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
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? :) Levente
Stef
Nicolas
2011/10/16 Stéphane Ducasse <stephane.ducasse@inria.fr>:
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 <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
2011/10/17 Levente Uzonyi <leves@elte.hu>
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 <stephane.ducasse@inria.fr>:
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 <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
-- best, Eliot
Just to hammer home the message. The below, which won't be inlined since the block argument is in a variable,
Elliot what is hammer home? To get in my skull? I should reread the thread without my flu and it will go better :)
| 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.
I should rereade the code thinkking about that hidden self it did not occur to me that I should think about it. Stef
On Mon, Oct 17, 2011 at 10:40 PM, Stéphane Ducasse < stephane.ducasse@inria.fr> wrote:
Just to hammer home the message. The below, which won't be inlined since the block argument is in a variable,
Elliot what is hammer home?
http://idioms.thefreedictionary.com/hammer+home
To get in my skull?
I should reread the thread without my flu and it will go better :)
| 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.
I should rereade the code thinkking about that hidden self it did not occur to me that I should think about it.
Stef
-- Mariano http://marianopeck.wordpress.com
On Oct 17, 2011, at 1:17 PM, Levente Uzonyi wrote:
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? :)
indeed :) I will have to reread the problem my friend got. Now my brain is glued with a little flu and excel salaries wonderful planning. Stef
participants (6)
-
Eliot Miranda -
Levente Uzonyi -
Mariano Martinez Peck -
Nicolas Cellier -
Schwab,Wilhelm K -
Stéphane Ducasse