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