Pharo-dev
By thread
pharo-dev@lists.pharo.org
By month
Messages by month
- ----- 2026 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
December 2015
- 990 messages
Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:
by Tudor Girba
Hi,
> On Dec 20, 2015, at 3:07 PM, Sven Van Caekenberghe <sven(a)stfx.eu> wrote:
>
>
>> On 20 Dec 2015, at 14:57, Tudor Girba <tudor(a)tudorgirba.com> wrote:
>>
>> Hi,
>>
>> Itâs clear that choices we would make would not be the same :). So, letâs drop past discussions and stay with the current situation. Do you agree with the observation that in the proposal of Max #sum and #sum: would not share the same meaning? If yes, do you agree that it would be misleading from the outside?
>
> The overal meaning is the same, IMO, summing a number of things (most often numbers) using #+. The processing block just adds functionality.
>
> The behaviour in the case of an empty collection is different yes. I want 0, why, because of https://en.wikipedia.org/wiki/Empty_sum
>
> This is about optimisation for the common case.
Fair enough. But, then why are you not equally picking on the fact that #sum: throws an error? :)
We are really overusing a term for something we should not and I think in the process we are getting to a tradeoff that does not lead to simplicity. From my point of view this discussion is similar to having Object>>#name. It kind of makes common sense to ask an object for its name, only that in a few situations it is actually painful to have it there :)
> VW had no #sum, I think because of all the points raised in this discussion (you can't always expect numbers and it is not clear what to do with empty collections).
I would not guide our decisions based on what VW did or did not do (I could not resist :)).
> Check out the senders of #sum and #sum: in a 50 image.
Sure, but we are supposed to create a language that is used by others. In the base image, there is no problem with Object>>#name either, but it is still not a good thing :)
So, why not remove #sum altogether then?
Cheers,
Doru
>> I would be fine with either answer. I would just want to understand.
>>
>> Cheers,
>> Doru
>>
>>
>>> On Dec 20, 2015, at 2:43 PM, Sven Van Caekenberghe <sven(a)stfx.eu> wrote:
>>>
>>> Doru,
>>>
>>> For me this whole discussion started because you (the standpoint that you take) hijacked the best selector (#sum) for a use case that is much less common than adding a collection of numbers which should give 0 when empty (you hijack it by not wanting to return 0, which I totally understand, but doing so you redefine the meaning/semantics).
>>>
>>> Max's point is to make everything more consistent and remove some API. I support that too.
>>>
>>> Now, I like Max's proposal.
>>>
>>> But, you know, my conclusion when the thread ended was that it might be better to throw all these selectors away, since #inject:into: covers most use cases at least as well and at least as clear.
>>>
>>> Sven
>>>
>>>> On 20 Dec 2015, at 14:10, Tudor Girba <tudor(a)tudorgirba.com> wrote:
>>>>
>>>> Hi,
>>>>
>>>> Could we not have sum, but sumNumbers instead? So, we would end up with:
>>>>
>>>> sum:ifEmpty:
>>>> sum: (with error)
>>>> sumNumbers (without error)
>>>>
>>>> From the outside, #sum: looks like it should parameterize #sum, but the implementation is actually different. So, given that in this implementation #sum is not a special case of #sum: the two should be named differently to reflect that difference. Hence my proposal is to keep #sumNumbers instead of #sum.
>>>>
>>>> Cheers,
>>>> Doru
>>>>
>>>>
>>>>> On Dec 20, 2015, at 1:47 PM, Max Leske <maxleske(a)gmail.com> wrote:
>>>>>
>>>>>>
>>>>>> On 20 Dec 2015, at 13:43, Gabriel Cotelli <g.cotelli(a)gmail.com> wrote:
>>>>>>
>>>>>> Max,
>>>>>>
>>>>>> sum: aBlock ifEmpty: emptyBlock needs to obtain the sample evaluating the block.
>>>>>>
>>>>>> sum: aBlock ifEmpty: emptyBlock
>>>>>> | sum sample |
>>>>>> self isEmpty ifTrue: [ ^ emptyBlock value ].
>>>>>> sample := aBlock value: self anyOne.
>>>>>> sum := self
>>>>>> inject: sample
>>>>>> into: [ :accum :each | accum + (aBlock value: each) ].
>>>>>> ^ sum - sample
>>>>>
>>>>>
>>>>> Thanks! Missed that.
>>>>>
>>>>>>
>>>>>> On Sun, Dec 20, 2015 at 8:59 AM, Max Leske <maxleske(a)gmail.com> wrote:
>>>>>> I would like to wrap up this discussion.
>>>>>>
>>>>>>
>>>>>>> On 05 Dec 2015, at 18:14, stepharo <stepharo(a)free.fr> wrote:
>>>>>>>
>>>>>>> So what is the conclusion?
>>>>>>> I like the idea of Esteban M to have iterator because it moves some behavior out of core classes.
>>>>>>>
>>>>>>> [[[
>>>>>>>
>>>>>>> aCollection arithmetic sum: [...] or.... aCollection
>>>>>>> arithmetic avg.
>>>>>>>
>>>>>>> ]]]
>>>>>>>
>>>>>>
>>>>>> While I think that iterators are an intriguing idea I also believe that they are beyond the scope of this issue. If anybody wants to follow up on iterators (or unit types for that matter) please start a new thread / issue.
>>>>>>
>>>>>>
>>>>>> I propose to use Svenâs version for #sum:ifEmpty:. The result would be these three methods:
>>>>>>
>>>>>> sum
>>>>>> ^ self
>>>>>> sum: [ :each | each ]
>>>>>> ifEmpty: [ 0 ]
>>>>>>
>>>>>> sum: aBlock
>>>>>> ^ self
>>>>>> sum: aBlock
>>>>>> ifEmpty: [ self errorEmptyCollection ]
>>>>>>
>>>>>> sum: aBlock ifEmpty: emptyBlock
>>>>>> | sum sample |
>>>>>> self isEmpty ifTrue: [ ^ emptyBlock value ].
>>>>>> sample := self anyOne.
>>>>>> sum := self
>>>>>> inject: sample
>>>>>> into: [ :accum :each | accum + (aBlock value: each) ].
>>>>>> ^ sum - sample
>>>>>>
>>>>>>
>>>>>> Iâve attached a couple of benchmark results below. To me they show that
>>>>>> 1. the new implementation is maybe a tiny bit slower but insignificantly so (if youâre going for performance youâll probably write your own optimised version anyway)
>>>>>> 2. there is no need to duplicate the code (like #sum and #sum: currently do). Itâs perfectly fine to delegate to #sum:ifEmpty:
>>>>>>
>>>>>>
>>>>>>
>>>>>> In addition to the above changes I would like to remove #detectSum: (-> #sum:) and #sumNumbers (-> #sum).
>>>>>>
>>>>>>
>>>>>> Note that once we agree on changing this API, we will need to also change #detectMin:, #detectMax:, #min, #max as well as all overrides (e.g. RunArray, Interval) of these and of #sum et. al. to stay consistent. The changes would of course be in line with this change, such that every operation has a unary selector with a sensible default, one that takes a block and throws an error for empty collections and a third that takes a block for the iteration and one for the empty case.
>>>>>>
>>>>>>
>>>>>> Please cast your vote for these changes:
>>>>>>
>>>>>> 1. Do you agree to changing #sum and #sum: in the suggested way?
>>>>>>
>>>>>> 2. Do you agree to the removal of #detectSum:?
>>>>>>
>>>>>> 3. Do you agree to the removal of #sumNumbers?
>>>>>>
>>>>>> 4. Do you agree that the #max and #min selectors also need to be adapted?
>>>>>>
>>>>>>
>>>>>>
>>>>>> Thanks for you help.
>>>>>>
>>>>>> Cheers,
>>>>>> Max
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> Benchmarks
>>>>>> ============
>>>>>> (Note that these arenât very good benchmarks. Thereâs quite some variation on each run.)
>>>>>>
>>>>>>
>>>>>> Machine:
>>>>>> MacBook Pro (15-inch, Early 2011)
>>>>>> CPU: 2.2 GHz Intel Core i7
>>>>>> Memory: 8 GB 1333 MHz DDR3
>>>>>> Disk: APPLE SSD TS512C (500 GB)
>>>>>>
>>>>>>
>>>>>> Benchmarks of the current versions:
>>>>>>
>>>>>> [ (1 to: 1000000) asArray sum ] benchFor: 10 seconds.
>>>>>> 75 iterations, 7.470 per second
>>>>>>
>>>>>> [ (1 to: 1000000) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>>>>> 72 iterations, 7.128 per second
>>>>>>
>>>>>>
>>>>>> [ (1 to: 100) asArray sum ] benchFor: 10 seconds.
>>>>>> 1,189,477 iterations, 118,912 per second
>>>>>>
>>>>>>
>>>>>> [ (1 to: 100) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>>>>> 1,171,467 iterations, 117,112 per second
>>>>>>
>>>>>>
>>>>>>
>>>>>> Benchmarks of the new versions:
>>>>>>
>>>>>> [ (1 to: 1000000) asArray sum ] benchFor: 10 seconds.
>>>>>> 73 iterations, 7.244 per second
>>>>>>
>>>>>> [ (1 to: 1000000) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>>>>> 75 iterations, 7.480 per second
>>>>>>
>>>>>> [ (1 to: 1000000) asArray sum: [ :e | e ] ifEmpty: [ 0 ] ] benchFor: 10 seconds.
>>>>>> 72 iterations, 7.141 per second
>>>>>>
>>>>>>
>>>>>> [ (1 to: 100) asArray sum ] benchFor: 10 seconds.
>>>>>> 1,115,827 iterations, 111,560 per second
>>>>>>
>>>>>> [ (1 to: 100) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>>>>> 1,154,595 iterations, 115,425 per second
>>>>>>
>>>>>> [ (1 to: 100) asArray sum: [ :e | e ] ifEmpty: [ 0 ] ] benchFor: 10 seconds.
>>>>>> 1,102,358 iterations, 110,203 per second
>>>>
>>>> --
>>>> www.tudorgirba.com
>>>> www.feenk.com
>>>>
>>>> "There are no old things, there are only old ways of looking at them."
>>>>
>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>
>> --
>> www.tudorgirba.com
>> www.feenk.com
>>
>> "It's not how it is, it is how we see it."
>>
>>
>
>
--
www.tudorgirba.com
www.feenk.com
"What we can governs what we wish."
Dec. 20, 2015
Re: [Pharo-dev] [Vm-dev] Re: SecureSession frame types
by Robert Withers
My apologies for #2 below; what I said is wrong. The smallest message
will be 8 bytes, as the messageSpecification is not FEC encoded. I will
repair the doc as there are some issues with the spec and layout...done.
Once again the link is:
https://www.dropbox.com/s/zj2i1votg432b2p/FrameTypes.pptx?dl=0
* MessageSpecification is 8 bytes binary encoded.
* Header is always asn.1 encoded
* All messages may be FEC encoded with the FEC header asn.1 encoded.
* Data Message payload is encrypted.
Change query:
Regarding the Message Specification, with a hdrSize...I don't think we
need it. The message size includes everything + the 8 bytes spec. The
hdrType will specify the kind of message and header. The specific header
knows it's own size and layout. Therefor, we have 16bits free if we
keep an 8 byte msgSpec. Let's rework it to a 7 byte msgSpec as below.
Perhaps it is useful to be 64bit aligned, so leave it at 8. Thoughts?
Does this work?
*msgSpec: 7 bytes binary encoded*
* HeaderSpecification: 3 bytes
o multicastSymbol: 6 bits
o sanguinity: 7 bits
o msgVersion: 5 bits
o hdrType: 6 bits
* msgSize: 2nd word, 4 bytes
o 4 bytes (total size with msgSpec, header, payload sizes)
regards,
robert
On 12/20/2015 07:01 AM, Robert Withers wrote:
> Good morning, just a few comments and questions..
>
> 1) current 4bits for msgVersion and 4bits for hdrType. With 14
> messages and some not implemented (suspend/resume/...) we have
> little headroom in 4bits of hdrType. Shall I make the msgVersion
> 3bits and the hdrType 5bits?
>
> 2) the smallest interleaved FEC encoded msg is 30 bytes. With 8
> bytes of data: a msgSpec, using RS(15,9) with 4bit symbols, and 4
> symbol block interleaving, the smallest on the wire is 30 bytes.
> Without FEC enabled is it 8 bytes.
>
> 3) when run to the end of hdrType room, we can add a jump tag and
> have a second hdrType field as the 9th byte.
>
>
> Again, the valid document link is:
> https://www.dropbox.com/s/zj2i1votg432b2p/FrameTypes.pptx?dl=0
>
> Thank you,
> robert
>
>
>
> On 12/20/2015 06:20 AM, Clément Bera wrote:
>>
>>
>>
>> Hello,
>>
>> I tried to get your document but I got:
>>
>> Dropbox - error
>>
>> Is it only me ?
>>
>> 2015-12-20 11:31 GMT+01:00 Robert Withers <robert.w.withers(a)gmail.com
>> <mailto:robert.w.withers@gmail.com>>:
>>
>>
>> Excuse me for failing to complete this email./ I wanted to ask
>> for feedback on these structures, especially the header
>> specification word structure. So these fields make sense?
>>
>> thank you,
>> robert
>>
>>
>> On 12/20/2015 05:27 AM, Robert Withers wrote:
>>
>> I wrote up the various SecureSession frame types in
>> presentation document, which you can get here:
>> https://www.dropbox.com/s/3xfa5oqs8ihj88v/FrameTypes.pptx?dl=0
>>
>> These are not yet implemented, but it is progressing. Ne quid
>> nemis.
>>
>> thanks,
>>
>>
>> --
>> . .. .. ^,^ robert
>>
>>
>
> --
> . .. .. ^,^ robert
--
. .. .. ^,^ robert
Dec. 20, 2015
Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:
by Sven Van Caekenberghe
> On 20 Dec 2015, at 14:57, Tudor Girba <tudor(a)tudorgirba.com> wrote:
>
> Hi,
>
> Itâs clear that choices we would make would not be the same :). So, letâs drop past discussions and stay with the current situation. Do you agree with the observation that in the proposal of Max #sum and #sum: would not share the same meaning? If yes, do you agree that it would be misleading from the outside?
The overal meaning is the same, IMO, summing a number of things (most often numbers) using #+. The processing block just adds functionality.
The behaviour in the case of an empty collection is different yes. I want 0, why, because of https://en.wikipedia.org/wiki/Empty_sum
This is about optimisation for the common case.
VW had no #sum, I think because of all the points raised in this discussion (you can't always expect numbers and it is not clear what to do with empty collections).
Check out the senders of #sum and #sum: in a 50 image.
> I would be fine with either answer. I would just want to understand.
>
> Cheers,
> Doru
>
>
>> On Dec 20, 2015, at 2:43 PM, Sven Van Caekenberghe <sven(a)stfx.eu> wrote:
>>
>> Doru,
>>
>> For me this whole discussion started because you (the standpoint that you take) hijacked the best selector (#sum) for a use case that is much less common than adding a collection of numbers which should give 0 when empty (you hijack it by not wanting to return 0, which I totally understand, but doing so you redefine the meaning/semantics).
>>
>> Max's point is to make everything more consistent and remove some API. I support that too.
>>
>> Now, I like Max's proposal.
>>
>> But, you know, my conclusion when the thread ended was that it might be better to throw all these selectors away, since #inject:into: covers most use cases at least as well and at least as clear.
>>
>> Sven
>>
>>> On 20 Dec 2015, at 14:10, Tudor Girba <tudor(a)tudorgirba.com> wrote:
>>>
>>> Hi,
>>>
>>> Could we not have sum, but sumNumbers instead? So, we would end up with:
>>>
>>> sum:ifEmpty:
>>> sum: (with error)
>>> sumNumbers (without error)
>>>
>>> From the outside, #sum: looks like it should parameterize #sum, but the implementation is actually different. So, given that in this implementation #sum is not a special case of #sum: the two should be named differently to reflect that difference. Hence my proposal is to keep #sumNumbers instead of #sum.
>>>
>>> Cheers,
>>> Doru
>>>
>>>
>>>> On Dec 20, 2015, at 1:47 PM, Max Leske <maxleske(a)gmail.com> wrote:
>>>>
>>>>>
>>>>> On 20 Dec 2015, at 13:43, Gabriel Cotelli <g.cotelli(a)gmail.com> wrote:
>>>>>
>>>>> Max,
>>>>>
>>>>> sum: aBlock ifEmpty: emptyBlock needs to obtain the sample evaluating the block.
>>>>>
>>>>> sum: aBlock ifEmpty: emptyBlock
>>>>> | sum sample |
>>>>> self isEmpty ifTrue: [ ^ emptyBlock value ].
>>>>> sample := aBlock value: self anyOne.
>>>>> sum := self
>>>>> inject: sample
>>>>> into: [ :accum :each | accum + (aBlock value: each) ].
>>>>> ^ sum - sample
>>>>
>>>>
>>>> Thanks! Missed that.
>>>>
>>>>>
>>>>> On Sun, Dec 20, 2015 at 8:59 AM, Max Leske <maxleske(a)gmail.com> wrote:
>>>>> I would like to wrap up this discussion.
>>>>>
>>>>>
>>>>>> On 05 Dec 2015, at 18:14, stepharo <stepharo(a)free.fr> wrote:
>>>>>>
>>>>>> So what is the conclusion?
>>>>>> I like the idea of Esteban M to have iterator because it moves some behavior out of core classes.
>>>>>>
>>>>>> [[[
>>>>>>
>>>>>> aCollection arithmetic sum: [...] or.... aCollection
>>>>>> arithmetic avg.
>>>>>>
>>>>>> ]]]
>>>>>>
>>>>>
>>>>> While I think that iterators are an intriguing idea I also believe that they are beyond the scope of this issue. If anybody wants to follow up on iterators (or unit types for that matter) please start a new thread / issue.
>>>>>
>>>>>
>>>>> I propose to use Svenâs version for #sum:ifEmpty:. The result would be these three methods:
>>>>>
>>>>> sum
>>>>> ^ self
>>>>> sum: [ :each | each ]
>>>>> ifEmpty: [ 0 ]
>>>>>
>>>>> sum: aBlock
>>>>> ^ self
>>>>> sum: aBlock
>>>>> ifEmpty: [ self errorEmptyCollection ]
>>>>>
>>>>> sum: aBlock ifEmpty: emptyBlock
>>>>> | sum sample |
>>>>> self isEmpty ifTrue: [ ^ emptyBlock value ].
>>>>> sample := self anyOne.
>>>>> sum := self
>>>>> inject: sample
>>>>> into: [ :accum :each | accum + (aBlock value: each) ].
>>>>> ^ sum - sample
>>>>>
>>>>>
>>>>> Iâve attached a couple of benchmark results below. To me they show that
>>>>> 1. the new implementation is maybe a tiny bit slower but insignificantly so (if youâre going for performance youâll probably write your own optimised version anyway)
>>>>> 2. there is no need to duplicate the code (like #sum and #sum: currently do). Itâs perfectly fine to delegate to #sum:ifEmpty:
>>>>>
>>>>>
>>>>>
>>>>> In addition to the above changes I would like to remove #detectSum: (-> #sum:) and #sumNumbers (-> #sum).
>>>>>
>>>>>
>>>>> Note that once we agree on changing this API, we will need to also change #detectMin:, #detectMax:, #min, #max as well as all overrides (e.g. RunArray, Interval) of these and of #sum et. al. to stay consistent. The changes would of course be in line with this change, such that every operation has a unary selector with a sensible default, one that takes a block and throws an error for empty collections and a third that takes a block for the iteration and one for the empty case.
>>>>>
>>>>>
>>>>> Please cast your vote for these changes:
>>>>>
>>>>> 1. Do you agree to changing #sum and #sum: in the suggested way?
>>>>>
>>>>> 2. Do you agree to the removal of #detectSum:?
>>>>>
>>>>> 3. Do you agree to the removal of #sumNumbers?
>>>>>
>>>>> 4. Do you agree that the #max and #min selectors also need to be adapted?
>>>>>
>>>>>
>>>>>
>>>>> Thanks for you help.
>>>>>
>>>>> Cheers,
>>>>> Max
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> Benchmarks
>>>>> ============
>>>>> (Note that these arenât very good benchmarks. Thereâs quite some variation on each run.)
>>>>>
>>>>>
>>>>> Machine:
>>>>> MacBook Pro (15-inch, Early 2011)
>>>>> CPU: 2.2 GHz Intel Core i7
>>>>> Memory: 8 GB 1333 MHz DDR3
>>>>> Disk: APPLE SSD TS512C (500 GB)
>>>>>
>>>>>
>>>>> Benchmarks of the current versions:
>>>>>
>>>>> [ (1 to: 1000000) asArray sum ] benchFor: 10 seconds.
>>>>> 75 iterations, 7.470 per second
>>>>>
>>>>> [ (1 to: 1000000) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>>>> 72 iterations, 7.128 per second
>>>>>
>>>>>
>>>>> [ (1 to: 100) asArray sum ] benchFor: 10 seconds.
>>>>> 1,189,477 iterations, 118,912 per second
>>>>>
>>>>>
>>>>> [ (1 to: 100) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>>>> 1,171,467 iterations, 117,112 per second
>>>>>
>>>>>
>>>>>
>>>>> Benchmarks of the new versions:
>>>>>
>>>>> [ (1 to: 1000000) asArray sum ] benchFor: 10 seconds.
>>>>> 73 iterations, 7.244 per second
>>>>>
>>>>> [ (1 to: 1000000) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>>>> 75 iterations, 7.480 per second
>>>>>
>>>>> [ (1 to: 1000000) asArray sum: [ :e | e ] ifEmpty: [ 0 ] ] benchFor: 10 seconds.
>>>>> 72 iterations, 7.141 per second
>>>>>
>>>>>
>>>>> [ (1 to: 100) asArray sum ] benchFor: 10 seconds.
>>>>> 1,115,827 iterations, 111,560 per second
>>>>>
>>>>> [ (1 to: 100) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>>>> 1,154,595 iterations, 115,425 per second
>>>>>
>>>>> [ (1 to: 100) asArray sum: [ :e | e ] ifEmpty: [ 0 ] ] benchFor: 10 seconds.
>>>>> 1,102,358 iterations, 110,203 per second
>>>
>>> --
>>> www.tudorgirba.com
>>> www.feenk.com
>>>
>>> "There are no old things, there are only old ways of looking at them."
>>>
>>>
>>>
>>>
>>>
>>
>>
>
> --
> www.tudorgirba.com
> www.feenk.com
>
> "It's not how it is, it is how we see it."
>
>
Dec. 20, 2015
Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:
by Sven Van Caekenberghe
No means I don't want to start adding Numbers to beautiful unary selectors. I don't understand why you don't understand that point about beauty and simplicity.
> On 20 Dec 2015, at 14:54, Tudor Girba <tudor(a)tudorgirba.com> wrote:
>
> Hi,
>
> I am not sure I understand the meaning of NO in the context of the previous message.
>
> Is the NO related to the sumNumbers, or to the min, max?
>
> Cheers,
> Doru
>
>
>> On Dec 20, 2015, at 2:43 PM, Sven Van Caekenberghe <sven(a)stfx.eu> wrote:
>>
>> NO
>>
>>> On 20 Dec 2015, at 14:32, Tudor Girba <tudor(a)tudorgirba.com> wrote:
>>>
>>> Hi,
>>>
>>>> On Dec 20, 2015, at 2:30 PM, Max Leske <maxleske(a)gmail.com> wrote:
>>>>
>>>>
>>>>> On 20 Dec 2015, at 14:10, Tudor Girba <tudor(a)tudorgirba.com> wrote:
>>>>>
>>>>> Hi,
>>>>>
>>>>> Could we not have sum, but sumNumbers instead? So, we would end up with:
>>>>>
>>>>> sum:ifEmpty:
>>>>> sum: (with error)
>>>>> sumNumbers (without error)
>>>>>
>>>>> From the outside, #sum: looks like it should parameterize #sum, but the implementation is actually different. So, given that in this implementation #sum is not a special case of #sum: the two should be named differently to reflect that difference. Hence my proposal is to keep #sumNumbers instead of #sum.
>>>>
>>>> I could live with that. We would sacrifice the beautiful selector #sum for the more intention revealing #sumNumbers. I think that makes sense.
>>>>
>>>> Concerning the #min and #max methods that means weâd end up with e.g. #minNumbers, #min: and #min:ifEmpty: etc.
>>>
>>> Yes.
>>>
>>> Doru
>>>
>>>
>>>>
>>>>>
>>>>> Cheers,
>>>>> Doru
>>>>>
>>>>>
>>>>>> On Dec 20, 2015, at 1:47 PM, Max Leske <maxleske(a)gmail.com> wrote:
>>>>>>
>>>>>>>
>>>>>>> On 20 Dec 2015, at 13:43, Gabriel Cotelli <g.cotelli(a)gmail.com> wrote:
>>>>>>>
>>>>>>> Max,
>>>>>>>
>>>>>>> sum: aBlock ifEmpty: emptyBlock needs to obtain the sample evaluating the block.
>>>>>>>
>>>>>>> sum: aBlock ifEmpty: emptyBlock
>>>>>>> | sum sample |
>>>>>>> self isEmpty ifTrue: [ ^ emptyBlock value ].
>>>>>>> sample := aBlock value: self anyOne.
>>>>>>> sum := self
>>>>>>> inject: sample
>>>>>>> into: [ :accum :each | accum + (aBlock value: each) ].
>>>>>>> ^ sum - sample
>>>>>>
>>>>>>
>>>>>> Thanks! Missed that.
>>>>>>
>>>>>>>
>>>>>>> On Sun, Dec 20, 2015 at 8:59 AM, Max Leske <maxleske(a)gmail.com> wrote:
>>>>>>> I would like to wrap up this discussion.
>>>>>>>
>>>>>>>
>>>>>>>> On 05 Dec 2015, at 18:14, stepharo <stepharo(a)free.fr> wrote:
>>>>>>>>
>>>>>>>> So what is the conclusion?
>>>>>>>> I like the idea of Esteban M to have iterator because it moves some behavior out of core classes.
>>>>>>>>
>>>>>>>> [[[
>>>>>>>>
>>>>>>>> aCollection arithmetic sum: [...] or.... aCollection
>>>>>>>> arithmetic avg.
>>>>>>>>
>>>>>>>> ]]]
>>>>>>>>
>>>>>>>
>>>>>>> While I think that iterators are an intriguing idea I also believe that they are beyond the scope of this issue. If anybody wants to follow up on iterators (or unit types for that matter) please start a new thread / issue.
>>>>>>>
>>>>>>>
>>>>>>> I propose to use Svenâs version for #sum:ifEmpty:. The result would be these three methods:
>>>>>>>
>>>>>>> sum
>>>>>>> ^ self
>>>>>>> sum: [ :each | each ]
>>>>>>> ifEmpty: [ 0 ]
>>>>>>>
>>>>>>> sum: aBlock
>>>>>>> ^ self
>>>>>>> sum: aBlock
>>>>>>> ifEmpty: [ self errorEmptyCollection ]
>>>>>>>
>>>>>>> sum: aBlock ifEmpty: emptyBlock
>>>>>>> | sum sample |
>>>>>>> self isEmpty ifTrue: [ ^ emptyBlock value ].
>>>>>>> sample := self anyOne.
>>>>>>> sum := self
>>>>>>> inject: sample
>>>>>>> into: [ :accum :each | accum + (aBlock value: each) ].
>>>>>>> ^ sum - sample
>>>>>>>
>>>>>>>
>>>>>>> Iâve attached a couple of benchmark results below. To me they show that
>>>>>>> 1. the new implementation is maybe a tiny bit slower but insignificantly so (if youâre going for performance youâll probably write your own optimised version anyway)
>>>>>>> 2. there is no need to duplicate the code (like #sum and #sum: currently do). Itâs perfectly fine to delegate to #sum:ifEmpty:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> In addition to the above changes I would like to remove #detectSum: (-> #sum:) and #sumNumbers (-> #sum).
>>>>>>>
>>>>>>>
>>>>>>> Note that once we agree on changing this API, we will need to also change #detectMin:, #detectMax:, #min, #max as well as all overrides (e.g. RunArray, Interval) of these and of #sum et. al. to stay consistent. The changes would of course be in line with this change, such that every operation has a unary selector with a sensible default, one that takes a block and throws an error for empty collections and a third that takes a block for the iteration and one for the empty case.
>>>>>>>
>>>>>>>
>>>>>>> Please cast your vote for these changes:
>>>>>>>
>>>>>>> 1. Do you agree to changing #sum and #sum: in the suggested way?
>>>>>>>
>>>>>>> 2. Do you agree to the removal of #detectSum:?
>>>>>>>
>>>>>>> 3. Do you agree to the removal of #sumNumbers?
>>>>>>>
>>>>>>> 4. Do you agree that the #max and #min selectors also need to be adapted?
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Thanks for you help.
>>>>>>>
>>>>>>> Cheers,
>>>>>>> Max
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Benchmarks
>>>>>>> ============
>>>>>>> (Note that these arenât very good benchmarks. Thereâs quite some variation on each run.)
>>>>>>>
>>>>>>>
>>>>>>> Machine:
>>>>>>> MacBook Pro (15-inch, Early 2011)
>>>>>>> CPU: 2.2 GHz Intel Core i7
>>>>>>> Memory: 8 GB 1333 MHz DDR3
>>>>>>> Disk: APPLE SSD TS512C (500 GB)
>>>>>>>
>>>>>>>
>>>>>>> Benchmarks of the current versions:
>>>>>>>
>>>>>>> [ (1 to: 1000000) asArray sum ] benchFor: 10 seconds.
>>>>>>> 75 iterations, 7.470 per second
>>>>>>>
>>>>>>> [ (1 to: 1000000) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>>>>>> 72 iterations, 7.128 per second
>>>>>>>
>>>>>>>
>>>>>>> [ (1 to: 100) asArray sum ] benchFor: 10 seconds.
>>>>>>> 1,189,477 iterations, 118,912 per second
>>>>>>>
>>>>>>>
>>>>>>> [ (1 to: 100) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>>>>>> 1,171,467 iterations, 117,112 per second
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Benchmarks of the new versions:
>>>>>>>
>>>>>>> [ (1 to: 1000000) asArray sum ] benchFor: 10 seconds.
>>>>>>> 73 iterations, 7.244 per second
>>>>>>>
>>>>>>> [ (1 to: 1000000) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>>>>>> 75 iterations, 7.480 per second
>>>>>>>
>>>>>>> [ (1 to: 1000000) asArray sum: [ :e | e ] ifEmpty: [ 0 ] ] benchFor: 10 seconds.
>>>>>>> 72 iterations, 7.141 per second
>>>>>>>
>>>>>>>
>>>>>>> [ (1 to: 100) asArray sum ] benchFor: 10 seconds.
>>>>>>> 1,115,827 iterations, 111,560 per second
>>>>>>>
>>>>>>> [ (1 to: 100) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>>>>>> 1,154,595 iterations, 115,425 per second
>>>>>>>
>>>>>>> [ (1 to: 100) asArray sum: [ :e | e ] ifEmpty: [ 0 ] ] benchFor: 10 seconds.
>>>>>>> 1,102,358 iterations, 110,203 per second
>>>>>
>>>>> --
>>>>> www.tudorgirba.com
>>>>> www.feenk.com
>>>>>
>>>>> "There are no old things, there are only old ways of looking at them."
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>
>>> --
>>> www.tudorgirba.com
>>> www.feenk.com
>>>
>>> "If you can't say why something is relevant,
>>> it probably isn't."
>>
>>
>
> --
> www.tudorgirba.com
> www.feenk.com
>
> "Beauty is where we see it."
>
>
>
>
>
Dec. 20, 2015
Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:
by Tudor Girba
Hi,
Itâs clear that choices we would make would not be the same :). So, letâs drop past discussions and stay with the current situation. Do you agree with the observation that in the proposal of Max #sum and #sum: would not share the same meaning? If yes, do you agree that it would be misleading from the outside?
I would be fine with either answer. I would just want to understand.
Cheers,
Doru
> On Dec 20, 2015, at 2:43 PM, Sven Van Caekenberghe <sven(a)stfx.eu> wrote:
>
> Doru,
>
> For me this whole discussion started because you (the standpoint that you take) hijacked the best selector (#sum) for a use case that is much less common than adding a collection of numbers which should give 0 when empty (you hijack it by not wanting to return 0, which I totally understand, but doing so you redefine the meaning/semantics).
>
> Max's point is to make everything more consistent and remove some API. I support that too.
>
> Now, I like Max's proposal.
>
> But, you know, my conclusion when the thread ended was that it might be better to throw all these selectors away, since #inject:into: covers most use cases at least as well and at least as clear.
>
> Sven
>
>> On 20 Dec 2015, at 14:10, Tudor Girba <tudor(a)tudorgirba.com> wrote:
>>
>> Hi,
>>
>> Could we not have sum, but sumNumbers instead? So, we would end up with:
>>
>> sum:ifEmpty:
>> sum: (with error)
>> sumNumbers (without error)
>>
>> From the outside, #sum: looks like it should parameterize #sum, but the implementation is actually different. So, given that in this implementation #sum is not a special case of #sum: the two should be named differently to reflect that difference. Hence my proposal is to keep #sumNumbers instead of #sum.
>>
>> Cheers,
>> Doru
>>
>>
>>> On Dec 20, 2015, at 1:47 PM, Max Leske <maxleske(a)gmail.com> wrote:
>>>
>>>>
>>>> On 20 Dec 2015, at 13:43, Gabriel Cotelli <g.cotelli(a)gmail.com> wrote:
>>>>
>>>> Max,
>>>>
>>>> sum: aBlock ifEmpty: emptyBlock needs to obtain the sample evaluating the block.
>>>>
>>>> sum: aBlock ifEmpty: emptyBlock
>>>> | sum sample |
>>>> self isEmpty ifTrue: [ ^ emptyBlock value ].
>>>> sample := aBlock value: self anyOne.
>>>> sum := self
>>>> inject: sample
>>>> into: [ :accum :each | accum + (aBlock value: each) ].
>>>> ^ sum - sample
>>>
>>>
>>> Thanks! Missed that.
>>>
>>>>
>>>> On Sun, Dec 20, 2015 at 8:59 AM, Max Leske <maxleske(a)gmail.com> wrote:
>>>> I would like to wrap up this discussion.
>>>>
>>>>
>>>>> On 05 Dec 2015, at 18:14, stepharo <stepharo(a)free.fr> wrote:
>>>>>
>>>>> So what is the conclusion?
>>>>> I like the idea of Esteban M to have iterator because it moves some behavior out of core classes.
>>>>>
>>>>> [[[
>>>>>
>>>>> aCollection arithmetic sum: [...] or.... aCollection
>>>>> arithmetic avg.
>>>>>
>>>>> ]]]
>>>>>
>>>>
>>>> While I think that iterators are an intriguing idea I also believe that they are beyond the scope of this issue. If anybody wants to follow up on iterators (or unit types for that matter) please start a new thread / issue.
>>>>
>>>>
>>>> I propose to use Svenâs version for #sum:ifEmpty:. The result would be these three methods:
>>>>
>>>> sum
>>>> ^ self
>>>> sum: [ :each | each ]
>>>> ifEmpty: [ 0 ]
>>>>
>>>> sum: aBlock
>>>> ^ self
>>>> sum: aBlock
>>>> ifEmpty: [ self errorEmptyCollection ]
>>>>
>>>> sum: aBlock ifEmpty: emptyBlock
>>>> | sum sample |
>>>> self isEmpty ifTrue: [ ^ emptyBlock value ].
>>>> sample := self anyOne.
>>>> sum := self
>>>> inject: sample
>>>> into: [ :accum :each | accum + (aBlock value: each) ].
>>>> ^ sum - sample
>>>>
>>>>
>>>> Iâve attached a couple of benchmark results below. To me they show that
>>>> 1. the new implementation is maybe a tiny bit slower but insignificantly so (if youâre going for performance youâll probably write your own optimised version anyway)
>>>> 2. there is no need to duplicate the code (like #sum and #sum: currently do). Itâs perfectly fine to delegate to #sum:ifEmpty:
>>>>
>>>>
>>>>
>>>> In addition to the above changes I would like to remove #detectSum: (-> #sum:) and #sumNumbers (-> #sum).
>>>>
>>>>
>>>> Note that once we agree on changing this API, we will need to also change #detectMin:, #detectMax:, #min, #max as well as all overrides (e.g. RunArray, Interval) of these and of #sum et. al. to stay consistent. The changes would of course be in line with this change, such that every operation has a unary selector with a sensible default, one that takes a block and throws an error for empty collections and a third that takes a block for the iteration and one for the empty case.
>>>>
>>>>
>>>> Please cast your vote for these changes:
>>>>
>>>> 1. Do you agree to changing #sum and #sum: in the suggested way?
>>>>
>>>> 2. Do you agree to the removal of #detectSum:?
>>>>
>>>> 3. Do you agree to the removal of #sumNumbers?
>>>>
>>>> 4. Do you agree that the #max and #min selectors also need to be adapted?
>>>>
>>>>
>>>>
>>>> Thanks for you help.
>>>>
>>>> Cheers,
>>>> Max
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> Benchmarks
>>>> ============
>>>> (Note that these arenât very good benchmarks. Thereâs quite some variation on each run.)
>>>>
>>>>
>>>> Machine:
>>>> MacBook Pro (15-inch, Early 2011)
>>>> CPU: 2.2 GHz Intel Core i7
>>>> Memory: 8 GB 1333 MHz DDR3
>>>> Disk: APPLE SSD TS512C (500 GB)
>>>>
>>>>
>>>> Benchmarks of the current versions:
>>>>
>>>> [ (1 to: 1000000) asArray sum ] benchFor: 10 seconds.
>>>> 75 iterations, 7.470 per second
>>>>
>>>> [ (1 to: 1000000) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>>> 72 iterations, 7.128 per second
>>>>
>>>>
>>>> [ (1 to: 100) asArray sum ] benchFor: 10 seconds.
>>>> 1,189,477 iterations, 118,912 per second
>>>>
>>>>
>>>> [ (1 to: 100) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>>> 1,171,467 iterations, 117,112 per second
>>>>
>>>>
>>>>
>>>> Benchmarks of the new versions:
>>>>
>>>> [ (1 to: 1000000) asArray sum ] benchFor: 10 seconds.
>>>> 73 iterations, 7.244 per second
>>>>
>>>> [ (1 to: 1000000) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>>> 75 iterations, 7.480 per second
>>>>
>>>> [ (1 to: 1000000) asArray sum: [ :e | e ] ifEmpty: [ 0 ] ] benchFor: 10 seconds.
>>>> 72 iterations, 7.141 per second
>>>>
>>>>
>>>> [ (1 to: 100) asArray sum ] benchFor: 10 seconds.
>>>> 1,115,827 iterations, 111,560 per second
>>>>
>>>> [ (1 to: 100) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>>> 1,154,595 iterations, 115,425 per second
>>>>
>>>> [ (1 to: 100) asArray sum: [ :e | e ] ifEmpty: [ 0 ] ] benchFor: 10 seconds.
>>>> 1,102,358 iterations, 110,203 per second
>>
>> --
>> www.tudorgirba.com
>> www.feenk.com
>>
>> "There are no old things, there are only old ways of looking at them."
>>
>>
>>
>>
>>
>
>
--
www.tudorgirba.com
www.feenk.com
"It's not how it is, it is how we see it."
Dec. 20, 2015
Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:
by Tudor Girba
Hi,
I am not sure I understand the meaning of NO in the context of the previous message.
Is the NO related to the sumNumbers, or to the min, max?
Cheers,
Doru
> On Dec 20, 2015, at 2:43 PM, Sven Van Caekenberghe <sven(a)stfx.eu> wrote:
>
> NO
>
>> On 20 Dec 2015, at 14:32, Tudor Girba <tudor(a)tudorgirba.com> wrote:
>>
>> Hi,
>>
>>> On Dec 20, 2015, at 2:30 PM, Max Leske <maxleske(a)gmail.com> wrote:
>>>
>>>
>>>> On 20 Dec 2015, at 14:10, Tudor Girba <tudor(a)tudorgirba.com> wrote:
>>>>
>>>> Hi,
>>>>
>>>> Could we not have sum, but sumNumbers instead? So, we would end up with:
>>>>
>>>> sum:ifEmpty:
>>>> sum: (with error)
>>>> sumNumbers (without error)
>>>>
>>>> From the outside, #sum: looks like it should parameterize #sum, but the implementation is actually different. So, given that in this implementation #sum is not a special case of #sum: the two should be named differently to reflect that difference. Hence my proposal is to keep #sumNumbers instead of #sum.
>>>
>>> I could live with that. We would sacrifice the beautiful selector #sum for the more intention revealing #sumNumbers. I think that makes sense.
>>>
>>> Concerning the #min and #max methods that means weâd end up with e.g. #minNumbers, #min: and #min:ifEmpty: etc.
>>
>> Yes.
>>
>> Doru
>>
>>
>>>
>>>>
>>>> Cheers,
>>>> Doru
>>>>
>>>>
>>>>> On Dec 20, 2015, at 1:47 PM, Max Leske <maxleske(a)gmail.com> wrote:
>>>>>
>>>>>>
>>>>>> On 20 Dec 2015, at 13:43, Gabriel Cotelli <g.cotelli(a)gmail.com> wrote:
>>>>>>
>>>>>> Max,
>>>>>>
>>>>>> sum: aBlock ifEmpty: emptyBlock needs to obtain the sample evaluating the block.
>>>>>>
>>>>>> sum: aBlock ifEmpty: emptyBlock
>>>>>> | sum sample |
>>>>>> self isEmpty ifTrue: [ ^ emptyBlock value ].
>>>>>> sample := aBlock value: self anyOne.
>>>>>> sum := self
>>>>>> inject: sample
>>>>>> into: [ :accum :each | accum + (aBlock value: each) ].
>>>>>> ^ sum - sample
>>>>>
>>>>>
>>>>> Thanks! Missed that.
>>>>>
>>>>>>
>>>>>> On Sun, Dec 20, 2015 at 8:59 AM, Max Leske <maxleske(a)gmail.com> wrote:
>>>>>> I would like to wrap up this discussion.
>>>>>>
>>>>>>
>>>>>>> On 05 Dec 2015, at 18:14, stepharo <stepharo(a)free.fr> wrote:
>>>>>>>
>>>>>>> So what is the conclusion?
>>>>>>> I like the idea of Esteban M to have iterator because it moves some behavior out of core classes.
>>>>>>>
>>>>>>> [[[
>>>>>>>
>>>>>>> aCollection arithmetic sum: [...] or.... aCollection
>>>>>>> arithmetic avg.
>>>>>>>
>>>>>>> ]]]
>>>>>>>
>>>>>>
>>>>>> While I think that iterators are an intriguing idea I also believe that they are beyond the scope of this issue. If anybody wants to follow up on iterators (or unit types for that matter) please start a new thread / issue.
>>>>>>
>>>>>>
>>>>>> I propose to use Svenâs version for #sum:ifEmpty:. The result would be these three methods:
>>>>>>
>>>>>> sum
>>>>>> ^ self
>>>>>> sum: [ :each | each ]
>>>>>> ifEmpty: [ 0 ]
>>>>>>
>>>>>> sum: aBlock
>>>>>> ^ self
>>>>>> sum: aBlock
>>>>>> ifEmpty: [ self errorEmptyCollection ]
>>>>>>
>>>>>> sum: aBlock ifEmpty: emptyBlock
>>>>>> | sum sample |
>>>>>> self isEmpty ifTrue: [ ^ emptyBlock value ].
>>>>>> sample := self anyOne.
>>>>>> sum := self
>>>>>> inject: sample
>>>>>> into: [ :accum :each | accum + (aBlock value: each) ].
>>>>>> ^ sum - sample
>>>>>>
>>>>>>
>>>>>> Iâve attached a couple of benchmark results below. To me they show that
>>>>>> 1. the new implementation is maybe a tiny bit slower but insignificantly so (if youâre going for performance youâll probably write your own optimised version anyway)
>>>>>> 2. there is no need to duplicate the code (like #sum and #sum: currently do). Itâs perfectly fine to delegate to #sum:ifEmpty:
>>>>>>
>>>>>>
>>>>>>
>>>>>> In addition to the above changes I would like to remove #detectSum: (-> #sum:) and #sumNumbers (-> #sum).
>>>>>>
>>>>>>
>>>>>> Note that once we agree on changing this API, we will need to also change #detectMin:, #detectMax:, #min, #max as well as all overrides (e.g. RunArray, Interval) of these and of #sum et. al. to stay consistent. The changes would of course be in line with this change, such that every operation has a unary selector with a sensible default, one that takes a block and throws an error for empty collections and a third that takes a block for the iteration and one for the empty case.
>>>>>>
>>>>>>
>>>>>> Please cast your vote for these changes:
>>>>>>
>>>>>> 1. Do you agree to changing #sum and #sum: in the suggested way?
>>>>>>
>>>>>> 2. Do you agree to the removal of #detectSum:?
>>>>>>
>>>>>> 3. Do you agree to the removal of #sumNumbers?
>>>>>>
>>>>>> 4. Do you agree that the #max and #min selectors also need to be adapted?
>>>>>>
>>>>>>
>>>>>>
>>>>>> Thanks for you help.
>>>>>>
>>>>>> Cheers,
>>>>>> Max
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> Benchmarks
>>>>>> ============
>>>>>> (Note that these arenât very good benchmarks. Thereâs quite some variation on each run.)
>>>>>>
>>>>>>
>>>>>> Machine:
>>>>>> MacBook Pro (15-inch, Early 2011)
>>>>>> CPU: 2.2 GHz Intel Core i7
>>>>>> Memory: 8 GB 1333 MHz DDR3
>>>>>> Disk: APPLE SSD TS512C (500 GB)
>>>>>>
>>>>>>
>>>>>> Benchmarks of the current versions:
>>>>>>
>>>>>> [ (1 to: 1000000) asArray sum ] benchFor: 10 seconds.
>>>>>> 75 iterations, 7.470 per second
>>>>>>
>>>>>> [ (1 to: 1000000) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>>>>> 72 iterations, 7.128 per second
>>>>>>
>>>>>>
>>>>>> [ (1 to: 100) asArray sum ] benchFor: 10 seconds.
>>>>>> 1,189,477 iterations, 118,912 per second
>>>>>>
>>>>>>
>>>>>> [ (1 to: 100) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>>>>> 1,171,467 iterations, 117,112 per second
>>>>>>
>>>>>>
>>>>>>
>>>>>> Benchmarks of the new versions:
>>>>>>
>>>>>> [ (1 to: 1000000) asArray sum ] benchFor: 10 seconds.
>>>>>> 73 iterations, 7.244 per second
>>>>>>
>>>>>> [ (1 to: 1000000) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>>>>> 75 iterations, 7.480 per second
>>>>>>
>>>>>> [ (1 to: 1000000) asArray sum: [ :e | e ] ifEmpty: [ 0 ] ] benchFor: 10 seconds.
>>>>>> 72 iterations, 7.141 per second
>>>>>>
>>>>>>
>>>>>> [ (1 to: 100) asArray sum ] benchFor: 10 seconds.
>>>>>> 1,115,827 iterations, 111,560 per second
>>>>>>
>>>>>> [ (1 to: 100) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>>>>> 1,154,595 iterations, 115,425 per second
>>>>>>
>>>>>> [ (1 to: 100) asArray sum: [ :e | e ] ifEmpty: [ 0 ] ] benchFor: 10 seconds.
>>>>>> 1,102,358 iterations, 110,203 per second
>>>>
>>>> --
>>>> www.tudorgirba.com
>>>> www.feenk.com
>>>>
>>>> "There are no old things, there are only old ways of looking at them."
>>>>
>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>
>> --
>> www.tudorgirba.com
>> www.feenk.com
>>
>> "If you can't say why something is relevant,
>> it probably isn't."
>
>
--
www.tudorgirba.com
www.feenk.com
"Beauty is where we see it."
Dec. 20, 2015
Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:
by Sven Van Caekenberghe
NO
> On 20 Dec 2015, at 14:32, Tudor Girba <tudor(a)tudorgirba.com> wrote:
>
> Hi,
>
>> On Dec 20, 2015, at 2:30 PM, Max Leske <maxleske(a)gmail.com> wrote:
>>
>>
>>> On 20 Dec 2015, at 14:10, Tudor Girba <tudor(a)tudorgirba.com> wrote:
>>>
>>> Hi,
>>>
>>> Could we not have sum, but sumNumbers instead? So, we would end up with:
>>>
>>> sum:ifEmpty:
>>> sum: (with error)
>>> sumNumbers (without error)
>>>
>>> From the outside, #sum: looks like it should parameterize #sum, but the implementation is actually different. So, given that in this implementation #sum is not a special case of #sum: the two should be named differently to reflect that difference. Hence my proposal is to keep #sumNumbers instead of #sum.
>>
>> I could live with that. We would sacrifice the beautiful selector #sum for the more intention revealing #sumNumbers. I think that makes sense.
>>
>> Concerning the #min and #max methods that means weâd end up with e.g. #minNumbers, #min: and #min:ifEmpty: etc.
>
> Yes.
>
> Doru
>
>
>>
>>>
>>> Cheers,
>>> Doru
>>>
>>>
>>>> On Dec 20, 2015, at 1:47 PM, Max Leske <maxleske(a)gmail.com> wrote:
>>>>
>>>>>
>>>>> On 20 Dec 2015, at 13:43, Gabriel Cotelli <g.cotelli(a)gmail.com> wrote:
>>>>>
>>>>> Max,
>>>>>
>>>>> sum: aBlock ifEmpty: emptyBlock needs to obtain the sample evaluating the block.
>>>>>
>>>>> sum: aBlock ifEmpty: emptyBlock
>>>>> | sum sample |
>>>>> self isEmpty ifTrue: [ ^ emptyBlock value ].
>>>>> sample := aBlock value: self anyOne.
>>>>> sum := self
>>>>> inject: sample
>>>>> into: [ :accum :each | accum + (aBlock value: each) ].
>>>>> ^ sum - sample
>>>>
>>>>
>>>> Thanks! Missed that.
>>>>
>>>>>
>>>>> On Sun, Dec 20, 2015 at 8:59 AM, Max Leske <maxleske(a)gmail.com> wrote:
>>>>> I would like to wrap up this discussion.
>>>>>
>>>>>
>>>>>> On 05 Dec 2015, at 18:14, stepharo <stepharo(a)free.fr> wrote:
>>>>>>
>>>>>> So what is the conclusion?
>>>>>> I like the idea of Esteban M to have iterator because it moves some behavior out of core classes.
>>>>>>
>>>>>> [[[
>>>>>>
>>>>>> aCollection arithmetic sum: [...] or.... aCollection
>>>>>> arithmetic avg.
>>>>>>
>>>>>> ]]]
>>>>>>
>>>>>
>>>>> While I think that iterators are an intriguing idea I also believe that they are beyond the scope of this issue. If anybody wants to follow up on iterators (or unit types for that matter) please start a new thread / issue.
>>>>>
>>>>>
>>>>> I propose to use Svenâs version for #sum:ifEmpty:. The result would be these three methods:
>>>>>
>>>>> sum
>>>>> ^ self
>>>>> sum: [ :each | each ]
>>>>> ifEmpty: [ 0 ]
>>>>>
>>>>> sum: aBlock
>>>>> ^ self
>>>>> sum: aBlock
>>>>> ifEmpty: [ self errorEmptyCollection ]
>>>>>
>>>>> sum: aBlock ifEmpty: emptyBlock
>>>>> | sum sample |
>>>>> self isEmpty ifTrue: [ ^ emptyBlock value ].
>>>>> sample := self anyOne.
>>>>> sum := self
>>>>> inject: sample
>>>>> into: [ :accum :each | accum + (aBlock value: each) ].
>>>>> ^ sum - sample
>>>>>
>>>>>
>>>>> Iâve attached a couple of benchmark results below. To me they show that
>>>>> 1. the new implementation is maybe a tiny bit slower but insignificantly so (if youâre going for performance youâll probably write your own optimised version anyway)
>>>>> 2. there is no need to duplicate the code (like #sum and #sum: currently do). Itâs perfectly fine to delegate to #sum:ifEmpty:
>>>>>
>>>>>
>>>>>
>>>>> In addition to the above changes I would like to remove #detectSum: (-> #sum:) and #sumNumbers (-> #sum).
>>>>>
>>>>>
>>>>> Note that once we agree on changing this API, we will need to also change #detectMin:, #detectMax:, #min, #max as well as all overrides (e.g. RunArray, Interval) of these and of #sum et. al. to stay consistent. The changes would of course be in line with this change, such that every operation has a unary selector with a sensible default, one that takes a block and throws an error for empty collections and a third that takes a block for the iteration and one for the empty case.
>>>>>
>>>>>
>>>>> Please cast your vote for these changes:
>>>>>
>>>>> 1. Do you agree to changing #sum and #sum: in the suggested way?
>>>>>
>>>>> 2. Do you agree to the removal of #detectSum:?
>>>>>
>>>>> 3. Do you agree to the removal of #sumNumbers?
>>>>>
>>>>> 4. Do you agree that the #max and #min selectors also need to be adapted?
>>>>>
>>>>>
>>>>>
>>>>> Thanks for you help.
>>>>>
>>>>> Cheers,
>>>>> Max
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> Benchmarks
>>>>> ============
>>>>> (Note that these arenât very good benchmarks. Thereâs quite some variation on each run.)
>>>>>
>>>>>
>>>>> Machine:
>>>>> MacBook Pro (15-inch, Early 2011)
>>>>> CPU: 2.2 GHz Intel Core i7
>>>>> Memory: 8 GB 1333 MHz DDR3
>>>>> Disk: APPLE SSD TS512C (500 GB)
>>>>>
>>>>>
>>>>> Benchmarks of the current versions:
>>>>>
>>>>> [ (1 to: 1000000) asArray sum ] benchFor: 10 seconds.
>>>>> 75 iterations, 7.470 per second
>>>>>
>>>>> [ (1 to: 1000000) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>>>> 72 iterations, 7.128 per second
>>>>>
>>>>>
>>>>> [ (1 to: 100) asArray sum ] benchFor: 10 seconds.
>>>>> 1,189,477 iterations, 118,912 per second
>>>>>
>>>>>
>>>>> [ (1 to: 100) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>>>> 1,171,467 iterations, 117,112 per second
>>>>>
>>>>>
>>>>>
>>>>> Benchmarks of the new versions:
>>>>>
>>>>> [ (1 to: 1000000) asArray sum ] benchFor: 10 seconds.
>>>>> 73 iterations, 7.244 per second
>>>>>
>>>>> [ (1 to: 1000000) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>>>> 75 iterations, 7.480 per second
>>>>>
>>>>> [ (1 to: 1000000) asArray sum: [ :e | e ] ifEmpty: [ 0 ] ] benchFor: 10 seconds.
>>>>> 72 iterations, 7.141 per second
>>>>>
>>>>>
>>>>> [ (1 to: 100) asArray sum ] benchFor: 10 seconds.
>>>>> 1,115,827 iterations, 111,560 per second
>>>>>
>>>>> [ (1 to: 100) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>>>> 1,154,595 iterations, 115,425 per second
>>>>>
>>>>> [ (1 to: 100) asArray sum: [ :e | e ] ifEmpty: [ 0 ] ] benchFor: 10 seconds.
>>>>> 1,102,358 iterations, 110,203 per second
>>>
>>> --
>>> www.tudorgirba.com
>>> www.feenk.com
>>>
>>> "There are no old things, there are only old ways of looking at them."
>>>
>>>
>>>
>>>
>>>
>>
>>
>
> --
> www.tudorgirba.com
> www.feenk.com
>
> "If you can't say why something is relevant,
> it probably isn't."
Dec. 20, 2015
Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:
by Sven Van Caekenberghe
Doru,
For me this whole discussion started because you (the standpoint that you take) hijacked the best selector (#sum) for a use case that is much less common than adding a collection of numbers which should give 0 when empty (you hijack it by not wanting to return 0, which I totally understand, but doing so you redefine the meaning/semantics).
Max's point is to make everything more consistent and remove some API. I support that too.
Now, I like Max's proposal.
But, you know, my conclusion when the thread ended was that it might be better to throw all these selectors away, since #inject:into: covers most use cases at least as well and at least as clear.
Sven
> On 20 Dec 2015, at 14:10, Tudor Girba <tudor(a)tudorgirba.com> wrote:
>
> Hi,
>
> Could we not have sum, but sumNumbers instead? So, we would end up with:
>
> sum:ifEmpty:
> sum: (with error)
> sumNumbers (without error)
>
> From the outside, #sum: looks like it should parameterize #sum, but the implementation is actually different. So, given that in this implementation #sum is not a special case of #sum: the two should be named differently to reflect that difference. Hence my proposal is to keep #sumNumbers instead of #sum.
>
> Cheers,
> Doru
>
>
>> On Dec 20, 2015, at 1:47 PM, Max Leske <maxleske(a)gmail.com> wrote:
>>
>>>
>>> On 20 Dec 2015, at 13:43, Gabriel Cotelli <g.cotelli(a)gmail.com> wrote:
>>>
>>> Max,
>>>
>>> sum: aBlock ifEmpty: emptyBlock needs to obtain the sample evaluating the block.
>>>
>>> sum: aBlock ifEmpty: emptyBlock
>>> | sum sample |
>>> self isEmpty ifTrue: [ ^ emptyBlock value ].
>>> sample := aBlock value: self anyOne.
>>> sum := self
>>> inject: sample
>>> into: [ :accum :each | accum + (aBlock value: each) ].
>>> ^ sum - sample
>>
>>
>> Thanks! Missed that.
>>
>>>
>>> On Sun, Dec 20, 2015 at 8:59 AM, Max Leske <maxleske(a)gmail.com> wrote:
>>> I would like to wrap up this discussion.
>>>
>>>
>>>> On 05 Dec 2015, at 18:14, stepharo <stepharo(a)free.fr> wrote:
>>>>
>>>> So what is the conclusion?
>>>> I like the idea of Esteban M to have iterator because it moves some behavior out of core classes.
>>>>
>>>> [[[
>>>>
>>>> aCollection arithmetic sum: [...] or.... aCollection
>>>> arithmetic avg.
>>>>
>>>> ]]]
>>>>
>>>
>>> While I think that iterators are an intriguing idea I also believe that they are beyond the scope of this issue. If anybody wants to follow up on iterators (or unit types for that matter) please start a new thread / issue.
>>>
>>>
>>> I propose to use Svenâs version for #sum:ifEmpty:. The result would be these three methods:
>>>
>>> sum
>>> ^ self
>>> sum: [ :each | each ]
>>> ifEmpty: [ 0 ]
>>>
>>> sum: aBlock
>>> ^ self
>>> sum: aBlock
>>> ifEmpty: [ self errorEmptyCollection ]
>>>
>>> sum: aBlock ifEmpty: emptyBlock
>>> | sum sample |
>>> self isEmpty ifTrue: [ ^ emptyBlock value ].
>>> sample := self anyOne.
>>> sum := self
>>> inject: sample
>>> into: [ :accum :each | accum + (aBlock value: each) ].
>>> ^ sum - sample
>>>
>>>
>>> Iâve attached a couple of benchmark results below. To me they show that
>>> 1. the new implementation is maybe a tiny bit slower but insignificantly so (if youâre going for performance youâll probably write your own optimised version anyway)
>>> 2. there is no need to duplicate the code (like #sum and #sum: currently do). Itâs perfectly fine to delegate to #sum:ifEmpty:
>>>
>>>
>>>
>>> In addition to the above changes I would like to remove #detectSum: (-> #sum:) and #sumNumbers (-> #sum).
>>>
>>>
>>> Note that once we agree on changing this API, we will need to also change #detectMin:, #detectMax:, #min, #max as well as all overrides (e.g. RunArray, Interval) of these and of #sum et. al. to stay consistent. The changes would of course be in line with this change, such that every operation has a unary selector with a sensible default, one that takes a block and throws an error for empty collections and a third that takes a block for the iteration and one for the empty case.
>>>
>>>
>>> Please cast your vote for these changes:
>>>
>>> 1. Do you agree to changing #sum and #sum: in the suggested way?
>>>
>>> 2. Do you agree to the removal of #detectSum:?
>>>
>>> 3. Do you agree to the removal of #sumNumbers?
>>>
>>> 4. Do you agree that the #max and #min selectors also need to be adapted?
>>>
>>>
>>>
>>> Thanks for you help.
>>>
>>> Cheers,
>>> Max
>>>
>>>
>>>
>>>
>>>
>>> Benchmarks
>>> ============
>>> (Note that these arenât very good benchmarks. Thereâs quite some variation on each run.)
>>>
>>>
>>> Machine:
>>> MacBook Pro (15-inch, Early 2011)
>>> CPU: 2.2 GHz Intel Core i7
>>> Memory: 8 GB 1333 MHz DDR3
>>> Disk: APPLE SSD TS512C (500 GB)
>>>
>>>
>>> Benchmarks of the current versions:
>>>
>>> [ (1 to: 1000000) asArray sum ] benchFor: 10 seconds.
>>> 75 iterations, 7.470 per second
>>>
>>> [ (1 to: 1000000) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>> 72 iterations, 7.128 per second
>>>
>>>
>>> [ (1 to: 100) asArray sum ] benchFor: 10 seconds.
>>> 1,189,477 iterations, 118,912 per second
>>>
>>>
>>> [ (1 to: 100) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>> 1,171,467 iterations, 117,112 per second
>>>
>>>
>>>
>>> Benchmarks of the new versions:
>>>
>>> [ (1 to: 1000000) asArray sum ] benchFor: 10 seconds.
>>> 73 iterations, 7.244 per second
>>>
>>> [ (1 to: 1000000) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>> 75 iterations, 7.480 per second
>>>
>>> [ (1 to: 1000000) asArray sum: [ :e | e ] ifEmpty: [ 0 ] ] benchFor: 10 seconds.
>>> 72 iterations, 7.141 per second
>>>
>>>
>>> [ (1 to: 100) asArray sum ] benchFor: 10 seconds.
>>> 1,115,827 iterations, 111,560 per second
>>>
>>> [ (1 to: 100) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>> 1,154,595 iterations, 115,425 per second
>>>
>>> [ (1 to: 100) asArray sum: [ :e | e ] ifEmpty: [ 0 ] ] benchFor: 10 seconds.
>>> 1,102,358 iterations, 110,203 per second
>
> --
> www.tudorgirba.com
> www.feenk.com
>
> "There are no old things, there are only old ways of looking at them."
>
>
>
>
>
Dec. 20, 2015
Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:
by Tudor Girba
Hi,
> On Dec 20, 2015, at 2:30 PM, Max Leske <maxleske(a)gmail.com> wrote:
>
>
>> On 20 Dec 2015, at 14:10, Tudor Girba <tudor(a)tudorgirba.com> wrote:
>>
>> Hi,
>>
>> Could we not have sum, but sumNumbers instead? So, we would end up with:
>>
>> sum:ifEmpty:
>> sum: (with error)
>> sumNumbers (without error)
>>
>> From the outside, #sum: looks like it should parameterize #sum, but the implementation is actually different. So, given that in this implementation #sum is not a special case of #sum: the two should be named differently to reflect that difference. Hence my proposal is to keep #sumNumbers instead of #sum.
>
> I could live with that. We would sacrifice the beautiful selector #sum for the more intention revealing #sumNumbers. I think that makes sense.
>
> Concerning the #min and #max methods that means weâd end up with e.g. #minNumbers, #min: and #min:ifEmpty: etc.
Yes.
Doru
>
>>
>> Cheers,
>> Doru
>>
>>
>>> On Dec 20, 2015, at 1:47 PM, Max Leske <maxleske(a)gmail.com> wrote:
>>>
>>>>
>>>> On 20 Dec 2015, at 13:43, Gabriel Cotelli <g.cotelli(a)gmail.com> wrote:
>>>>
>>>> Max,
>>>>
>>>> sum: aBlock ifEmpty: emptyBlock needs to obtain the sample evaluating the block.
>>>>
>>>> sum: aBlock ifEmpty: emptyBlock
>>>> | sum sample |
>>>> self isEmpty ifTrue: [ ^ emptyBlock value ].
>>>> sample := aBlock value: self anyOne.
>>>> sum := self
>>>> inject: sample
>>>> into: [ :accum :each | accum + (aBlock value: each) ].
>>>> ^ sum - sample
>>>
>>>
>>> Thanks! Missed that.
>>>
>>>>
>>>> On Sun, Dec 20, 2015 at 8:59 AM, Max Leske <maxleske(a)gmail.com> wrote:
>>>> I would like to wrap up this discussion.
>>>>
>>>>
>>>>> On 05 Dec 2015, at 18:14, stepharo <stepharo(a)free.fr> wrote:
>>>>>
>>>>> So what is the conclusion?
>>>>> I like the idea of Esteban M to have iterator because it moves some behavior out of core classes.
>>>>>
>>>>> [[[
>>>>>
>>>>> aCollection arithmetic sum: [...] or.... aCollection
>>>>> arithmetic avg.
>>>>>
>>>>> ]]]
>>>>>
>>>>
>>>> While I think that iterators are an intriguing idea I also believe that they are beyond the scope of this issue. If anybody wants to follow up on iterators (or unit types for that matter) please start a new thread / issue.
>>>>
>>>>
>>>> I propose to use Svenâs version for #sum:ifEmpty:. The result would be these three methods:
>>>>
>>>> sum
>>>> ^ self
>>>> sum: [ :each | each ]
>>>> ifEmpty: [ 0 ]
>>>>
>>>> sum: aBlock
>>>> ^ self
>>>> sum: aBlock
>>>> ifEmpty: [ self errorEmptyCollection ]
>>>>
>>>> sum: aBlock ifEmpty: emptyBlock
>>>> | sum sample |
>>>> self isEmpty ifTrue: [ ^ emptyBlock value ].
>>>> sample := self anyOne.
>>>> sum := self
>>>> inject: sample
>>>> into: [ :accum :each | accum + (aBlock value: each) ].
>>>> ^ sum - sample
>>>>
>>>>
>>>> Iâve attached a couple of benchmark results below. To me they show that
>>>> 1. the new implementation is maybe a tiny bit slower but insignificantly so (if youâre going for performance youâll probably write your own optimised version anyway)
>>>> 2. there is no need to duplicate the code (like #sum and #sum: currently do). Itâs perfectly fine to delegate to #sum:ifEmpty:
>>>>
>>>>
>>>>
>>>> In addition to the above changes I would like to remove #detectSum: (-> #sum:) and #sumNumbers (-> #sum).
>>>>
>>>>
>>>> Note that once we agree on changing this API, we will need to also change #detectMin:, #detectMax:, #min, #max as well as all overrides (e.g. RunArray, Interval) of these and of #sum et. al. to stay consistent. The changes would of course be in line with this change, such that every operation has a unary selector with a sensible default, one that takes a block and throws an error for empty collections and a third that takes a block for the iteration and one for the empty case.
>>>>
>>>>
>>>> Please cast your vote for these changes:
>>>>
>>>> 1. Do you agree to changing #sum and #sum: in the suggested way?
>>>>
>>>> 2. Do you agree to the removal of #detectSum:?
>>>>
>>>> 3. Do you agree to the removal of #sumNumbers?
>>>>
>>>> 4. Do you agree that the #max and #min selectors also need to be adapted?
>>>>
>>>>
>>>>
>>>> Thanks for you help.
>>>>
>>>> Cheers,
>>>> Max
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> Benchmarks
>>>> ============
>>>> (Note that these arenât very good benchmarks. Thereâs quite some variation on each run.)
>>>>
>>>>
>>>> Machine:
>>>> MacBook Pro (15-inch, Early 2011)
>>>> CPU: 2.2 GHz Intel Core i7
>>>> Memory: 8 GB 1333 MHz DDR3
>>>> Disk: APPLE SSD TS512C (500 GB)
>>>>
>>>>
>>>> Benchmarks of the current versions:
>>>>
>>>> [ (1 to: 1000000) asArray sum ] benchFor: 10 seconds.
>>>> 75 iterations, 7.470 per second
>>>>
>>>> [ (1 to: 1000000) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>>> 72 iterations, 7.128 per second
>>>>
>>>>
>>>> [ (1 to: 100) asArray sum ] benchFor: 10 seconds.
>>>> 1,189,477 iterations, 118,912 per second
>>>>
>>>>
>>>> [ (1 to: 100) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>>> 1,171,467 iterations, 117,112 per second
>>>>
>>>>
>>>>
>>>> Benchmarks of the new versions:
>>>>
>>>> [ (1 to: 1000000) asArray sum ] benchFor: 10 seconds.
>>>> 73 iterations, 7.244 per second
>>>>
>>>> [ (1 to: 1000000) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>>> 75 iterations, 7.480 per second
>>>>
>>>> [ (1 to: 1000000) asArray sum: [ :e | e ] ifEmpty: [ 0 ] ] benchFor: 10 seconds.
>>>> 72 iterations, 7.141 per second
>>>>
>>>>
>>>> [ (1 to: 100) asArray sum ] benchFor: 10 seconds.
>>>> 1,115,827 iterations, 111,560 per second
>>>>
>>>> [ (1 to: 100) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>>> 1,154,595 iterations, 115,425 per second
>>>>
>>>> [ (1 to: 100) asArray sum: [ :e | e ] ifEmpty: [ 0 ] ] benchFor: 10 seconds.
>>>> 1,102,358 iterations, 110,203 per second
>>
>> --
>> www.tudorgirba.com
>> www.feenk.com
>>
>> "There are no old things, there are only old ways of looking at them."
>>
>>
>>
>>
>>
>
>
--
www.tudorgirba.com
www.feenk.com
"If you can't say why something is relevant,
it probably isn't."
Dec. 20, 2015
Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:
by Max Leske
> On 20 Dec 2015, at 14:10, Tudor Girba <tudor(a)tudorgirba.com> wrote:
>
> Hi,
>
> Could we not have sum, but sumNumbers instead? So, we would end up with:
>
> sum:ifEmpty:
> sum: (with error)
> sumNumbers (without error)
>
> From the outside, #sum: looks like it should parameterize #sum, but the implementation is actually different. So, given that in this implementation #sum is not a special case of #sum: the two should be named differently to reflect that difference. Hence my proposal is to keep #sumNumbers instead of #sum.
I could live with that. We would sacrifice the beautiful selector #sum for the more intention revealing #sumNumbers. I think that makes sense.
Concerning the #min and #max methods that means weâd end up with e.g. #minNumbers, #min: and #min:ifEmpty: etc.
>
> Cheers,
> Doru
>
>
>> On Dec 20, 2015, at 1:47 PM, Max Leske <maxleske(a)gmail.com> wrote:
>>
>>>
>>> On 20 Dec 2015, at 13:43, Gabriel Cotelli <g.cotelli(a)gmail.com> wrote:
>>>
>>> Max,
>>>
>>> sum: aBlock ifEmpty: emptyBlock needs to obtain the sample evaluating the block.
>>>
>>> sum: aBlock ifEmpty: emptyBlock
>>> | sum sample |
>>> self isEmpty ifTrue: [ ^ emptyBlock value ].
>>> sample := aBlock value: self anyOne.
>>> sum := self
>>> inject: sample
>>> into: [ :accum :each | accum + (aBlock value: each) ].
>>> ^ sum - sample
>>
>>
>> Thanks! Missed that.
>>
>>>
>>> On Sun, Dec 20, 2015 at 8:59 AM, Max Leske <maxleske(a)gmail.com> wrote:
>>> I would like to wrap up this discussion.
>>>
>>>
>>>> On 05 Dec 2015, at 18:14, stepharo <stepharo(a)free.fr> wrote:
>>>>
>>>> So what is the conclusion?
>>>> I like the idea of Esteban M to have iterator because it moves some behavior out of core classes.
>>>>
>>>> [[[
>>>>
>>>> aCollection arithmetic sum: [...] or.... aCollection
>>>> arithmetic avg.
>>>>
>>>> ]]]
>>>>
>>>
>>> While I think that iterators are an intriguing idea I also believe that they are beyond the scope of this issue. If anybody wants to follow up on iterators (or unit types for that matter) please start a new thread / issue.
>>>
>>>
>>> I propose to use Svenâs version for #sum:ifEmpty:. The result would be these three methods:
>>>
>>> sum
>>> ^ self
>>> sum: [ :each | each ]
>>> ifEmpty: [ 0 ]
>>>
>>> sum: aBlock
>>> ^ self
>>> sum: aBlock
>>> ifEmpty: [ self errorEmptyCollection ]
>>>
>>> sum: aBlock ifEmpty: emptyBlock
>>> | sum sample |
>>> self isEmpty ifTrue: [ ^ emptyBlock value ].
>>> sample := self anyOne.
>>> sum := self
>>> inject: sample
>>> into: [ :accum :each | accum + (aBlock value: each) ].
>>> ^ sum - sample
>>>
>>>
>>> Iâve attached a couple of benchmark results below. To me they show that
>>> 1. the new implementation is maybe a tiny bit slower but insignificantly so (if youâre going for performance youâll probably write your own optimised version anyway)
>>> 2. there is no need to duplicate the code (like #sum and #sum: currently do). Itâs perfectly fine to delegate to #sum:ifEmpty:
>>>
>>>
>>>
>>> In addition to the above changes I would like to remove #detectSum: (-> #sum:) and #sumNumbers (-> #sum).
>>>
>>>
>>> Note that once we agree on changing this API, we will need to also change #detectMin:, #detectMax:, #min, #max as well as all overrides (e.g. RunArray, Interval) of these and of #sum et. al. to stay consistent. The changes would of course be in line with this change, such that every operation has a unary selector with a sensible default, one that takes a block and throws an error for empty collections and a third that takes a block for the iteration and one for the empty case.
>>>
>>>
>>> Please cast your vote for these changes:
>>>
>>> 1. Do you agree to changing #sum and #sum: in the suggested way?
>>>
>>> 2. Do you agree to the removal of #detectSum:?
>>>
>>> 3. Do you agree to the removal of #sumNumbers?
>>>
>>> 4. Do you agree that the #max and #min selectors also need to be adapted?
>>>
>>>
>>>
>>> Thanks for you help.
>>>
>>> Cheers,
>>> Max
>>>
>>>
>>>
>>>
>>>
>>> Benchmarks
>>> ============
>>> (Note that these arenât very good benchmarks. Thereâs quite some variation on each run.)
>>>
>>>
>>> Machine:
>>> MacBook Pro (15-inch, Early 2011)
>>> CPU: 2.2 GHz Intel Core i7
>>> Memory: 8 GB 1333 MHz DDR3
>>> Disk: APPLE SSD TS512C (500 GB)
>>>
>>>
>>> Benchmarks of the current versions:
>>>
>>> [ (1 to: 1000000) asArray sum ] benchFor: 10 seconds.
>>> 75 iterations, 7.470 per second
>>>
>>> [ (1 to: 1000000) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>> 72 iterations, 7.128 per second
>>>
>>>
>>> [ (1 to: 100) asArray sum ] benchFor: 10 seconds.
>>> 1,189,477 iterations, 118,912 per second
>>>
>>>
>>> [ (1 to: 100) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>> 1,171,467 iterations, 117,112 per second
>>>
>>>
>>>
>>> Benchmarks of the new versions:
>>>
>>> [ (1 to: 1000000) asArray sum ] benchFor: 10 seconds.
>>> 73 iterations, 7.244 per second
>>>
>>> [ (1 to: 1000000) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>> 75 iterations, 7.480 per second
>>>
>>> [ (1 to: 1000000) asArray sum: [ :e | e ] ifEmpty: [ 0 ] ] benchFor: 10 seconds.
>>> 72 iterations, 7.141 per second
>>>
>>>
>>> [ (1 to: 100) asArray sum ] benchFor: 10 seconds.
>>> 1,115,827 iterations, 111,560 per second
>>>
>>> [ (1 to: 100) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>> 1,154,595 iterations, 115,425 per second
>>>
>>> [ (1 to: 100) asArray sum: [ :e | e ] ifEmpty: [ 0 ] ] benchFor: 10 seconds.
>>> 1,102,358 iterations, 110,203 per second
>
> --
> www.tudorgirba.com
> www.feenk.com
>
> "There are no old things, there are only old ways of looking at them."
>
>
>
>
>
Dec. 20, 2015