Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2016-01-15 Thread Max Leske
Ok. So while the “decorator” approach looks fantastic it will obviously have 
its own drawbacks.

Discussing this on the mailing list is very tiering, so I suggest that this 
should be discussed during the next sprint or Pharo days. Since I will not be 
able to attend either one, can I ask one of you to take responsibility for 
this? Sven or Doru maybe?

Cheers,
Max

> On 11 Jan 2016, at 08:10, Sven Van Caekenberghe  wrote:
> 
> 
>> On 08 Jan 2016, at 21:15, stepharo  wrote:
>> 
>> Sven
>> 
>> may be should do the following:
>>   - introduce the best solution (not using your and henrik decomposition)
>>   - continue to think about it.
> 
> There is no intermediary solution, we'll continue to think about it.
> 
>> I would like to see if Xtreams does not go in the same direction too. But I 
>> do not have the code at hand to think about it.
> 
> Xtreams does not solve the problem either, I think.
> 
> The key question is: can you write operations on objects, generic containers 
> of element objects, that depend on the fact that the element objects are of a 
> certain type (or protocol), but that might fail and make completely no sense 
> for others.
> 
> Consider the 'data get/put' category on PositionalStream with operations like 
> #int32 and #int32: - these assume that this are byte streams. But in my book, 
> streams can be anything, colors, records, points, fonts, ... 
> 
>> Stef
> 
> 




Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2016-01-08 Thread stepharo

Sven

may be should do the following:
- introduce the best solution (not using your and henrik decomposition)
- continue to think about it.

I would like to see if Xtreams does not go in the same direction too. 
But I do not have the code at hand to think about it.


Stef



Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2016-01-07 Thread Sven Van Caekenberghe
Thanks for the (positive) feedback.

My problem is: if you think this through, lots of things could change. 

Consider that I added #magnitudes this would imply that sorting should move 
too, because you cannot assume the objects to be sortable (i.e. Magnitudes or 
conforming to that protocol).

Also, this would create a kind of parallel hierarchy, with more type 
information. It feels like a simple single inheritance hierarchy cannot cover 
all combinations (for example, being sequenceable and being numbers, as opposed 
to being just a collection of numbers).

Sorting an unordered collection is also different from sorting an ordered one 
(this last one could keep its type, or even be sorted in place).

So maybe this is a can of worms. I am all for dynamic typing, not for trying to 
add some (weak) for of static typing.

> On 07 Jan 2016, at 13:14, Max Leske <maxle...@gmail.com> wrote:
> 
> Very, very cool Sven (and Henrik!)!
> 
> And it even works with exotic objects: { 1@2. 2@3 } numbers sum “—> (3@5)”
> 
> Could Collections-Arithmetic be integrated into the collections operations? 
> Not really sure that’s a good idea, I just want to know.
> 
> Cheers,
> Max
> 
>> On 04 Jan 2016, at 16:19, Tudor Girba <tu...@tudorgirba.com> wrote:
>> 
>> Thank you, Sven!
>> 
>> I like this very much.
>> 
>> This would also mean that we could deprecate Collection>>#sum altogether :))
>> 
>> Cheers,
>> Doru
>> 
>> 
>>> On Dec 30, 2015, at 12:53 AM, Sven Van Caekenberghe <s...@stfx.eu> wrote:
>>> 
>>> Hi Henrik,
>>> 
>>>> On 25 Dec 2015, at 14:08, Henrik Nergaard <henri...@student.uia.no> wrote:
>>>> 
>>>> Like this?
>>>> http://smalltalkhub.com/#!/~Latsabben/NumIt
>>> 
>>> That is a cool take on a possible approach. Thanks for doing it, it makes 
>>> it much easier to think about and discuss alternatives.
>>> 
>>> This inspired me to do something similar, but not quite. I am just thinking 
>>> out loud by implementation. Here is my result:
>>> 
>>> 
>>> 
>>> There are some examples in the class comments.
>>> 
>>> Sven
>>> 
>>>> Best regards,
>>>> Henrik
>>>> 
>>>> -Original Message-
>>>> From: Pharo-dev [mailto:pharo-dev-boun...@lists.pharo.org] On Behalf Of 
>>>> stepharo
>>>> Sent: Thursday, December 24, 2015 9:58 AM
>>>> To: Pharo Development List <pharo-dev@lists.pharo.org>
>>>> Subject: Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:
>>>> 
>>>> Just a remark.
>>>> I think that we discarded the proposition of having
>>>> 
>>>> aCol arithmetic sum
>>>> 
>>>> but I found it nice because there if was clear that you want to get back 
>>>> 0 for #().
>>>> 
>>>> Stef
>>>> 
>>> 
>> 
>> --
>> www.tudorgirba.com
>> www.feenk.com
>> 
>> "Innovation comes in the least expected form. 
>> That is, if it is expected, it already happened."
>> 
>> 
> 
> 




Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2016-01-07 Thread Denis Kudriashov
2016-01-07 13:14 GMT+01:00 Max Leske :

> Very, very cool Sven (and Henrik!)!
>
> And it even works with exotic objects: { 1@2. 2@3 } numbers sum “—> (3@5)”
>

I really not understand how it helps with original problem. There was
example with colors sum which was stop people to allow sum on empty
collection. How extra message solve it?


Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2016-01-07 Thread Ben Coman
On Mon, Jan 4, 2016 at 10:55 PM, Guillermo Polito
<guillermopol...@gmail.com> wrote:
> I like these last.
>
> Particularly because
>
>  - it cleans the collection’s API
>  - we can continue extending this idea to add parallelism, mutual exclusion...

I don't understand the second point.

>
>
>> On 29 dic 2015, at 11:53 p.m., Sven Van Caekenberghe <s...@stfx.eu> wrote:
>>
>> Hi Henrik,
>>
>>> On 25 Dec 2015, at 14:08, Henrik Nergaard <henri...@student.uia.no> wrote:
>>>
>>> Like this?
>>> http://smalltalkhub.com/#!/~Latsabben/NumIt
>>
>> That is a cool take on a possible approach. Thanks for doing it, it makes it 
>> much easier to think about and discuss alternatives.
>>
>> This inspired me to do something similar, but not quite. I am just thinking 
>> out loud by implementation. Here is my result:
>>
>> 

Interesting to great enthusiasm from several people.  Looks like I'm
in the minority but I'm wary of this.  It seems like
over-intellectualized design.  I'll need to remember whether to send
#magnitude or #numbers before an operation and which matches up with
which operations.  This seems harder for newcomers.  Are there any
other programming languages that do it this way?

>>
>> There are some examples in the class comments.

Class comment says CollectionOperations is "a class that offers
extended API to operate on collections assumed to contain objects of a
certain type."

>>1. CollectionOperations
>>2.   OperationsOnMagnitudes
>>3. OperationsOnNumbers
>>4.OperationsOnSequenceableNumbers

So 2 & 3 refer to the elements of the collection, so 4 makes me wonder
what elements are sequence-able numbers?   So 4 breaks the pattern to
refer to the type of collection not just the type of element.

Why is #average defined for OperationsOnNumbers rather than
OperationsOnMagnitudes? If I have a collection of magnitudes like Time
"17:28 . 17:29 . 17:31 . 17:32" or Duration "4 minutes . 6 minutes"
I would expect to be able to get 17:30 and 5 minutes as the respective
averages.
But then it doesn't make sense to average other magnitudes like
Character, so where does that leave us?

Also I'd like to sum Durations but its not defined for OperationsOnMagnitudes.

I guess I fear there is hidden complexity for little gain.   Maybe
those that like the idea can collaborate on a package they use on
their own projects to work out the kinks.

cheers -ben

>>
>> Sven
>>
>>> Best regards,
>>> Henrik
>>>
>>> -Original Message-
>>> From: Pharo-dev [mailto:pharo-dev-boun...@lists.pharo.org] On Behalf Of 
>>> stepharo
>>> Sent: Thursday, December 24, 2015 9:58 AM
>>> To: Pharo Development List <pharo-dev@lists.pharo.org>
>>> Subject: Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:
>>>
>>> Just a remark.
>>> I think that we discarded the proposition of having
>>>
>>> aCol arithmetic sum
>>>
>>> but I found it nice because there if was clear that you want to get back
>>> 0 for #().
>>>
>>> Stef
>>>
>>
>
>



Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2016-01-07 Thread Guillermo Polito
gt; refer to the type of collection not just the type of element.
> >>
> >> Yes, that is a problem, it feels wrong. There are several dimensions
> that cannot be captured in one simple hierarchy.
> >>
> >>> Why is #average defined for OperationsOnNumbers rather than
> >>> OperationsOnMagnitudes? If I have a collection of magnitudes like Time
> >>> "17:28 . 17:29 . 17:31 . 17:32" or Duration "4 minutes . 6 minutes"
> >>> I would expect to be able to get 17:30 and 5 minutes as the respective
> >>> averages.
> >>> But then it doesn't make sense to average other magnitudes like
> >>> Character, so where does that leave us?
> >>
> >> You are wrong, a Magnitude is only comparable, it does not mean it can
> do arithmetic. You need arithmetic to compute average.
> >>
> >> In this case, you could use #numbers to indicate that you see your
> objects as compatible with that (and the time objects mostly are).
> >>
> >> But summing an empty collection of Durations, you would probably want
> Duration zero to be the result, and then we are back to our original
> problem ;-)
> >>
> >>> Also I'd like to sum Durations but its not defined for
> OperationsOnMagnitudes.
> >>>
> >>> I guess I fear there is hidden complexity for little gain.   Maybe
> >>> those that like the idea can collaborate on a package they use on
> >>> their own projects to work out the kinks.
> >>>
> >>> cheers -ben
> >>>
> >>>>>
> >>>>> Sven
> >>>>>
> >>>>>> Best regards,
> >>>>>> Henrik
> >>>>>>
> >>>>>> -Original Message-
> >>>>>> From: Pharo-dev [mailto:pharo-dev-boun...@lists.pharo.org] On
> Behalf Of stepharo
> >>>>>> Sent: Thursday, December 24, 2015 9:58 AM
> >>>>>> To: Pharo Development List <pharo-dev@lists.pharo.org>
> >>>>>> Subject: Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:
> >>>>>>
> >>>>>> Just a remark.
> >>>>>> I think that we discarded the proposition of having
> >>>>>>
> >>>>>> aCol arithmetic sum
> >>>>>>
> >>>>>> but I found it nice because there if was clear that you want to get
> back
> >>>>>> 0 for #().
> >>>>>>
> >>>>>> Stef
>
>
>


Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2016-01-07 Thread Ben Coman
On Thu, Jan 7, 2016 at 9:40 PM, Sven Van Caekenberghe <s...@stfx.eu> wrote:
>
>> On 07 Jan 2016, at 14:23, Ben Coman <b...@openinworld.com> wrote:
>>
>> On Mon, Jan 4, 2016 at 10:55 PM, Guillermo Polito
>> <guillermopol...@gmail.com> wrote:
>>> I like these last.
>>>
>>> Particularly because
>>>
>>> - it cleans the collection’s API
>>> - we can continue extending this idea to add parallelism, mutual 
>>> exclusion...
>>
>> I don't understand the second point.
>
> Wrapping an object in another to add behaviour is a standard technique (as 
> opposed to adding the behaviour to the object itself). There can be several 
> reasons for doing this. It is not necessarily or always a good idea either 
> (for example, extension protocols are nice too).

> "standard technique"

Does it have a pattern name?, that I could look up to learn more (btw
I have Design Patterns Smalltalk Companion - but its hard to remember
them without using them in practice.) ?

cheers -ben

>
>>>> On 29 dic 2015, at 11:53 p.m., Sven Van Caekenberghe <s...@stfx.eu> wrote:
>>>>
>>>> Hi Henrik,
>>>>
>>>>> On 25 Dec 2015, at 14:08, Henrik Nergaard <henri...@student.uia.no> wrote:
>>>>>
>>>>> Like this?
>>>>> http://smalltalkhub.com/#!/~Latsabben/NumIt
>>>>
>>>> That is a cool take on a possible approach. Thanks for doing it, it makes 
>>>> it much easier to think about and discuss alternatives.
>>>>
>>>> This inspired me to do something similar, but not quite. I am just 
>>>> thinking out loud by implementation. Here is my result:
>>>>
>>>> 
>>
>> Interesting to great enthusiasm from several people.  Looks like I'm
>> in the minority but I'm wary of this.  It seems like
>> over-intellectualized design.
>
> Yes, maybe ;-)
>
>> I'll need to remember whether to send
>> #magnitude or #numbers before an operation and which matches up with
>> which operations.  This seems harder for newcomers.
>
> #(1 2 foo true false) sum => ?
> #() sum => ?
> { window1. window2. window3 } max => ?
>
>> Are there any other programming languages that do it this way?
>
> There are not so many fully dynamic languages with non-homogeneous 
> collections. Most languages have static typing and generic types (both are 
> not what we want). But I would love to see how comparable languages solve 
> this 'problem'.
>
> Most language won't allow (or don't define) operations on collections that 
> could fail because of the fact that they contain the wrong objects.
>
> Having said that, I am not saying that I want to move away from our 
> flexibility/simplicity !
>
>>>>
>>>> There are some examples in the class comments.
>>
>> Class comment says CollectionOperations is "a class that offers
>> extended API to operate on collections assumed to contain objects of a
>> certain type."
>>
>>>> 1. CollectionOperations
>>>> 2.   OperationsOnMagnitudes
>>>> 3. OperationsOnNumbers
>>>> 4.OperationsOnSequenceableNumbers
>>
>> So 2 & 3 refer to the elements of the collection, so 4 makes me wonder
>> what elements are sequence-able numbers?   So 4 breaks the pattern to
>> refer to the type of collection not just the type of element.
>
> Yes, that is a problem, it feels wrong. There are several dimensions that 
> cannot be captured in one simple hierarchy.
>
>> Why is #average defined for OperationsOnNumbers rather than
>> OperationsOnMagnitudes? If I have a collection of magnitudes like Time
>> "17:28 . 17:29 . 17:31 . 17:32" or Duration "4 minutes . 6 minutes"
>> I would expect to be able to get 17:30 and 5 minutes as the respective
>> averages.
>> But then it doesn't make sense to average other magnitudes like
>> Character, so where does that leave us?
>
> You are wrong, a Magnitude is only comparable, it does not mean it can do 
> arithmetic. You need arithmetic to compute average.
>
> In this case, you could use #numbers to indicate that you see your objects as 
> compatible with that (and the time objects mostly are).
>
> But summing an empty collection of Durations, you would probably want 
> Duration zero to be the result, and then we are back to our original problem 
> ;-)
>
>> Also I'd like to sum Durations but its not defined for 
>> OperationsOnMagnitudes.
>>
>> I guess I fear there is hidden complexity for little gain.   Maybe
>> those that like the idea can collaborate on a package they use on
>> their own projects to work out the kinks.
>>
>> cheers -ben
>>
>>>>
>>>> Sven
>>>>
>>>>> Best regards,
>>>>> Henrik
>>>>>
>>>>> -Original Message-
>>>>> From: Pharo-dev [mailto:pharo-dev-boun...@lists.pharo.org] On Behalf Of 
>>>>> stepharo
>>>>> Sent: Thursday, December 24, 2015 9:58 AM
>>>>> To: Pharo Development List <pharo-dev@lists.pharo.org>
>>>>> Subject: Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:
>>>>>
>>>>> Just a remark.
>>>>> I think that we discarded the proposition of having
>>>>>
>>>>> aCol arithmetic sum
>>>>>
>>>>> but I found it nice because there if was clear that you want to get back
>>>>> 0 for #().
>>>>>
>>>>> Stef
>
>



Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2016-01-04 Thread Guillermo Polito
I like these last.

Particularly because 

 - it cleans the collection’s API
 - we can continue extending this idea to add parallelism, mutual exclusion...


> On 29 dic 2015, at 11:53 p.m., Sven Van Caekenberghe <s...@stfx.eu> wrote:
> 
> Hi Henrik,
> 
>> On 25 Dec 2015, at 14:08, Henrik Nergaard <henri...@student.uia.no> wrote:
>> 
>> Like this?
>> http://smalltalkhub.com/#!/~Latsabben/NumIt
> 
> That is a cool take on a possible approach. Thanks for doing it, it makes it 
> much easier to think about and discuss alternatives.
> 
> This inspired me to do something similar, but not quite. I am just thinking 
> out loud by implementation. Here is my result:
> 
> 
> 
> There are some examples in the class comments.
> 
> Sven
> 
>> Best regards,
>> Henrik
>> 
>> -Original Message-
>> From: Pharo-dev [mailto:pharo-dev-boun...@lists.pharo.org] On Behalf Of 
>> stepharo
>> Sent: Thursday, December 24, 2015 9:58 AM
>> To: Pharo Development List <pharo-dev@lists.pharo.org>
>> Subject: Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:
>> 
>> Just a remark.
>> I think that we discarded the proposition of having
>> 
>> aCol arithmetic sum
>> 
>> but I found it nice because there if was clear that you want to get back 
>> 0 for #().
>> 
>> Stef
>> 
> 




Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2016-01-04 Thread Tudor Girba
Thank you, Sven!

I like this very much.

This would also mean that we could deprecate Collection>>#sum altogether :))

Cheers,
Doru


> On Dec 30, 2015, at 12:53 AM, Sven Van Caekenberghe <s...@stfx.eu> wrote:
> 
> Hi Henrik,
> 
>> On 25 Dec 2015, at 14:08, Henrik Nergaard <henri...@student.uia.no> wrote:
>> 
>> Like this?
>> http://smalltalkhub.com/#!/~Latsabben/NumIt
> 
> That is a cool take on a possible approach. Thanks for doing it, it makes it 
> much easier to think about and discuss alternatives.
> 
> This inspired me to do something similar, but not quite. I am just thinking 
> out loud by implementation. Here is my result:
> 
> 
> 
> There are some examples in the class comments.
> 
> Sven
> 
>> Best regards,
>> Henrik
>> 
>> -Original Message-
>> From: Pharo-dev [mailto:pharo-dev-boun...@lists.pharo.org] On Behalf Of 
>> stepharo
>> Sent: Thursday, December 24, 2015 9:58 AM
>> To: Pharo Development List <pharo-dev@lists.pharo.org>
>> Subject: Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:
>> 
>> Just a remark.
>> I think that we discarded the proposition of having
>> 
>> aCol arithmetic sum
>> 
>> but I found it nice because there if was clear that you want to get back 
>> 0 for #().
>> 
>> Stef
>> 
> 

--
www.tudorgirba.com
www.feenk.com

"Innovation comes in the least expected form. 
That is, if it is expected, it already happened."




Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-29 Thread Sven Van Caekenberghe
Hi Henrik,

> On 25 Dec 2015, at 14:08, Henrik Nergaard <henri...@student.uia.no> wrote:
> 
> Like this?
> http://smalltalkhub.com/#!/~Latsabben/NumIt

That is a cool take on a possible approach. Thanks for doing it, it makes it 
much easier to think about and discuss alternatives.

This inspired me to do something similar, but not quite. I am just thinking out 
loud by implementation. Here is my result:



Collections-Operations-SvenVanCaekenberghe.1.mcz
Description: Binary data


There are some examples in the class comments.

Sven

> Best regards,
> Henrik
> 
> -Original Message-
> From: Pharo-dev [mailto:pharo-dev-boun...@lists.pharo.org] On Behalf Of 
> stepharo
> Sent: Thursday, December 24, 2015 9:58 AM
> To: Pharo Development List <pharo-dev@lists.pharo.org>
> Subject: Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:
> 
> Just a remark.
> I think that we discarded the proposition of having
> 
> aCol arithmetic sum
> 
> but I found it nice because there if was clear that you want to get back 
> 0 for #().
> 
> Stef
> 



Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-28 Thread Eliot Miranda


> On Dec 27, 2015, at 1:52 PM, Nicolas Cellier 
>  wrote:
> 
> 
> 
> 2015-12-27 2:49 GMT+01:00 Ben Coman :
>> On Sun, Dec 27, 2015 at 6:13 AM, Nicolas Cellier
>>  wrote:
>> >
>> >
>> > 2015-12-25 2:03 GMT+01:00 Eliot Miranda :
>> >>
>> >> Ben,
>> >>
>> >> _,,,^..^,,,_ (phone)
>> >>
>> >> > On Dec 4, 2015, at 12:49 AM, Ben Coman  wrote:
>> >> >
>> >> >> On Fri, Dec 4, 2015 at 4:23 AM, Nicolai Hess 
>> >> >> wrote:
>> >> >>
>> >> >>
>> >> >> 2015-12-03 14:48 GMT+01:00 Ben Coman :
>> >> >>>
>> >> >>> On Wed, Dec 2, 2015 at 10:45 PM, Sven Van Caekenberghe 
>> >> >>> wrote:
>> >> 
>> >> > On 02 Dec 2015, at 15:21, Nicolai Hess 
>> >> > wrote:
>> >> >
>> >> >
>> >> >
>> >> > 2015-12-02 15:03 GMT+01:00 Ben Coman :
>> >> > On Wed, Dec 2, 2015 at 12:38 AM, Tudor Girba 
>> >> > wrote:
>> >> >> Hi,
>> >> >>
>> >> >>> On Dec 1, 2015, at 5:13 PM, Max Leske  wrote:
>> >> >>>
>> >> >>> @Doru
>> >> >>> You’re missing the point: #anyOne *fails* for empty collections.
>> >> >>
>> >> >> I am not missing the point at all. I am saying that if you want
>> >> >> sum:
>> >> >> to be generic, it cannot assume a specific Zero object.
>> >> >>
>> >> >> And sum: should be generic because of its name.
>> >> >
>> >> > I am missing understanding the other use cases.  Can you describe
>> >> > further the generic nature of #sum & #sum: ?  I would have thought
>> >> > by
>> >> > default they only applied to numbers.
>> >> >
>> >> > sum can be applied to anything that supports #+, not only numbers
>> >> > sum: can be applied to any collection with a block that return some
>> >> > object that supports #+
>> >> >>>
>> >> >>> To me this is a mis-application of polymorphism, that just because
>> >> >>> something responds to #+ it should be summable. We have overloaded the
>> >> >>> semantics of  #+  to mean both numeric addition and
>> >> >>> concatenation/membership, but technically "summation" relates only to
>> >> >>> numeric addition.
>> >> >>
>> >> >>
>> >> >> I didn't wanted to argue for or against any change. I just wanted to
>> >> >> clarify
>> >> >> that there are situations in which a generic sum/sum: that throws an
>> >> >> error
>> >> >> on empty collections and don't assume a null value makes sense.
>> >> >>
>> >> >>
>> >> >>>
>> >> >>>
>> >> >>> https://www.google.com.au/search?q=define+sum=define+sum
>> >> >>>
>> >> >>>
>> >> >>> https://www.google.com.au/search?q=define+concatenate=define+concatenate
>> >> >>>
>> >> >>> For example...
>> >> >>>
>> >> >>> * KMModifier implements  #+  so what is the expected semantic of   " {
>> >> >>> KMModifier shift . KMModifier meta} sum " ?
>> >> >>> To me this is more of a concatenation/join/union facility rather than
>> >> >>> numeric addition.  (btw, that expression actually fails since
>> >> >>> KMModifier does not understand minus #- ) .
>> >> >>>
>> >> >>> * String implements  #+  and  " { '1' . '2' } sum " --> '3',   so
>> >> >>> actually its doing numeric addition.  However  " { 'a' . 'b' } sum "
>> >> >>> produces an error.
>> >> >>>
>> >> >>> So actually there seem some existing problems with summing
>> >> >>> non-numerics.  What examples work?
>> >> >>>
>> >> >>> * Trait classes implement both  #+  and  #- , but the semantic seems
>> >> >>> more to do with membership than numeric addition.  I don't how how to
>> >> >>> produce an example of using #sum against traits.
>> >> >>>
>> >> >>> * Points are summable  " { 2@2 . 3@3 } " --> 5@5.   But then  " 2@2 +
>> >> >>> 1 " --> 3@3   ,   so  " {} sum "  returning  0  would seem to not
>> >> >>> cause any error in this case.
>> >> >>>
>> >> >>>
>> >> >>> cheers -ben
>> >> >>>
>> >> >>>
>> >> >
>> >> > therefore you can not assume 0 (<- a number) is a proper initial
>> >> > value
>> >> > therefore you *need* to work with #anyOne
>> >> > and as you can not assume a proper initial value, you can not assume
>> >> > a
>> >> > default value for empty collections
>> >> > -> it should throw an error. If you (the caller of the function)
>> >> > knows
>> >> > what to do with an empty collection you have
>> >> > to check, or call inject:into: directly, with a proper initial
>> >> > value.
>> >> 
>> >>  I am sorry but I am getting really tired of this, you should read
>> >>  what
>> >>  is being said.
>> >> >>
>> >> >>
>> >> >> do that change, I am not against it. Ben just asked for an example and
>> >> >> I
>> >> >> thought it would be helpful.
>> >> >
>> >> > It was helpful :)  It evolved my thinking.   Now thinking further, I
>> >> > wonder how returning  0  will work with 

Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-28 Thread Sven Van Caekenberghe
Well, I beg to disagree, #sum on an empty collection should return 0.

https://en.wikipedia.org/wiki/Empty_sum

We do not need more tricks, the current trick with #anyOne is more than enough, 
that is not the problem. 

The problem is that it is impossible to talk about sum (in the general most 
common sense) without assuming that the collection should have contained 
numbers, where 0 is the neutral element.

The #anyOne trick solves the problem of the neutral element for non empty 
collection, but leaves it unsolved for empty collections. 

Defining it so that empty collections error is really silly: check the senders, 
most of them are then forced to check before calling #sum. In that case, they 
could all just as well have used #inject:into: for the same amount of code.

> On 28 Dec 2015, at 21:08, Eliot Miranda  wrote:
> 
> 
> 
> On Dec 27, 2015, at 1:52 PM, Nicolas Cellier 
>  wrote:
> 
>> 
>> 
>> 2015-12-27 2:49 GMT+01:00 Ben Coman :
>> On Sun, Dec 27, 2015 at 6:13 AM, Nicolas Cellier
>>  wrote:
>> >
>> >
>> > 2015-12-25 2:03 GMT+01:00 Eliot Miranda :
>> >>
>> >> Ben,
>> >>
>> >> _,,,^..^,,,_ (phone)
>> >>
>> >> > On Dec 4, 2015, at 12:49 AM, Ben Coman  wrote:
>> >> >
>> >> >> On Fri, Dec 4, 2015 at 4:23 AM, Nicolai Hess 
>> >> >> wrote:
>> >> >>
>> >> >>
>> >> >> 2015-12-03 14:48 GMT+01:00 Ben Coman :
>> >> >>>
>> >> >>> On Wed, Dec 2, 2015 at 10:45 PM, Sven Van Caekenberghe 
>> >> >>> wrote:
>> >> 
>> >> > On 02 Dec 2015, at 15:21, Nicolai Hess 
>> >> > wrote:
>> >> >
>> >> >
>> >> >
>> >> > 2015-12-02 15:03 GMT+01:00 Ben Coman :
>> >> > On Wed, Dec 2, 2015 at 12:38 AM, Tudor Girba 
>> >> > wrote:
>> >> >> Hi,
>> >> >>
>> >> >>> On Dec 1, 2015, at 5:13 PM, Max Leske  wrote:
>> >> >>>
>> >> >>> @Doru
>> >> >>> You’re missing the point: #anyOne *fails* for empty collections.
>> >> >>
>> >> >> I am not missing the point at all. I am saying that if you want
>> >> >> sum:
>> >> >> to be generic, it cannot assume a specific Zero object.
>> >> >>
>> >> >> And sum: should be generic because of its name.
>> >> >
>> >> > I am missing understanding the other use cases.  Can you describe
>> >> > further the generic nature of #sum & #sum: ?  I would have thought
>> >> > by
>> >> > default they only applied to numbers.
>> >> >
>> >> > sum can be applied to anything that supports #+, not only numbers
>> >> > sum: can be applied to any collection with a block that return some
>> >> > object that supports #+
>> >> >>>
>> >> >>> To me this is a mis-application of polymorphism, that just because
>> >> >>> something responds to #+ it should be summable. We have overloaded the
>> >> >>> semantics of  #+  to mean both numeric addition and
>> >> >>> concatenation/membership, but technically "summation" relates only to
>> >> >>> numeric addition.
>> >> >>
>> >> >>
>> >> >> I didn't wanted to argue for or against any change. I just wanted to
>> >> >> clarify
>> >> >> that there are situations in which a generic sum/sum: that throws an
>> >> >> error
>> >> >> on empty collections and don't assume a null value makes sense.
>> >> >>
>> >> >>
>> >> >>>
>> >> >>>
>> >> >>> https://www.google.com.au/search?q=define+sum=define+sum
>> >> >>>
>> >> >>>
>> >> >>> https://www.google.com.au/search?q=define+concatenate=define+concatenate
>> >> >>>
>> >> >>> For example...
>> >> >>>
>> >> >>> * KMModifier implements  #+  so what is the expected semantic of   " {
>> >> >>> KMModifier shift . KMModifier meta} sum " ?
>> >> >>> To me this is more of a concatenation/join/union facility rather than
>> >> >>> numeric addition.  (btw, that expression actually fails since
>> >> >>> KMModifier does not understand minus #- ) .
>> >> >>>
>> >> >>> * String implements  #+  and  " { '1' . '2' } sum " --> '3',   so
>> >> >>> actually its doing numeric addition.  However  " { 'a' . 'b' } sum "
>> >> >>> produces an error.
>> >> >>>
>> >> >>> So actually there seem some existing problems with summing
>> >> >>> non-numerics.  What examples work?
>> >> >>>
>> >> >>> * Trait classes implement both  #+  and  #- , but the semantic seems
>> >> >>> more to do with membership than numeric addition.  I don't how how to
>> >> >>> produce an example of using #sum against traits.
>> >> >>>
>> >> >>> * Points are summable  " { 2@2 . 3@3 } " --> 5@5.   But then  " 2@2 +
>> >> >>> 1 " --> 3@3   ,   so  " {} sum "  returning  0  would seem to not
>> >> >>> cause any error in this case.
>> >> >>>
>> >> >>>
>> >> >>> cheers -ben
>> >> >>>
>> >> >>>
>> >> >
>> >> > therefore you can not assume 0 (<- a number) is a proper initial
>> >> 

Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-28 Thread Robert Withers

This is sounding like a type inference situation.

On 12/28/2015 03:20 PM, Sven Van Caekenberghe wrote:

Well, I beg to disagree, #sum on an empty collection should return 0.

https://en.wikipedia.org/wiki/Empty_sum

We do not need more tricks, the current trick with #anyOne is more than enough, 
that is not the problem.

The problem is that it is impossible to talk about sum (in the general most 
common sense) without assuming that the collection should have contained 
numbers, where 0 is the neutral element.

The #anyOne trick solves the problem of the neutral element for non empty 
collection, but leaves it unsolved for empty collections.

Defining it so that empty collections error is really silly: check the senders, 
most of them are then forced to check before calling #sum. In that case, they 
could all just as well have used #inject:into: for the same amount of code.


On 28 Dec 2015, at 21:08, Eliot Miranda  wrote:



On Dec 27, 2015, at 1:52 PM, Nicolas Cellier 
 wrote:



2015-12-27 2:49 GMT+01:00 Ben Coman :
On Sun, Dec 27, 2015 at 6:13 AM, Nicolas Cellier
 wrote:


2015-12-25 2:03 GMT+01:00 Eliot Miranda :

Ben,

_,,,^..^,,,_ (phone)


On Dec 4, 2015, at 12:49 AM, Ben Coman  wrote:


On Fri, Dec 4, 2015 at 4:23 AM, Nicolai Hess 
wrote:


2015-12-03 14:48 GMT+01:00 Ben Coman :

On Wed, Dec 2, 2015 at 10:45 PM, Sven Van Caekenberghe 
wrote:

On 02 Dec 2015, at 15:21, Nicolai Hess 
wrote:



2015-12-02 15:03 GMT+01:00 Ben Coman :
On Wed, Dec 2, 2015 at 12:38 AM, Tudor Girba 
wrote:

Hi,


On Dec 1, 2015, at 5:13 PM, Max Leske  wrote:

@Doru
You’re missing the point: #anyOne *fails* for empty collections.

I am not missing the point at all. I am saying that if you want
sum:
to be generic, it cannot assume a specific Zero object.

And sum: should be generic because of its name.

I am missing understanding the other use cases.  Can you describe
further the generic nature of #sum & #sum: ?  I would have thought
by
default they only applied to numbers.

sum can be applied to anything that supports #+, not only numbers
sum: can be applied to any collection with a block that return some
object that supports #+

To me this is a mis-application of polymorphism, that just because
something responds to #+ it should be summable. We have overloaded the
semantics of  #+  to mean both numeric addition and
concatenation/membership, but technically "summation" relates only to
numeric addition.


I didn't wanted to argue for or against any change. I just wanted to
clarify
that there are situations in which a generic sum/sum: that throws an
error
on empty collections and don't assume a null value makes sense.




https://www.google.com.au/search?q=define+sum=define+sum


https://www.google.com.au/search?q=define+concatenate=define+concatenate

For example...

* KMModifier implements  #+  so what is the expected semantic of   " {
KMModifier shift . KMModifier meta} sum " ?
To me this is more of a concatenation/join/union facility rather than
numeric addition.  (btw, that expression actually fails since
KMModifier does not understand minus #- ) .

* String implements  #+  and  " { '1' . '2' } sum " --> '3',   so
actually its doing numeric addition.  However  " { 'a' . 'b' } sum "
produces an error.

So actually there seem some existing problems with summing
non-numerics.  What examples work?

* Trait classes implement both  #+  and  #- , but the semantic seems
more to do with membership than numeric addition.  I don't how how to
produce an example of using #sum against traits.

* Points are summable  " { 2@2 . 3@3 } " --> 5@5.   But then  " 2@2 +
1 " --> 3@3   ,   so  " {} sum "  returning  0  would seem to not
cause any error in this case.


cheers -ben



therefore you can not assume 0 (<- a number) is a proper initial
value
therefore you *need* to work with #anyOne
and as you can not assume a proper initial value, you can not assume
a
default value for empty collections
-> it should throw an error. If you (the caller of the function)
knows
what to do with an empty collection you have
to check, or call inject:into: directly, with a proper initial
value.

I am sorry but I am getting really tired of this, you should read
what
is being said.


do that change, I am not against it. Ben just asked for an example and
I
thought it would be helpful.

It was helpful :)  It evolved my thinking.   Now thinking further, I
wonder how returning  0  will work with applications using units like
Aconcagua, and if it would over-complicate things to do something
like...

Collection>>sum
   | sum sample |
   self isEmpty ifTrue: [ ^ ArithmeticZero ].
   sample := self anyOne.
   sum := self inject: sample 

Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-27 Thread Nicolas Cellier
2015-12-27 2:49 GMT+01:00 Ben Coman :

> On Sun, Dec 27, 2015 at 6:13 AM, Nicolas Cellier
>  wrote:
> >
> >
> > 2015-12-25 2:03 GMT+01:00 Eliot Miranda :
> >>
> >> Ben,
> >>
> >> _,,,^..^,,,_ (phone)
> >>
> >> > On Dec 4, 2015, at 12:49 AM, Ben Coman  wrote:
> >> >
> >> >> On Fri, Dec 4, 2015 at 4:23 AM, Nicolai Hess 
> >> >> wrote:
> >> >>
> >> >>
> >> >> 2015-12-03 14:48 GMT+01:00 Ben Coman :
> >> >>>
> >> >>> On Wed, Dec 2, 2015 at 10:45 PM, Sven Van Caekenberghe <
> s...@stfx.eu>
> >> >>> wrote:
> >> 
> >> > On 02 Dec 2015, at 15:21, Nicolai Hess 
> >> > wrote:
> >> >
> >> >
> >> >
> >> > 2015-12-02 15:03 GMT+01:00 Ben Coman :
> >> > On Wed, Dec 2, 2015 at 12:38 AM, Tudor Girba <
> tu...@tudorgirba.com>
> >> > wrote:
> >> >> Hi,
> >> >>
> >> >>> On Dec 1, 2015, at 5:13 PM, Max Leske 
> wrote:
> >> >>>
> >> >>> @Doru
> >> >>> You’re missing the point: #anyOne *fails* for empty collections.
> >> >>
> >> >> I am not missing the point at all. I am saying that if you want
> >> >> sum:
> >> >> to be generic, it cannot assume a specific Zero object.
> >> >>
> >> >> And sum: should be generic because of its name.
> >> >
> >> > I am missing understanding the other use cases.  Can you describe
> >> > further the generic nature of #sum & #sum: ?  I would have thought
> >> > by
> >> > default they only applied to numbers.
> >> >
> >> > sum can be applied to anything that supports #+, not only numbers
> >> > sum: can be applied to any collection with a block that return
> some
> >> > object that supports #+
> >> >>>
> >> >>> To me this is a mis-application of polymorphism, that just because
> >> >>> something responds to #+ it should be summable. We have overloaded
> the
> >> >>> semantics of  #+  to mean both numeric addition and
> >> >>> concatenation/membership, but technically "summation" relates only
> to
> >> >>> numeric addition.
> >> >>
> >> >>
> >> >> I didn't wanted to argue for or against any change. I just wanted to
> >> >> clarify
> >> >> that there are situations in which a generic sum/sum: that throws an
> >> >> error
> >> >> on empty collections and don't assume a null value makes sense.
> >> >>
> >> >>
> >> >>>
> >> >>>
> >> >>> https://www.google.com.au/search?q=define+sum=define+sum
> >> >>>
> >> >>>
> >> >>>
> https://www.google.com.au/search?q=define+concatenate=define+concatenate
> >> >>>
> >> >>> For example...
> >> >>>
> >> >>> * KMModifier implements  #+  so what is the expected semantic of
>  " {
> >> >>> KMModifier shift . KMModifier meta} sum " ?
> >> >>> To me this is more of a concatenation/join/union facility rather
> than
> >> >>> numeric addition.  (btw, that expression actually fails since
> >> >>> KMModifier does not understand minus #- ) .
> >> >>>
> >> >>> * String implements  #+  and  " { '1' . '2' } sum " --> '3',   so
> >> >>> actually its doing numeric addition.  However  " { 'a' . 'b' } sum "
> >> >>> produces an error.
> >> >>>
> >> >>> So actually there seem some existing problems with summing
> >> >>> non-numerics.  What examples work?
> >> >>>
> >> >>> * Trait classes implement both  #+  and  #- , but the semantic seems
> >> >>> more to do with membership than numeric addition.  I don't how how
> to
> >> >>> produce an example of using #sum against traits.
> >> >>>
> >> >>> * Points are summable  " { 2@2 . 3@3 } " --> 5@5.   But then  " 2@2
> +
> >> >>> 1 " --> 3@3   ,   so  " {} sum "  returning  0  would seem to not
> >> >>> cause any error in this case.
> >> >>>
> >> >>>
> >> >>> cheers -ben
> >> >>>
> >> >>>
> >> >
> >> > therefore you can not assume 0 (<- a number) is a proper initial
> >> > value
> >> > therefore you *need* to work with #anyOne
> >> > and as you can not assume a proper initial value, you can not
> assume
> >> > a
> >> > default value for empty collections
> >> > -> it should throw an error. If you (the caller of the function)
> >> > knows
> >> > what to do with an empty collection you have
> >> > to check, or call inject:into: directly, with a proper initial
> >> > value.
> >> 
> >>  I am sorry but I am getting really tired of this, you should read
> >>  what
> >>  is being said.
> >> >>
> >> >>
> >> >> do that change, I am not against it. Ben just asked for an example
> and
> >> >> I
> >> >> thought it would be helpful.
> >> >
> >> > It was helpful :)  It evolved my thinking.   Now thinking further, I
> >> > wonder how returning  0  will work with applications using units like
> >> > Aconcagua, and if it would over-complicate things to do something
> >> > like...
> >> >
> >> >Collection>>sum
> >> >   | sum sample |
> >> >   self isEmpty 

Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-26 Thread Nicolas Cellier
2015-12-25 2:03 GMT+01:00 Eliot Miranda :

> Ben,
>
> _,,,^..^,,,_ (phone)
>
> > On Dec 4, 2015, at 12:49 AM, Ben Coman  wrote:
> >
> >> On Fri, Dec 4, 2015 at 4:23 AM, Nicolai Hess 
> wrote:
> >>
> >>
> >> 2015-12-03 14:48 GMT+01:00 Ben Coman :
> >>>
> >>> On Wed, Dec 2, 2015 at 10:45 PM, Sven Van Caekenberghe 
> >>> wrote:
> 
> > On 02 Dec 2015, at 15:21, Nicolai Hess 
> wrote:
> >
> >
> >
> > 2015-12-02 15:03 GMT+01:00 Ben Coman :
> > On Wed, Dec 2, 2015 at 12:38 AM, Tudor Girba 
> > wrote:
> >> Hi,
> >>
> >>> On Dec 1, 2015, at 5:13 PM, Max Leske  wrote:
> >>>
> >>> @Doru
> >>> You’re missing the point: #anyOne *fails* for empty collections.
> >>
> >> I am not missing the point at all. I am saying that if you want sum:
> >> to be generic, it cannot assume a specific Zero object.
> >>
> >> And sum: should be generic because of its name.
> >
> > I am missing understanding the other use cases.  Can you describe
> > further the generic nature of #sum & #sum: ?  I would have thought by
> > default they only applied to numbers.
> >
> > sum can be applied to anything that supports #+, not only numbers
> > sum: can be applied to any collection with a block that return some
> > object that supports #+
> >>>
> >>> To me this is a mis-application of polymorphism, that just because
> >>> something responds to #+ it should be summable. We have overloaded the
> >>> semantics of  #+  to mean both numeric addition and
> >>> concatenation/membership, but technically "summation" relates only to
> >>> numeric addition.
> >>
> >>
> >> I didn't wanted to argue for or against any change. I just wanted to
> clarify
> >> that there are situations in which a generic sum/sum: that throws an
> error
> >> on empty collections and don't assume a null value makes sense.
> >>
> >>
> >>>
> >>>
> >>> https://www.google.com.au/search?q=define+sum=define+sum
> >>>
> >>>
> https://www.google.com.au/search?q=define+concatenate=define+concatenate
> >>>
> >>> For example...
> >>>
> >>> * KMModifier implements  #+  so what is the expected semantic of   " {
> >>> KMModifier shift . KMModifier meta} sum " ?
> >>> To me this is more of a concatenation/join/union facility rather than
> >>> numeric addition.  (btw, that expression actually fails since
> >>> KMModifier does not understand minus #- ) .
> >>>
> >>> * String implements  #+  and  " { '1' . '2' } sum " --> '3',   so
> >>> actually its doing numeric addition.  However  " { 'a' . 'b' } sum "
> >>> produces an error.
> >>>
> >>> So actually there seem some existing problems with summing
> >>> non-numerics.  What examples work?
> >>>
> >>> * Trait classes implement both  #+  and  #- , but the semantic seems
> >>> more to do with membership than numeric addition.  I don't how how to
> >>> produce an example of using #sum against traits.
> >>>
> >>> * Points are summable  " { 2@2 . 3@3 } " --> 5@5.   But then  " 2@2 +
> >>> 1 " --> 3@3   ,   so  " {} sum "  returning  0  would seem to not
> >>> cause any error in this case.
> >>>
> >>>
> >>> cheers -ben
> >>>
> >>>
> >
> > therefore you can not assume 0 (<- a number) is a proper initial
> value
> > therefore you *need* to work with #anyOne
> > and as you can not assume a proper initial value, you can not assume
> a
> > default value for empty collections
> > -> it should throw an error. If you (the caller of the function)
> knows
> > what to do with an empty collection you have
> > to check, or call inject:into: directly, with a proper initial value.
> 
>  I am sorry but I am getting really tired of this, you should read what
>  is being said.
> >>
> >>
> >> do that change, I am not against it. Ben just asked for an example and I
> >> thought it would be helpful.
> >
> > It was helpful :)  It evolved my thinking.   Now thinking further, I
> > wonder how returning  0  will work with applications using units like
> > Aconcagua, and if it would over-complicate things to do something
> > like...
> >
> >Collection>>sum
> >   | sum sample |
> >   self isEmpty ifTrue: [ ^ ArithmeticZero ].
> >   sample := self anyOne.
> >   sum := self inject: sample into: [ :accum :each | accum + each ].
> >^ sum - sample
> >
> >ArithmeticZero class >> + anObject
> >^anObject
>
> surely you mean
>
> Collection>>sum
>   ^self inject: ArithmeticZero into: [ :accum :each | accum + each ]
>
>ArithmeticZero class >> + anObject
>^anObject
>
> and I'd optimise as
> Collection>>sum
>   | sum |
>   sum := ArithmeticZero.
>   self do: [ :each | sum := sum + each ].
>   ^sum
>
> But in with those that want an error and would use either
> Collection>>sum
>   

Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-26 Thread Ben Coman
On Sun, Dec 27, 2015 at 6:13 AM, Nicolas Cellier
 wrote:
>
>
> 2015-12-25 2:03 GMT+01:00 Eliot Miranda :
>>
>> Ben,
>>
>> _,,,^..^,,,_ (phone)
>>
>> > On Dec 4, 2015, at 12:49 AM, Ben Coman  wrote:
>> >
>> >> On Fri, Dec 4, 2015 at 4:23 AM, Nicolai Hess 
>> >> wrote:
>> >>
>> >>
>> >> 2015-12-03 14:48 GMT+01:00 Ben Coman :
>> >>>
>> >>> On Wed, Dec 2, 2015 at 10:45 PM, Sven Van Caekenberghe 
>> >>> wrote:
>> 
>> > On 02 Dec 2015, at 15:21, Nicolai Hess 
>> > wrote:
>> >
>> >
>> >
>> > 2015-12-02 15:03 GMT+01:00 Ben Coman :
>> > On Wed, Dec 2, 2015 at 12:38 AM, Tudor Girba 
>> > wrote:
>> >> Hi,
>> >>
>> >>> On Dec 1, 2015, at 5:13 PM, Max Leske  wrote:
>> >>>
>> >>> @Doru
>> >>> You’re missing the point: #anyOne *fails* for empty collections.
>> >>
>> >> I am not missing the point at all. I am saying that if you want
>> >> sum:
>> >> to be generic, it cannot assume a specific Zero object.
>> >>
>> >> And sum: should be generic because of its name.
>> >
>> > I am missing understanding the other use cases.  Can you describe
>> > further the generic nature of #sum & #sum: ?  I would have thought
>> > by
>> > default they only applied to numbers.
>> >
>> > sum can be applied to anything that supports #+, not only numbers
>> > sum: can be applied to any collection with a block that return some
>> > object that supports #+
>> >>>
>> >>> To me this is a mis-application of polymorphism, that just because
>> >>> something responds to #+ it should be summable. We have overloaded the
>> >>> semantics of  #+  to mean both numeric addition and
>> >>> concatenation/membership, but technically "summation" relates only to
>> >>> numeric addition.
>> >>
>> >>
>> >> I didn't wanted to argue for or against any change. I just wanted to
>> >> clarify
>> >> that there are situations in which a generic sum/sum: that throws an
>> >> error
>> >> on empty collections and don't assume a null value makes sense.
>> >>
>> >>
>> >>>
>> >>>
>> >>> https://www.google.com.au/search?q=define+sum=define+sum
>> >>>
>> >>>
>> >>> https://www.google.com.au/search?q=define+concatenate=define+concatenate
>> >>>
>> >>> For example...
>> >>>
>> >>> * KMModifier implements  #+  so what is the expected semantic of   " {
>> >>> KMModifier shift . KMModifier meta} sum " ?
>> >>> To me this is more of a concatenation/join/union facility rather than
>> >>> numeric addition.  (btw, that expression actually fails since
>> >>> KMModifier does not understand minus #- ) .
>> >>>
>> >>> * String implements  #+  and  " { '1' . '2' } sum " --> '3',   so
>> >>> actually its doing numeric addition.  However  " { 'a' . 'b' } sum "
>> >>> produces an error.
>> >>>
>> >>> So actually there seem some existing problems with summing
>> >>> non-numerics.  What examples work?
>> >>>
>> >>> * Trait classes implement both  #+  and  #- , but the semantic seems
>> >>> more to do with membership than numeric addition.  I don't how how to
>> >>> produce an example of using #sum against traits.
>> >>>
>> >>> * Points are summable  " { 2@2 . 3@3 } " --> 5@5.   But then  " 2@2 +
>> >>> 1 " --> 3@3   ,   so  " {} sum "  returning  0  would seem to not
>> >>> cause any error in this case.
>> >>>
>> >>>
>> >>> cheers -ben
>> >>>
>> >>>
>> >
>> > therefore you can not assume 0 (<- a number) is a proper initial
>> > value
>> > therefore you *need* to work with #anyOne
>> > and as you can not assume a proper initial value, you can not assume
>> > a
>> > default value for empty collections
>> > -> it should throw an error. If you (the caller of the function)
>> > knows
>> > what to do with an empty collection you have
>> > to check, or call inject:into: directly, with a proper initial
>> > value.
>> 
>>  I am sorry but I am getting really tired of this, you should read
>>  what
>>  is being said.
>> >>
>> >>
>> >> do that change, I am not against it. Ben just asked for an example and
>> >> I
>> >> thought it would be helpful.
>> >
>> > It was helpful :)  It evolved my thinking.   Now thinking further, I
>> > wonder how returning  0  will work with applications using units like
>> > Aconcagua, and if it would over-complicate things to do something
>> > like...
>> >
>> >Collection>>sum
>> >   | sum sample |
>> >   self isEmpty ifTrue: [ ^ ArithmeticZero ].
>> >   sample := self anyOne.
>> >   sum := self inject: sample into: [ :accum :each | accum + each ].
>> >^ sum - sample
>> >
>> >ArithmeticZero class >> + anObject
>> >^anObject
>>
>> surely you mean
>>
>> Collection>>sum
>>   ^self inject: ArithmeticZero into: [ :accum :each | accum + 

Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-25 Thread Henrik Nergaard
Like this?
http://smalltalkhub.com/#!/~Latsabben/NumIt

Best regards,
Henrik

-Original Message-
From: Pharo-dev [mailto:pharo-dev-boun...@lists.pharo.org] On Behalf Of stepharo
Sent: Thursday, December 24, 2015 9:58 AM
To: Pharo Development List <pharo-dev@lists.pharo.org>
Subject: Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

Just a remark.
I think that we discarded the proposition of having

aCol arithmetic sum

but I found it nice because there if was clear that you want to get back 
0 for #().

Stef



Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-25 Thread stepharo

Just a remark.
I think that we discarded the proposition of having

aCol arithmetic sum

but I found it nice because there if was clear that you want to get back 
0 for #().


Stef



Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-23 Thread stepharo

Just a remark.
I think that we discarded the proposition of having

aCol arithmetic sum

but I found it nice because there if was clear that you want to get back 
0 for #().


Stef



Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-22 Thread Nicolas Cellier
2015-12-22 10:37 GMT+01:00 Sven Van Caekenberghe :

>
> > On 22 Dec 2015, at 10:22, Nicolas Cellier <
> nicolas.cellier.aka.n...@gmail.com> wrote:
> >
> >
> >
> > 2015-12-22 3:46 GMT+01:00 Ben Coman :
> > On Wed, Dec 2, 2015 at 3:38 AM, Tudor Girba 
> wrote:
> > > I am saying that if you want sum: to be generic, it cannot assume a
> *specific* Zero object.
> > > And sum:  should be generic because of its name.
> >
> > This seems the crux of the disparate viewpoints, which is why I
> > suggested return a *generic* Zero object as follows...
> >
> > > On 04 Dec 2015, at 01:49, Ben Coman  wrote:
> > > do something like...
> > >
> > >Collection>>sum
> > >   | sum sample |
> > >   self isEmpty ifTrue: [ ^ ArithmeticZero ].
> > >   sample := self anyOne.
> > >   sum := self inject: sample into: [ :accum :each | accum + each ].
> > >^ sum - sample
> >
> >
> > Nice, but generic zero can't work: you sometimes need to decide if it is
> the zero of vector space, or of associated field.
> > The generic zero can't behave as both say a matrix and a scalar...
>
> Indeed, that is what I said the first time Ben proposed this.
>
> But I am curious, Nicolas, what you think of this, with your math
> background/interest ?
>
>
This is what I had in old app (in the 90s):

SequenceableCollection>>sum: aBlock
"answer the sum of all elements after applying a Block"
| sum |
self isEmpty ifTrue: [^0].
sum := aBlock value: (self at: 1).
2 to: self size do: [:i | sum := sum + (aBlock value: (self at: i))].
^sum

Collection>>sum: aBlock
"answer the sum of all elements after applying a Block"
| sum |
sum := 0.
self do: [:e | sum := sum + (aBlock value: e)].
^sum

I find sum: much more expressive than inject:into:

If we really find that it adds semantic value to inject:into: we may also
implement optionnal:

Collection>>sum: aBlock to: initialValue
"answer the sum of all elements after applying a Block"
| sum |
sum := initialValue.
self do: [:e | sum := sum + (aBlock value: e)].
^sum
Collection>>sum: aBlock
^self sum: aBlock to: 0

This way, no (#anyOne,#-) trick required, that's why I prefer sum:to: to
sum:ifEmpty:...
For example, I had symbolic algebra, and the #- trick would have required
further simplification of the sum.

So I don't have any mathematical solution, just pragmatic ones:
- I agree on this: no need for many selectors, one or maximum two should be
enough
- I wouldn't care too much and would just answer 0 for empty collection
because we have inject:into: or optionnally sum:to: for exotic cases


Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-22 Thread Denis Kudriashov
Hi

My vote:


> 1. Do you agree to changing #sum and #sum: in the suggested way?
>

yes but I prefer #sum: return zero too for empty collections


> 2. Do you agree to the removal of #detectSum:?
>

yes


>
> 3. Do you agree to the removal of #sumNumbers?
>

yes


>
> 4. Do you agree that the #max and #min selectors also need to be adapted?
>

yes


Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-22 Thread Ferlicot D. Cyril
Le 20/12/2015 12:59, Max Leske a écrit :
> I would like to wrap up this discussion. 
> 
> 
> 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?
> 

Yes

> 2. Do you agree to the removal of #detectSum:?
> 

Yes

> 3. Do you agree to the removal of #sumNumbers?
> 

Yes

> 4. Do you agree that the #max and #min selectors also need to be adapted?
> 

Yes

> 
> 
> 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: 100) asArray sum ] benchFor: 10 seconds.
> 75 iterations, 7.470 per second
> 
> [ (1 to: 100) 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: 100) asArray sum ] benchFor: 10 seconds.
> 73 iterations, 7.244 per second
> 
> [ (1 to: 100) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
> 75 iterations, 7.480 per second
> 
> [ (1 to: 100) 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
> 


-- 
Cyril Ferlicot

http://www.synectique.eu

165 Avenue Bretagne
Lille 59000 France



signature.asc
Description: OpenPGP digital signature


Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-22 Thread Sven Van Caekenberghe

> On 22 Dec 2015, at 10:22, Nicolas Cellier 
>  wrote:
> 
> 
> 
> 2015-12-22 3:46 GMT+01:00 Ben Coman :
> On Wed, Dec 2, 2015 at 3:38 AM, Tudor Girba  wrote:
> > I am saying that if you want sum: to be generic, it cannot assume a 
> > *specific* Zero object.
> > And sum:  should be generic because of its name.
> 
> This seems the crux of the disparate viewpoints, which is why I
> suggested return a *generic* Zero object as follows...
> 
> > On 04 Dec 2015, at 01:49, Ben Coman  wrote:
> > do something like...
> >
> >Collection>>sum
> >   | sum sample |
> >   self isEmpty ifTrue: [ ^ ArithmeticZero ].
> >   sample := self anyOne.
> >   sum := self inject: sample into: [ :accum :each | accum + each ].
> >^ sum - sample
> 
> 
> Nice, but generic zero can't work: you sometimes need to decide if it is the 
> zero of vector space, or of associated field.
> The generic zero can't behave as both say a matrix and a scalar...

Indeed, that is what I said the first time Ben proposed this.

But I am curious, Nicolas, what you think of this, with your math 
background/interest ?

> On Sat, Dec 5, 2015 at 3:12 AM, Max Leske  wrote:
> > While I think you might be on to something, I think we should take small
> > steps. I’d be happy already if we can just get rid of one superfluous method
> > and provide a better API without starting to think about the deeper
> > semantics.
> 
> Sure, small steps are better, except when this hits a sticking point
> that the bigger step may overcome.  I think returning a generic zero
> allowing the program to proceed is better than throwing an generic
> error that the programmer needs to explicitly deal with.  The concept
> of zero is well defined for the common arithmetic functions.  Just for
> a thought experiment, what arithmetic functions would need to be dealt
> with.
> 
> >ArithmeticZero class >> + anObject
> >^anObject
> 
> AritmeticZero class >> * anObject
>  ^ anObject zero
> 
> AritmeticZero class >> - anObject
>  ^ anObject zero - anObject
> 
> 
> > Also, I think there’s a reason why Aconcagua is an external package:
> > developers usually are happy to work with numbers (which are already objects
> > in Smalltalk anyway) and they’re fast.
> 
> Sure its an external package, but when you have a collection of weight
> readings for example, you want to use the internal convenient #sum
> method...
>{ 4 kg . 5 kg . 6 kg } sum--> 16kg
>{ } sum + 1 kg --> 1kg
>{ } sum * 1 kg--> 0 kg^2   "hmmm, zero with units and
> multiplication starts getting more complicated - maybe should be left
> out of this discussion"
> 
> > While #sumNumbers may *technically* be the best name (which
> > we can’t seem to agree on…), #sum, #sum: and #sum:ifEmpty:
> > form a triple that naturally fits into the naming protocol applied
> > elsewhere.
> 
> So maybe alternative naming of the generic zero...
> #sum  (empty --> EmptyAggregateZero)
> #sum:   (empty --> EmptyAggregateZero)
> #sum: ifEmpty:   (empty --> whatever)
> 
> 
> > On Mon, Dec 21, 2015 at 12:43 AM, Sven Van Caekenberghe 
> > 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.
> 
> #sum is very convenient and that lowers the barrier of entry for
> newcomers over the relatively exotic #inject:into:We should keep
> trying to work through the sticky points, but maybe you guys getting
> together IRL is better than continuing on the mail list.
> 
> cheers -ben




Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-22 Thread Nicolai Hess
2015-12-20 12:59 GMT+01:00 Max Leske :

>
>
> 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).
>

there is no #sumNumbers, only #sumNumbers:


>
>
> 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?
>

yes


>
> 2. Do you agree to the removal of #detectSum:?
>

yes


>
> 3. Do you agree to the removal of #sumNumbers?
>

yes


>
> 4. Do you agree that the #max and #min selectors also need to be adapted?
>

hm. I like the "detect". If

aCollection detectMax: aBlock
becomes

aCollection max: aBlock

it looks too similar  to
aCollection size max: aValue

But  I could live with that :)


>
>
> 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: 100) asArray sum ] benchFor: 10 seconds.
> 75 iterations, 7.470 per second
>
> [ (1 to: 100) 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: 100) asArray sum ] benchFor: 10 seconds.
> 73 iterations, 7.244 per second
>
> [ (1 to: 100) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
> 75 iterations, 7.480 per second
>
> [ (1 to: 100) 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
>
>


Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-22 Thread Nicolas Cellier
2015-12-22 3:46 GMT+01:00 Ben Coman :

> On Wed, Dec 2, 2015 at 3:38 AM, Tudor Girba  wrote:
> > I am saying that if you want sum: to be generic, it cannot assume a
> *specific* Zero object.
> > And sum:  should be generic because of its name.
>
> This seems the crux of the disparate viewpoints, which is why I
> suggested return a *generic* Zero object as follows...
>
> > On 04 Dec 2015, at 01:49, Ben Coman  wrote:
> > do something like...
> >
> >Collection>>sum
> >   | sum sample |
> >   self isEmpty ifTrue: [ ^ ArithmeticZero ].
> >   sample := self anyOne.
> >   sum := self inject: sample into: [ :accum :each | accum + each ].
> >^ sum - sample
>
>
Nice, but generic zero can't work: you sometimes need to decide if it is
the zero of vector space, or of associated field.
The generic zero can't behave as both say a matrix and a scalar...


> On Sat, Dec 5, 2015 at 3:12 AM, Max Leske  wrote:
> > While I think you might be on to something, I think we should take small
> > steps. I’d be happy already if we can just get rid of one superfluous
> method
> > and provide a better API without starting to think about the deeper
> > semantics.
>
> Sure, small steps are better, except when this hits a sticking point
> that the bigger step may overcome.  I think returning a generic zero
> allowing the program to proceed is better than throwing an generic
> error that the programmer needs to explicitly deal with.  The concept
> of zero is well defined for the common arithmetic functions.  Just for
> a thought experiment, what arithmetic functions would need to be dealt
> with.
>
> >ArithmeticZero class >> + anObject
> >^anObject
>
> AritmeticZero class >> * anObject
>  ^ anObject zero
>
> AritmeticZero class >> - anObject
>  ^ anObject zero - anObject
>
>
> > Also, I think there’s a reason why Aconcagua is an external package:
> > developers usually are happy to work with numbers (which are already
> objects
> > in Smalltalk anyway) and they’re fast.
>
> Sure its an external package, but when you have a collection of weight
> readings for example, you want to use the internal convenient #sum
> method...
>{ 4 kg . 5 kg . 6 kg } sum--> 16kg
>{ } sum + 1 kg --> 1kg
>{ } sum * 1 kg--> 0 kg^2   "hmmm, zero with units and
> multiplication starts getting more complicated - maybe should be left
> out of this discussion"
>
> > While #sumNumbers may *technically* be the best name (which
> > we can’t seem to agree on…), #sum, #sum: and #sum:ifEmpty:
> > form a triple that naturally fits into the naming protocol applied
> > elsewhere.
>
> So maybe alternative naming of the generic zero...
> #sum  (empty --> EmptyAggregateZero)
> #sum:   (empty --> EmptyAggregateZero)
> #sum: ifEmpty:   (empty --> whatever)
>
>
> > On Mon, Dec 21, 2015 at 12:43 AM, Sven Van Caekenberghe 
> > 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.
>
> #sum is very convenient and that lowers the barrier of entry for
> newcomers over the relatively exotic #inject:into:We should keep
> trying to work through the sticky points, but maybe you guys getting
> together IRL is better than continuing on the mail list.
>
> cheers -ben
>
>


Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers: (Max Leske)

2015-12-21 Thread Sven Van Caekenberghe

> On 21 Dec 2015, at 23:48, Richard Uttner  wrote:
> 
> This is my first contribution to the DevList and I hope you forgive me that 
> it sounds more like "I see something we dont need" than the other way round, 
> but there will be more positive posts of mine concering the Unicode debate 
> (which I will postpone to the New Year in order to be able to respond 
> quickly).

Everybody's opinion count, thank you for yours.

> From a developer's point of view that is dealing with more than one 
> environment (3 Smalltalk environments including Pharo, where I am a newby) 
> and a handful of other languages, I dont like to reuse interfaces that are 
> hard to remember and understand though the task done by them is so easy that 
> I can write it down in one simple #inject:into-line 10 times faster than 
> looking it up in the implementors browser. Furthermore, something like 
> #inject:into: will work forever and never be deprecated! Fullstops.

That is my fallback position: if we can't agree on an implementation, just 
throw them all out, it is very easy to write yourself. But I would not prefer 
it.

> Next thing that is easily overlooked is the semantics. I am not that good in 
> mathematics, but I would suppose that summing up does by definition not need 
> a neutral element - only an implementation that can be written down in 2 
> lines needs it. A mathematically correct implementation of summing up 
> anything (including nil ... see reason below) that implements #+ would be:
> 
> Collection:>>#sum
>   | undef result |
>   undef := result := Object new.
>   self do: [:each | result := result == undef ifTrue: [each] ifFalse: [result 
> + each]].

Interesting, clever, but I guess you forgot a return of result at the end ?

In that case, you would return some new object for an empty collection, not 0 
like I would prefer.

For me the whole discussion centers around what happens with an empty 
collection. We know, and currently have, an implementation that can work on 
non-empty collection without using a neutral element to start with. That is 
cool.

However, if you check the actual senders, more than half of them are doing 
silly empty checks before invoking the summing. Which to me defeats what you 
gain by not writing an #inject:into: on the spot.

> 2015-12-21 18:00 GMT+01:00 :
> Send Pharo-dev mailing list submissions to
> pharo-dev@lists.pharo.org
> 
> To subscribe or unsubscribe via the World Wide Web, visit
> http://lists.pharo.org/mailman/listinfo/pharo-dev_lists.pharo.org
> or, via email, send a message with subject or body 'help' to
> pharo-dev-requ...@lists.pharo.org
> 
> You can reach the person managing the list at
> pharo-dev-ow...@lists.pharo.org
> 
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Pharo-dev digest..."
> 
> 
> Today's Topics:
> 
>1. Re: [Pharo-users] [ANN] Pharo Consortium Sponsored
>   Development Effort (Dimitris Chloupis)
>2. Re: #sum:, #detectSum:, #sumNumbers: (Max Leske)
>3. Re: [Pharo-users] [ANN] Pharo Consortium Sponsored
>   Development Effort (Mariano Martinez Peck)
>4. Re: #sum:, #detectSum:, #sumNumbers: (Max Leske)
>5. Re: [Pharo-users] [ANN] Pharo Consortium Sponsored
>   Development Effort (Dimitris Chloupis)
>6. Re: [Pharo-users] [ANN] Pharo Consortium Sponsored
>   Development Effort (Thierry Goubier)
>7. Re: #sum:, #detectSum:, #sumNumbers: (Tudor Girba)
>8. [pharo-project/pharo-core] (GitHub)
>9. [pharo-project/pharo-core] e8216b: 50508 (GitHub)
>   10. Re: [Pharo-users] [ANN] Pharo Consortium Sponsored
>   Development Effort (Denis Kudriashov)
>   11. Re: [Pharo-users] [ANN] Pharo Consortium Sponsored
>   Development Effort (Ben Coman)
>   12. Re: [squeak-dev] [Unicode] Summary (Re: Unicode Support   // e
>   acute example --> decomposition in Pharo?) (Sven Van Caekenberghe)
>   13. Re: [Pharo-users] [ANN] Pharo Consortium Sponsored
>   Development Effort (Thierry Goubier)
>   14. Re: [squeak-dev] [Unicode] Summary (Re: Unicode Support   // e
>   acute example --> decomposition in Pharo?) (Sven Van Caekenberghe)
>   15. Re: [Pharo-users] [ANN] Pharo Consortium Sponsored
>   Development Effort (Robert Withers)
>   16. Re: [Pharo-users] [ANN] Pharo Consortium Sponsored
>   Development Effort (p...@highoctane.be)
>   17. Re: [ANN] Multiple Desktop support for Pharo 5 (H. Hirzel)
>   18.  No refactoring for equal/hash generation (Denis Kudriashov)
>   19. Re: [Pharo-users] [ANN] Pharo Consortium Sponsored
>   Development Effort (Denis Kudriashov)
>   20. Re: [Pharo-users] [ANN] Pharo Consortium Sponsored
>   Development Effort (Mariano Martinez Peck)
>   21. Re: [Pharo-users] [ANN] Pharo Consortium Sponsored
>   Development Effort (Robert Withers)
> 
> 
> --
> 
> 

Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-21 Thread Ben Coman
On Wed, Dec 2, 2015 at 3:38 AM, Tudor Girba  wrote:
> I am saying that if you want sum: to be generic, it cannot assume a 
> *specific* Zero object.
> And sum:  should be generic because of its name.

This seems the crux of the disparate viewpoints, which is why I
suggested return a *generic* Zero object as follows...

> On 04 Dec 2015, at 01:49, Ben Coman  wrote:
> do something like...
>
>Collection>>sum
>   | sum sample |
>   self isEmpty ifTrue: [ ^ ArithmeticZero ].
>   sample := self anyOne.
>   sum := self inject: sample into: [ :accum :each | accum + each ].
>^ sum - sample

On Sat, Dec 5, 2015 at 3:12 AM, Max Leske  wrote:
> While I think you might be on to something, I think we should take small
> steps. I’d be happy already if we can just get rid of one superfluous method
> and provide a better API without starting to think about the deeper
> semantics.

Sure, small steps are better, except when this hits a sticking point
that the bigger step may overcome.  I think returning a generic zero
allowing the program to proceed is better than throwing an generic
error that the programmer needs to explicitly deal with.  The concept
of zero is well defined for the common arithmetic functions.  Just for
a thought experiment, what arithmetic functions would need to be dealt
with.

>ArithmeticZero class >> + anObject
>^anObject

AritmeticZero class >> * anObject
 ^ anObject zero

AritmeticZero class >> - anObject
 ^ anObject zero - anObject


> Also, I think there’s a reason why Aconcagua is an external package:
> developers usually are happy to work with numbers (which are already objects
> in Smalltalk anyway) and they’re fast.

Sure its an external package, but when you have a collection of weight
readings for example, you want to use the internal convenient #sum
method...
   { 4 kg . 5 kg . 6 kg } sum--> 16kg
   { } sum + 1 kg --> 1kg
   { } sum * 1 kg--> 0 kg^2   "hmmm, zero with units and
multiplication starts getting more complicated - maybe should be left
out of this discussion"

> While #sumNumbers may *technically* be the best name (which
> we can’t seem to agree on…), #sum, #sum: and #sum:ifEmpty:
> form a triple that naturally fits into the naming protocol applied
> elsewhere.

So maybe alternative naming of the generic zero...
#sum  (empty --> EmptyAggregateZero)
#sum:   (empty --> EmptyAggregateZero)
#sum: ifEmpty:   (empty --> whatever)


> On Mon, Dec 21, 2015 at 12:43 AM, Sven Van Caekenberghe 
> 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.

#sum is very convenient and that lowers the barrier of entry for
newcomers over the relatively exotic #inject:into:We should keep
trying to work through the sticky points, but maybe you guys getting
together IRL is better than continuing on the mail list.

cheers -ben



Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-21 Thread Sven Van Caekenberghe
I would suggest not to change anything for now, let's wait for Max's poll or 
feedback from others. We could also pick this up again when we see each other 
IRL, like at the Pharo Days, that will certainly make it easier.

> On 20 Dec 2015, at 22:09, Tudor Girba  wrote:
> 
> Hi,
> 
> I cannot seem to agree with the current line of reasoning, so I am 
> withdrawing from this debate. It’s late in the year and I know I need a 
> break, so it is likely that I am missing something obvious or that I am just 
> persisting in some sort of bike-shedding point of view :).
> 
> Thanks for keeping up with this.
> 
> I wish you all a lovely holiday and see you next year!
> 
> Doru
> 
> 
>> On Dec 20, 2015, at 8:23 PM, Max Leske  wrote:
>> 
>> I did a pass on all the changes that would be required (whatever the outcome 
>> of this discussion). Looks easy enough. One interesting point: 
>> FloatArray>>sum is implemented as a primitive in the FloatArrayPlugin and 
>> the zero element is explicitly defined as 0.0. The primitive will not fail 
>> for an empty collection but return 0.0. That would be in line with our new 
>> definition of #sum.
>> 
>> 
>> One other thing: should the old selectors be marked as deprecated rather 
>> than being removed? I think that’s the general policy, right?
>> 
>> Cheers,
>> Max
>> 
>> 
>>> On 20 Dec 2015, at 18:19, Max Leske  wrote:
>>> 
>>> 
 On 20 Dec 2015, at 15:26, Ben Coman  wrote:
 
 On Mon, Dec 21, 2015 at 12:43 AM, Sven Van Caekenberghe  
 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  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 agree somewhat with Duro to avoid #sum and #sum:  having different 
 semantics,
 but I agree more with Sven about keeping #sum for numbers only and
 returning zero,
 so why not turn Doru's suggestion around...
 
 #sum  (empty --> 0)
 #sumBy:   (empty --> error)
 #sumBy: ifEmpty:   (empty --> no error)
 
 alternatively could be #sumUsing: or #sumWith:  or something similar.
>>> 
>>> Also a good idea. However, looking at the methods on Collection, the 
>>> pattern is usually #message and #message:, e.g. #sorted and #sorted:. There 
>>> used to be #sortBy: but it was removed because the view was that the 
>>> protocol semantics should be the same across all methods.
>>> The current case is a bit different of course since we’re dealing with the 
>>> problem of the zero element which doesn’t arise in most other cases. Still, 
>>> I think from a users point of view it would be strange to have to use 
>>> #sumBy: when every other message pair uses the #message / #message: pattern.
>>> 
>>> I feel that this argument (thanks Ben :) ) is also a valid point against 
>>> Doru’s argument for #sumNumbers. While #sumNumbers may *technically* be the 
>>> best name (which we can’t seem to agree on…), #sum, #sum: and #sum:ifEmpty: 
>>> form a triple that naturally fits into the naming protocol applied 
>>> elsewhere.
>>> 
>>> 
>>> Cheers,
>>> Max
>>> 
 
 
 
>> 
>> Cheers,
>> Doru
>> 
>> 
>>> On Dec 20, 2015, at 1:47 PM, Max Leske  wrote:
>>> 
 
 On 20 Dec 2015, at 13:43, Gabriel Cotelli  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 

Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-20 Thread Tudor Girba
Hi,

I cannot seem to agree with the current line of reasoning, so I am withdrawing 
from this debate. It’s late in the year and I know I need a break, so it is 
likely that I am missing something obvious or that I am just persisting in some 
sort of bike-shedding point of view :).

Thanks for keeping up with this.

I wish you all a lovely holiday and see you next year!

Doru


> On Dec 20, 2015, at 8:23 PM, Max Leske  wrote:
> 
> I did a pass on all the changes that would be required (whatever the outcome 
> of this discussion). Looks easy enough. One interesting point: 
> FloatArray>>sum is implemented as a primitive in the FloatArrayPlugin and the 
> zero element is explicitly defined as 0.0. The primitive will not fail for an 
> empty collection but return 0.0. That would be in line with our new 
> definition of #sum.
> 
> 
> One other thing: should the old selectors be marked as deprecated rather than 
> being removed? I think that’s the general policy, right?
> 
> Cheers,
> Max
> 
> 
>> On 20 Dec 2015, at 18:19, Max Leske  wrote:
>> 
>> 
>>> On 20 Dec 2015, at 15:26, Ben Coman  wrote:
>>> 
>>> On Mon, Dec 21, 2015 at 12:43 AM, Sven Van Caekenberghe  
>>> 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  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 agree somewhat with Duro to avoid #sum and #sum:  having different 
>>> semantics,
>>> but I agree more with Sven about keeping #sum for numbers only and
>>> returning zero,
>>> so why not turn Doru's suggestion around...
>>> 
>>> #sum  (empty --> 0)
>>> #sumBy:   (empty --> error)
>>> #sumBy: ifEmpty:   (empty --> no error)
>>> 
>>> alternatively could be #sumUsing: or #sumWith:  or something similar.
>> 
>> Also a good idea. However, looking at the methods on Collection, the pattern 
>> is usually #message and #message:, e.g. #sorted and #sorted:. There used to 
>> be #sortBy: but it was removed because the view was that the protocol 
>> semantics should be the same across all methods.
>> The current case is a bit different of course since we’re dealing with the 
>> problem of the zero element which doesn’t arise in most other cases. Still, 
>> I think from a users point of view it would be strange to have to use 
>> #sumBy: when every other message pair uses the #message / #message: pattern.
>> 
>> I feel that this argument (thanks Ben :) ) is also a valid point against 
>> Doru’s argument for #sumNumbers. While #sumNumbers may *technically* be the 
>> best name (which we can’t seem to agree on…), #sum, #sum: and #sum:ifEmpty: 
>> form a triple that naturally fits into the naming protocol applied elsewhere.
>> 
>> 
>> Cheers,
>> Max
>> 
>>> 
>>> 
>>> 
> 
> Cheers,
> Doru
> 
> 
>> On Dec 20, 2015, at 1:47 PM, Max Leske  wrote:
>> 
>>> 
>>> On 20 Dec 2015, at 13:43, Gabriel Cotelli  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  wrote:
>>> I would like to wrap up this discussion.
>>> 
>>> 
 On 05 Dec 2015, at 18:14, stepharo  wrote:

Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-20 Thread Gabriel Cotelli
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

On Sun, Dec 20, 2015 at 8:59 AM, Max Leske  wrote:

> I would like to wrap up this discussion.
>
>
> On 05 Dec 2015, at 18:14, stepharo  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: 100) asArray sum ] benchFor: 10 seconds.
> 75 iterations, 7.470 per second
>
> [ (1 to: 100) 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: 100) asArray sum ] benchFor: 10 seconds.
> 73 iterations, 7.244 per second
>
> [ (1 to: 100) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
> 75 iterations, 7.480 per second
>
> [ (1 to: 100) 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
>
>


Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-20 Thread Sven Van Caekenberghe

> On 20 Dec 2015, at 12:59, Max Leske  wrote:
> 
> I would like to wrap up this discussion. 

Good idea.

>> On 05 Dec 2015, at 18:14, stepharo  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.

Excellent summary, thanks.

> Please cast your vote for these changes:
> 
> 1. Do you agree to changing #sum and #sum: in the suggested way?

yes

> 2. Do you agree to the removal of #detectSum:?

yes

> 3. Do you agree to the removal of #sumNumbers?

yes

> 4. Do you agree that the #max and #min selectors also need to be adapted?

probably yes.

> Thanks for you help.
> 
> Cheers,
> Max
> 
> 
> 
> 
> 
> Benchmarks
> 
> (Note that these aren’t very good benchmarks. There’s quite some variation on 
> each run.)

You should exclude your setup out of your actual benchmark, like this:

| numbers |
numbers := (1 to: 100) asArray.
[ numbers sum ] benchFor: 10 seconds. 

"a BenchmarkResult(126 iterations in 10 seconds 77 milliseconds. 12.504 per 
second)"

> 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: 100) asArray sum ] benchFor: 10 seconds.
>   75 iterations, 7.470 per second
> 
> [ (1 to: 100) 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: 100) asArray sum ] benchFor: 10 seconds.
>   73 iterations, 7.244 per second
> 
> [ (1 to: 100) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>   75 iterations, 7.480 per second
> 
> [ (1 to: 100) 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
> 




Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-20 Thread Tudor Girba
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  wrote:
> 
>> 
>> On 20 Dec 2015, at 13:43, Gabriel Cotelli  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  wrote:
>> I would like to wrap up this discussion. 
>> 
>> 
>>> On 05 Dec 2015, at 18:14, stepharo  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: 100) asArray sum ] benchFor: 10 seconds.
>>  75 iterations, 7.470 per second
>> 
>> [ (1 to: 100) 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: 100) asArray sum ] benchFor: 10 seconds.
>>  73 iterations, 7.244 per second
>> 
>> [ (1 to: 100) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>>  75 iterations, 7.480 per second
>> 
>> [ (1 to: 100) asArray sum: [ :e | e ] ifEmpty: [ 0 ] ] benchFor: 10 
>> seconds.
>>  72 iterations, 7.141 per second
>> 
>> 
>> [ (1 to: 100) asArray 

Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-20 Thread Max Leske

> On 20 Dec 2015, at 13:43, Gabriel Cotelli  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  > wrote:
> I would like to wrap up this discussion. 
> 
> 
>> On 05 Dec 2015, at 18:14, stepharo > > 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: 100) asArray sum ] benchFor: 10 seconds.
>   75 iterations, 7.470 per second
> 
> [ (1 to: 100) 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: 100) asArray sum ] benchFor: 10 seconds.
>   73 iterations, 7.244 per second
> 
> [ (1 to: 100) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
>   75 iterations, 7.480 per second
> 
> [ (1 to: 100) 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
> 
> 



Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-20 Thread Max Leske
I would like to wrap up this discussion. 


> On 05 Dec 2015, at 18:14, stepharo  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: 100) asArray sum ] benchFor: 10 seconds.
75 iterations, 7.470 per second

[ (1 to: 100) 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: 100) asArray sum ] benchFor: 10 seconds.
73 iterations, 7.244 per second

[ (1 to: 100) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
75 iterations, 7.480 per second

[ (1 to: 100) 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



Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-20 Thread Max Leske

> On 20 Dec 2015, at 14:10, Tudor Girba  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  wrote:
>> 
>>> 
>>> On 20 Dec 2015, at 13:43, Gabriel Cotelli  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  wrote:
>>> I would like to wrap up this discussion. 
>>> 
>>> 
 On 05 Dec 2015, at 18:14, stepharo  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: 100) asArray sum ] benchFor: 10 seconds.
>>> 75 iterations, 7.470 per second
>>> 
>>> [ (1 to: 100) 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 

Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-20 Thread Tudor Girba
Hi,

> On Dec 20, 2015, at 2:30 PM, Max Leske  wrote:
> 
> 
>> On 20 Dec 2015, at 14:10, Tudor Girba  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  wrote:
>>> 
 
 On 20 Dec 2015, at 13:43, Gabriel Cotelli  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  wrote:
 I would like to wrap up this discussion. 
 
 
> On 05 Dec 2015, at 18:14, stepharo  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: 100) asArray sum ] benchFor: 10 seconds.
75 iterations, 7.470 per second
 
 [ (1 to: 100) asArray sum: [ :e | e ] ] 

Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-20 Thread 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  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  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  wrote:
>>> 
 
 On 20 Dec 2015, at 13:43, Gabriel Cotelli  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  wrote:
 I would like to wrap up this discussion. 
 
 
> On 05 Dec 2015, at 18:14, stepharo  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 

Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-20 Thread 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  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  wrote:
>> 
>> NO
>> 
>>> On 20 Dec 2015, at 14:32, Tudor Girba  wrote:
>>> 
>>> Hi,
>>> 
 On Dec 20, 2015, at 2:30 PM, Max Leske  wrote:
 
 
> On 20 Dec 2015, at 14:10, Tudor Girba  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  wrote:
>> 
>>> 
>>> On 20 Dec 2015, at 13:43, Gabriel Cotelli  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  wrote:
>>> I would like to wrap up this discussion. 
>>> 
>>> 
 On 05 Dec 2015, at 18:14, stepharo  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 

Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-20 Thread Sven Van Caekenberghe

> On 20 Dec 2015, at 14:57, Tudor Girba  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  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  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  wrote:
 
> 
> On 20 Dec 2015, at 13:43, Gabriel Cotelli  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  wrote:
> I would like to wrap up this discussion. 
> 
> 
>> On 05 Dec 2015, at 18:14, stepharo  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 

Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-20 Thread 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  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  wrote:
>> 
>>> 
>>> On 20 Dec 2015, at 13:43, Gabriel Cotelli  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  wrote:
>>> I would like to wrap up this discussion. 
>>> 
>>> 
 On 05 Dec 2015, at 18:14, stepharo  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 

Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-20 Thread Sven Van Caekenberghe
NO

> On 20 Dec 2015, at 14:32, Tudor Girba  wrote:
> 
> Hi,
> 
>> On Dec 20, 2015, at 2:30 PM, Max Leske  wrote:
>> 
>> 
>>> On 20 Dec 2015, at 14:10, Tudor Girba  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  wrote:
 
> 
> On 20 Dec 2015, at 13:43, Gabriel Cotelli  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  wrote:
> I would like to wrap up this discussion. 
> 
> 
>> On 05 Dec 2015, at 18:14, stepharo  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 

Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-20 Thread 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  wrote:
> 
> NO
> 
>> On 20 Dec 2015, at 14:32, Tudor Girba  wrote:
>> 
>> Hi,
>> 
>>> On Dec 20, 2015, at 2:30 PM, Max Leske  wrote:
>>> 
>>> 
 On 20 Dec 2015, at 14:10, Tudor Girba  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  wrote:
> 
>> 
>> On 20 Dec 2015, at 13:43, Gabriel Cotelli  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  wrote:
>> I would like to wrap up this discussion. 
>> 
>> 
>>> On 05 Dec 2015, at 18:14, stepharo  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.
>> 

Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-20 Thread Tudor Girba
Hi,

> On Dec 20, 2015, at 3:07 PM, Sven Van Caekenberghe  wrote:
> 
> 
>> On 20 Dec 2015, at 14:57, Tudor Girba  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  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  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  wrote:
> 
>> 
>> On 20 Dec 2015, at 13:43, Gabriel Cotelli  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  wrote:
>> I would like to wrap up this discussion. 
>> 
>> 
>>> On 05 Dec 2015, at 18:14, stepharo  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 

Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-20 Thread Ben Coman
On Mon, Dec 21, 2015 at 12:43 AM, Sven Van Caekenberghe  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  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 agree somewhat with Duro to avoid #sum and #sum:  having different semantics,
but I agree more with Sven about keeping #sum for numbers only and
returning zero,
so why not turn Doru's suggestion around...

#sum  (empty --> 0)
#sumBy:   (empty --> error)
#sumBy: ifEmpty:   (empty --> no error)

alternatively could be #sumUsing: or #sumWith:  or something similar.



>>
>> Cheers,
>> Doru
>>
>>
>>> On Dec 20, 2015, at 1:47 PM, Max Leske  wrote:
>>>

 On 20 Dec 2015, at 13:43, Gabriel Cotelli  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  wrote:
 I would like to wrap up this discussion.


> On 05 Dec 2015, at 18:14, stepharo  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?
yes

 2. Do you agree to the removal of #detectSum:?

Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-20 Thread Max Leske
Updated benchmarks with pre-calculated collection of numbers (as suggested by 
Sven):


Benchmarks of the current versions:

[ (1 to: 100) asArray sum ] benchFor: 10 seconds.
124 iterations, 12.389 per second

[ (1 to: 100) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
109 iterations, 10.801 per second)


[ (1 to: 100) asArray sum ] benchFor: 10 seconds.
4,166,154 iterations, 416,532 per second


[ (1 to: 100) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
3,115,121 iterations, 311,481 per second



Benchmarks of the new versions:

[ (1 to: 100) asArray sum ] benchFor: 10 seconds.
125 iterations, 12.490 per second

[ (1 to: 100) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
119 iterations, 11.842 per second

[ (1 to: 100) asArray sum: [ :e | e ] ifEmpty: [ 0 ] ] benchFor: 10 seconds.
130 iterations, 12.947 per second


[ (1 to: 100) asArray sum ] benchFor: 10 seconds.
2,985,085 iterations, 298,449 per second

[ (1 to: 100) asArray sum: [ :e | e ] ] benchFor: 10 seconds.
3,260,280 iterations, 325,963 per second

[ (1 to: 100) asArray sum: [ :e | e ] ifEmpty: [ 0 ] ] benchFor: 10 seconds.
3,143,812 iterations, 314,287 per second



The benchmark for #sum suggests that there’s indeed a benefit of duplicating 
the code for that particular case (the delegations would make #sum 30% slower). 
I still think we should use delegation there instead of duplicate code. #sum is 
not a “critical” method in my opinion.

Cheers,
Max


> On 20 Dec 2015, at 14:01, Sven Van Caekenberghe  wrote:
> 
>> 
>> On 20 Dec 2015, at 12:59, Max Leske > > wrote:
>> 
>> I would like to wrap up this discussion. 
> 
> Good idea.
> 
>>> On 05 Dec 2015, at 18:14, stepharo  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.
> 
> Excellent summary, thanks.
> 
>> Please cast your vote for these changes:
>> 
>> 1. Do you agree to changing #sum and #sum: in the suggested way?
> 
> yes
> 
>> 2. Do you agree to the removal of #detectSum:?
> 
> yes
> 
>> 3. Do you agree to the removal of #sumNumbers?
> 
> yes
> 
>> 4. Do you agree that the #max and #min selectors also need to be adapted?
> 
> probably yes.
> 
>> Thanks for you help.
>> 
>> Cheers,
>> Max
>> 
>> 
>> 
>> 
>> 
>> Benchmarks
>> 
>> (Note that these aren’t very good benchmarks. There’s quite some variation 
>> on each run.)
> 
> You should exclude your setup out of your actual benchmark, like this:
> 
> | numbers |
> numbers := (1 to: 100) asArray.
> [ numbers sum ] benchFor: 10 seconds. 
> 
> "a BenchmarkResult(126 iterations in 10 seconds 77 milliseconds. 12.504 per 
> second)"
> 
>> Machine:
>>  MacBook Pro (15-inch, Early 2011)
>>  CPU: 2.2 GHz Intel Core i7
>>  Memory: 8 GB 1333 MHz DDR3
>>  Disk: APPLE SSD TS512C 

Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-20 Thread Max Leske

> On 20 Dec 2015, at 15:26, Ben Coman  wrote:
> 
> On Mon, Dec 21, 2015 at 12:43 AM, Sven Van Caekenberghe  > 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  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 agree somewhat with Duro to avoid #sum and #sum:  having different 
> semantics,
> but I agree more with Sven about keeping #sum for numbers only and
> returning zero,
> so why not turn Doru's suggestion around...
> 
> #sum  (empty --> 0)
> #sumBy:   (empty --> error)
> #sumBy: ifEmpty:   (empty --> no error)
> 
> alternatively could be #sumUsing: or #sumWith:  or something similar.

Also a good idea. However, looking at the methods on Collection, the pattern is 
usually #message and #message:, e.g. #sorted and #sorted:. There used to be 
#sortBy: but it was removed because the view was that the protocol semantics 
should be the same across all methods.
The current case is a bit different of course since we’re dealing with the 
problem of the zero element which doesn’t arise in most other cases. Still, I 
think from a users point of view it would be strange to have to use #sumBy: 
when every other message pair uses the #message / #message: pattern.

I feel that this argument (thanks Ben :) ) is also a valid point against Doru’s 
argument for #sumNumbers. While #sumNumbers may *technically* be the best name 
(which we can’t seem to agree on…), #sum, #sum: and #sum:ifEmpty: form a triple 
that naturally fits into the naming protocol applied elsewhere.


Cheers,
Max

> 
> 
> 
>>> 
>>> Cheers,
>>> Doru
>>> 
>>> 
 On Dec 20, 2015, at 1:47 PM, Max Leske  wrote:
 
> 
> On 20 Dec 2015, at 13:43, Gabriel Cotelli  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  wrote:
> I would like to wrap up this discussion.
> 
> 
>> On 05 Dec 2015, at 18:14, stepharo  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 

Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-20 Thread Max Leske
I did a pass on all the changes that would be required (whatever the outcome of 
this discussion). Looks easy enough. One interesting point: FloatArray>>sum is 
implemented as a primitive in the FloatArrayPlugin and the zero element is 
explicitly defined as 0.0. The primitive will not fail for an empty collection 
but return 0.0. That would be in line with our new definition of #sum.


One other thing: should the old selectors be marked as deprecated rather than 
being removed? I think that’s the general policy, right?

Cheers,
Max


> On 20 Dec 2015, at 18:19, Max Leske  wrote:
> 
> 
>> On 20 Dec 2015, at 15:26, Ben Coman > > wrote:
>> 
>> On Mon, Dec 21, 2015 at 12:43 AM, Sven Van Caekenberghe > > 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 > 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 agree somewhat with Duro to avoid #sum and #sum:  having different 
>> semantics,
>> but I agree more with Sven about keeping #sum for numbers only and
>> returning zero,
>> so why not turn Doru's suggestion around...
>> 
>> #sum  (empty --> 0)
>> #sumBy:   (empty --> error)
>> #sumBy: ifEmpty:   (empty --> no error)
>> 
>> alternatively could be #sumUsing: or #sumWith:  or something similar.
> 
> Also a good idea. However, looking at the methods on Collection, the pattern 
> is usually #message and #message:, e.g. #sorted and #sorted:. There used to 
> be #sortBy: but it was removed because the view was that the protocol 
> semantics should be the same across all methods.
> The current case is a bit different of course since we’re dealing with the 
> problem of the zero element which doesn’t arise in most other cases. Still, I 
> think from a users point of view it would be strange to have to use #sumBy: 
> when every other message pair uses the #message / #message: pattern.
> 
> I feel that this argument (thanks Ben :) ) is also a valid point against 
> Doru’s argument for #sumNumbers. While #sumNumbers may *technically* be the 
> best name (which we can’t seem to agree on…), #sum, #sum: and #sum:ifEmpty: 
> form a triple that naturally fits into the naming protocol applied elsewhere.
> 
> 
> Cheers,
> Max
> 
>> 
>> 
>> 
 
 Cheers,
 Doru
 
 
> On Dec 20, 2015, at 1:47 PM, Max Leske  > wrote:
> 
>> 
>> On 20 Dec 2015, at 13:43, Gabriel Cotelli > > 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 > > wrote:
>> I would like to wrap up this discussion.
>> 
>> 
>>> On 05 Dec 2015, at 18:14, stepharo >> > 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 

Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-05 Thread stepharo

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.

]]]



Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-04 Thread Max Leske

> On 04 Dec 2015, at 01:49, Ben Coman  wrote:
> 
> On Fri, Dec 4, 2015 at 4:23 AM, Nicolai Hess  > wrote:
>> 
>> 
>> 2015-12-03 14:48 GMT+01:00 Ben Coman :
>>> 
>>> On Wed, Dec 2, 2015 at 10:45 PM, Sven Van Caekenberghe 
>>> wrote:
 
> On 02 Dec 2015, at 15:21, Nicolai Hess  wrote:
> 
> 
> 
> 2015-12-02 15:03 GMT+01:00 Ben Coman :
> On Wed, Dec 2, 2015 at 12:38 AM, Tudor Girba 
> wrote:
>> Hi,
>> 
>>> On Dec 1, 2015, at 5:13 PM, Max Leske  wrote:
>>> 
>>> @Doru
>>> You’re missing the point: #anyOne *fails* for empty collections.
>> 
>> I am not missing the point at all. I am saying that if you want sum:
>> to be generic, it cannot assume a specific Zero object.
>> 
>> And sum: should be generic because of its name.
> 
> I am missing understanding the other use cases.  Can you describe
> further the generic nature of #sum & #sum: ?  I would have thought by
> default they only applied to numbers.
> 
> sum can be applied to anything that supports #+, not only numbers
> sum: can be applied to any collection with a block that return some
> object that supports #+
>>> 
>>> To me this is a mis-application of polymorphism, that just because
>>> something responds to #+ it should be summable. We have overloaded the
>>> semantics of  #+  to mean both numeric addition and
>>> concatenation/membership, but technically "summation" relates only to
>>> numeric addition.

I agree. If I want to sum something other than a collection of numbers I’ll 
happily provide the block for that summation (I wouldn’t even expect strings to 
be summable to be honest. Why would you have a collection of numbers that are 
strings…? And if you really have one, you should convert it explicitly so that 
another person reading your code knows what’s going on.)

>> 
>> 
>> I didn't wanted to argue for or against any change. I just wanted to clarify
>> that there are situations in which a generic sum/sum: that throws an error
>> on empty collections and don't assume a null value makes sense.
>> 
>> 
>>> 
>>> 
>>> https://www.google.com.au/search?q=define+sum=define+sum
>>> 
>>> https://www.google.com.au/search?q=define+concatenate=define+concatenate
>>> 
>>> For example...
>>> 
>>> * KMModifier implements  #+  so what is the expected semantic of   " {
>>> KMModifier shift . KMModifier meta} sum " ?
>>> To me this is more of a concatenation/join/union facility rather than
>>> numeric addition.  (btw, that expression actually fails since
>>> KMModifier does not understand minus #- ) .
>>> 
>>> * String implements  #+  and  " { '1' . '2' } sum " --> '3',   so
>>> actually its doing numeric addition.  However  " { 'a' . 'b' } sum "
>>> produces an error.
>>> 
>>> So actually there seem some existing problems with summing
>>> non-numerics.  What examples work?
>>> 
>>> * Trait classes implement both  #+  and  #- , but the semantic seems
>>> more to do with membership than numeric addition.  I don't how how to
>>> produce an example of using #sum against traits.
>>> 
>>> * Points are summable  " { 2@2 . 3@3 } " --> 5@5.   But then  " 2@2 +
>>> 1 " --> 3@3   ,   so  " {} sum "  returning  0  would seem to not
>>> cause any error in this case.
>>> 
>>> 
>>> cheers -ben
>>> 
>>> 
> 
> therefore you can not assume 0 (<- a number) is a proper initial value
> therefore you *need* to work with #anyOne
> and as you can not assume a proper initial value, you can not assume a
> default value for empty collections
> -> it should throw an error. If you (the caller of the function) knows
> what to do with an empty collection you have
> to check, or call inject:into: directly, with a proper initial value.
 
 I am sorry but I am getting really tired of this, you should read what
 is being said.
>> 
>> 
>> do that change, I am not against it. Ben just asked for an example and I
>> thought it would be helpful.
> 
> It was helpful :)  It evolved my thinking.   Now thinking further, I
> wonder how returning  0  will work with applications using units like
> Aconcagua, and if it would over-complicate things to do something
> like...
> 
>Collection>>sum
>   | sum sample |
>   self isEmpty ifTrue: [ ^ ArithmeticZero ].
>   sample := self anyOne.
>   sum := self inject: sample into: [ :accum :each | accum + each ].
>^ sum - sample
> 
>ArithmeticZero class >> + anObject
>^anObject

While I think you might be on to something, I think we should take small steps. 
I’d be happy already if we can just get rid of one superfluous method and 
provide a better API without starting to think about the deeper semantics.
Also, I think there’s a reason why Aconcagua is an external package: developers 

Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-03 Thread Chris Cunningham
On Thu, Dec 3, 2015 at 4:51 PM, Ben Coman  wrote:

> On Fri, Dec 4, 2015 at 3:26 AM, Chris Cunningham
>  wrote:
> > 
> >
> > On Thu, Dec 3, 2015 at 5:48 AM, Ben Coman  wrote:
> >>
> >>
> >>
> >> * Points are summable  " { 2@2 . 3@3 } " --> 5@5.   But then  " 2@2 +
> >> 1 " --> 3@3   ,   so  " {} sum "  returning  0  would seem to not
> >> cause any error in this case.
> >>
> >>
> >> cheers -ben
> >
> >
> > but points aren't commutative:
> >
> > 2@2 + 1 " = 3@3"
> > 1 + 2@2 " = 3@2"
> >
> > Of course, 0 wouldn't be an issue, unless you wanted to access x or y!
> >
> > -cbc
>
> whoops?
> 1 + (2@2)  = 3@3
>
> cheers -ben
>
> Yeah.  Forgot the parenthesis.  1 + 2@2 is the same as (1 + 2) @ 2.
My eye sees the closeness of 2@2 as a point - not as a binary message
(which it obviously is).

So, never mind.

-cbc


Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-03 Thread Ben Coman
On Wed, Dec 2, 2015 at 10:45 PM, Sven Van Caekenberghe  wrote:
>
>> On 02 Dec 2015, at 15:21, Nicolai Hess  wrote:
>>
>>
>>
>> 2015-12-02 15:03 GMT+01:00 Ben Coman :
>> On Wed, Dec 2, 2015 at 12:38 AM, Tudor Girba  wrote:
>> > Hi,
>> >
>> >> On Dec 1, 2015, at 5:13 PM, Max Leske  wrote:
>> >>
>> >> @Doru
>> >> You’re missing the point: #anyOne *fails* for empty collections.
>> >
>> > I am not missing the point at all. I am saying that if you want sum: to be 
>> > generic, it cannot assume a specific Zero object.
>> >
>> > And sum: should be generic because of its name.
>>
>> I am missing understanding the other use cases.  Can you describe
>> further the generic nature of #sum & #sum: ?  I would have thought by
>> default they only applied to numbers.
>>
>> sum can be applied to anything that supports #+, not only numbers
>> sum: can be applied to any collection with a block that return some object 
>> that supports #+

To me this is a mis-application of polymorphism, that just because
something responds to #+ it should be summable. We have overloaded the
semantics of  #+  to mean both numeric addition and
concatenation/membership, but technically "summation" relates only to
numeric addition.

https://www.google.com.au/search?q=define+sum=define+sum
https://www.google.com.au/search?q=define+concatenate=define+concatenate

For example...

* KMModifier implements  #+  so what is the expected semantic of   " {
KMModifier shift . KMModifier meta} sum " ?
To me this is more of a concatenation/join/union facility rather than
numeric addition.  (btw, that expression actually fails since
KMModifier does not understand minus #- ) .

* String implements  #+  and  " { '1' . '2' } sum " --> '3',   so
actually its doing numeric addition.  However  " { 'a' . 'b' } sum "
produces an error.

So actually there seem some existing problems with summing
non-numerics.  What examples work?

* Trait classes implement both  #+  and  #- , but the semantic seems
more to do with membership than numeric addition.  I don't how how to
produce an example of using #sum against traits.

* Points are summable  " { 2@2 . 3@3 } " --> 5@5.   But then  " 2@2 +
1 " --> 3@3   ,   so  " {} sum "  returning  0  would seem to not
cause any error in this case.


cheers -ben


>>
>> therefore you can not assume 0 (<- a number) is a proper initial value 
>> therefore you *need* to work with #anyOne
>> and as you can not assume a proper initial value, you can not assume a 
>> default value for empty collections
>> -> it should throw an error. If you (the caller of the function) knows what 
>> to do with an empty collection you have
>> to check, or call inject:into: directly, with a proper initial value.
>
> I am sorry but I am getting really tired of this, you should read what is 
> being said.
>
> I am not suggesting to stop using #anyOne because I like why it is there and 
> what it can do.
>
> The change I want is what happens with an empty collection when using the 
> simplest selector, #sum.
>
> I do not want to say to some collection of numbers #sumIfEmpty: [0], because 
> summing numbers starting from zero is the most common case and everybody 
> expects that, hence the unary selector fits.
>
> I want the less common cases to use the more complicated API, as in some 
> collection of colors #sumIfEmpty: [ Color black ]
>
> In my book that is common sense API design.
>
> Doing that I do no take anything away, because today you already have to make 
> sure the collection is not empty.
>
> The only change would be in the error behaviour. I think that is a reasonable 
> price to pay. Instead of having #anyOne fail, it will say that #+ cannot add 
> 0 to some object, and in a comment we can point to the alternative API.
>
> http://izquotes.com/quote/242740 right ?
>
>> cheers -ben
>>
>> >
>> >>> On 01 Dec 2015, at 15:31, Esteban A. Maringolo  
>> >>> wrote:
>> >>>
>> >>> I don't want to be heretic (or too orthodox), but why not to delegate
>> >>> this behavior to other class (an iterator maybe?).
>> >>>
>> >>> It's too tempting adding these convenience methods to Collection
>> >>> and/or subclasses, but anything that requires an explicit protocol of
>> >>> its elements is wrong, IMO.
>> >>>
>> >>> something like aCollection arithmetic sum: [...] or aCollection
>> >>> arithmetic avg.
>> >>
>> >>
>> >> Interesting thought!
>> >
>> > +100
>> >
>> > Doru
>> >
>> >>>
>> >>> My two cents for this.
>> >>>
>> >>> Regards!
>> >>>
>> >>>
>> >>> Esteban A. Maringolo
>> >>>
>> >>
>> >>
>> >
>> > --
>> > www.tudorgirba.com
>> >
>> > "Every thing has its own flow."
>> >
>> >
>> >
>> >
>> >
>
>



Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-03 Thread Chris Cunningham


On Thu, Dec 3, 2015 at 5:48 AM, Ben Coman  wrote:

>
>
> * Points are summable  " { 2@2 . 3@3 } " --> 5@5.   But then  " 2@2 +
> 1 " --> 3@3   ,   so  " {} sum "  returning  0  would seem to not
> cause any error in this case.
>
>
> cheers -ben


but points aren't commutative:

2@2 + 1 " = 3@3"
1 + 2@2 " = 3@2"

Of course, 0 wouldn't be an issue, unless you wanted to access x or y!

-cbc


Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-03 Thread Nicolai Hess
2015-12-03 14:48 GMT+01:00 Ben Coman :

> On Wed, Dec 2, 2015 at 10:45 PM, Sven Van Caekenberghe 
> wrote:
> >
> >> On 02 Dec 2015, at 15:21, Nicolai Hess  wrote:
> >>
> >>
> >>
> >> 2015-12-02 15:03 GMT+01:00 Ben Coman :
> >> On Wed, Dec 2, 2015 at 12:38 AM, Tudor Girba 
> wrote:
> >> > Hi,
> >> >
> >> >> On Dec 1, 2015, at 5:13 PM, Max Leske  wrote:
> >> >>
> >> >> @Doru
> >> >> You’re missing the point: #anyOne *fails* for empty collections.
> >> >
> >> > I am not missing the point at all. I am saying that if you want sum:
> to be generic, it cannot assume a specific Zero object.
> >> >
> >> > And sum: should be generic because of its name.
> >>
> >> I am missing understanding the other use cases.  Can you describe
> >> further the generic nature of #sum & #sum: ?  I would have thought by
> >> default they only applied to numbers.
> >>
> >> sum can be applied to anything that supports #+, not only numbers
> >> sum: can be applied to any collection with a block that return some
> object that supports #+
>
> To me this is a mis-application of polymorphism, that just because
> something responds to #+ it should be summable. We have overloaded the
> semantics of  #+  to mean both numeric addition and
> concatenation/membership, but technically "summation" relates only to
> numeric addition.
>

I didn't wanted to argue for or against any change. I just wanted to clarify
that there are situations in which a generic sum/sum: that throws an error
on empty collections and don't assume a null value makes sense.



>
> https://www.google.com.au/search?q=define+sum=define+sum
> https://www.google.com.au/search?q=define+concatenate=define+concatenate
>
> For example...
>
> * KMModifier implements  #+  so what is the expected semantic of   " {
> KMModifier shift . KMModifier meta} sum " ?
> To me this is more of a concatenation/join/union facility rather than
> numeric addition.  (btw, that expression actually fails since
> KMModifier does not understand minus #- ) .
>
> * String implements  #+  and  " { '1' . '2' } sum " --> '3',   so
> actually its doing numeric addition.  However  " { 'a' . 'b' } sum "
> produces an error.
>
> So actually there seem some existing problems with summing
> non-numerics.  What examples work?
>
> * Trait classes implement both  #+  and  #- , but the semantic seems
> more to do with membership than numeric addition.  I don't how how to
> produce an example of using #sum against traits.
>
> * Points are summable  " { 2@2 . 3@3 } " --> 5@5.   But then  " 2@2 +
> 1 " --> 3@3   ,   so  " {} sum "  returning  0  would seem to not
> cause any error in this case.
>
>
> cheers -ben
>
>
> >>
> >> therefore you can not assume 0 (<- a number) is a proper initial value
> therefore you *need* to work with #anyOne
> >> and as you can not assume a proper initial value, you can not assume a
> default value for empty collections
> >> -> it should throw an error. If you (the caller of the function) knows
> what to do with an empty collection you have
> >> to check, or call inject:into: directly, with a proper initial value.
> >
> > I am sorry but I am getting really tired of this, you should read what
> is being said.
>

do that change, I am not against it. Ben just asked for an example and I
thought it would be helpful.



> >
> > I am not suggesting to stop using #anyOne because I like why it is there
> and what it can do.
> >
> > The change I want is what happens with an empty collection when using
> the simplest selector, #sum.
> >
> > I do not want to say to some collection of numbers #sumIfEmpty: [0],
> because summing numbers starting from zero is the most common case and
> everybody expects that, hence the unary selector fits.
> >
> > I want the less common cases to use the more complicated API, as in some
> collection of colors #sumIfEmpty: [ Color black ]
> >
> > In my book that is common sense API design.
> >
> > Doing that I do no take anything away, because today you already have to
> make sure the collection is not empty.
> >
> > The only change would be in the error behaviour. I think that is a
> reasonable price to pay. Instead of having #anyOne fail, it will say that
> #+ cannot add 0 to some object, and in a comment we can point to the
> alternative API.
>




> >
> > http://izquotes.com/quote/242740 right ?
> >
> >> cheers -ben
> >>
> >> >
> >> >>> On 01 Dec 2015, at 15:31, Esteban A. Maringolo <
> emaring...@gmail.com> wrote:
> >> >>>
> >> >>> I don't want to be heretic (or too orthodox), but why not to
> delegate
> >> >>> this behavior to other class (an iterator maybe?).
> >> >>>
> >> >>> It's too tempting adding these convenience methods to Collection
> >> >>> and/or subclasses, but anything that requires an explicit protocol
> of
> >> >>> its elements is wrong, IMO.
> >> >>>
> >> >>> something like aCollection arithmetic sum: [...] or aCollection
> >> >>> 

Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-03 Thread Ben Coman
On Fri, Dec 4, 2015 at 4:23 AM, Nicolai Hess  wrote:
>
>
> 2015-12-03 14:48 GMT+01:00 Ben Coman :
>>
>> On Wed, Dec 2, 2015 at 10:45 PM, Sven Van Caekenberghe 
>> wrote:
>> >
>> >> On 02 Dec 2015, at 15:21, Nicolai Hess  wrote:
>> >>
>> >>
>> >>
>> >> 2015-12-02 15:03 GMT+01:00 Ben Coman :
>> >> On Wed, Dec 2, 2015 at 12:38 AM, Tudor Girba 
>> >> wrote:
>> >> > Hi,
>> >> >
>> >> >> On Dec 1, 2015, at 5:13 PM, Max Leske  wrote:
>> >> >>
>> >> >> @Doru
>> >> >> You’re missing the point: #anyOne *fails* for empty collections.
>> >> >
>> >> > I am not missing the point at all. I am saying that if you want sum:
>> >> > to be generic, it cannot assume a specific Zero object.
>> >> >
>> >> > And sum: should be generic because of its name.
>> >>
>> >> I am missing understanding the other use cases.  Can you describe
>> >> further the generic nature of #sum & #sum: ?  I would have thought by
>> >> default they only applied to numbers.
>> >>
>> >> sum can be applied to anything that supports #+, not only numbers
>> >> sum: can be applied to any collection with a block that return some
>> >> object that supports #+
>>
>> To me this is a mis-application of polymorphism, that just because
>> something responds to #+ it should be summable. We have overloaded the
>> semantics of  #+  to mean both numeric addition and
>> concatenation/membership, but technically "summation" relates only to
>> numeric addition.
>
>
> I didn't wanted to argue for or against any change. I just wanted to clarify
> that there are situations in which a generic sum/sum: that throws an error
> on empty collections and don't assume a null value makes sense.
>
>
>>
>>
>> https://www.google.com.au/search?q=define+sum=define+sum
>>
>> https://www.google.com.au/search?q=define+concatenate=define+concatenate
>>
>> For example...
>>
>> * KMModifier implements  #+  so what is the expected semantic of   " {
>> KMModifier shift . KMModifier meta} sum " ?
>> To me this is more of a concatenation/join/union facility rather than
>> numeric addition.  (btw, that expression actually fails since
>> KMModifier does not understand minus #- ) .
>>
>> * String implements  #+  and  " { '1' . '2' } sum " --> '3',   so
>> actually its doing numeric addition.  However  " { 'a' . 'b' } sum "
>> produces an error.
>>
>> So actually there seem some existing problems with summing
>> non-numerics.  What examples work?
>>
>> * Trait classes implement both  #+  and  #- , but the semantic seems
>> more to do with membership than numeric addition.  I don't how how to
>> produce an example of using #sum against traits.
>>
>> * Points are summable  " { 2@2 . 3@3 } " --> 5@5.   But then  " 2@2 +
>> 1 " --> 3@3   ,   so  " {} sum "  returning  0  would seem to not
>> cause any error in this case.
>>
>>
>> cheers -ben
>>
>>
>> >>
>> >> therefore you can not assume 0 (<- a number) is a proper initial value
>> >> therefore you *need* to work with #anyOne
>> >> and as you can not assume a proper initial value, you can not assume a
>> >> default value for empty collections
>> >> -> it should throw an error. If you (the caller of the function) knows
>> >> what to do with an empty collection you have
>> >> to check, or call inject:into: directly, with a proper initial value.
>> >
>> > I am sorry but I am getting really tired of this, you should read what
>> > is being said.
>
>
> do that change, I am not against it. Ben just asked for an example and I
> thought it would be helpful.

It was helpful :)  It evolved my thinking.   Now thinking further, I
wonder how returning  0  will work with applications using units like
Aconcagua, and if it would over-complicate things to do something
like...

Collection>>sum
   | sum sample |
   self isEmpty ifTrue: [ ^ ArithmeticZero ].
   sample := self anyOne.
   sum := self inject: sample into: [ :accum :each | accum + each ].
^ sum - sample

ArithmeticZero class >> + anObject
^anObject

cheers -ben

>
>
>>
>> >
>> > I am not suggesting to stop using #anyOne because I like why it is there
>> > and what it can do.
>> >
>> > The change I want is what happens with an empty collection when using
>> > the simplest selector, #sum.
>> >
>> > I do not want to say to some collection of numbers #sumIfEmpty: [0],
>> > because summing numbers starting from zero is the most common case and
>> > everybody expects that, hence the unary selector fits.
>> >
>> > I want the less common cases to use the more complicated API, as in some
>> > collection of colors #sumIfEmpty: [ Color black ]
>> >
>> > In my book that is common sense API design.
>> >
>> > Doing that I do no take anything away, because today you already have to
>> > make sure the collection is not empty.
>> >
>> > The only change would be in the error behaviour. I think that is a
>> > reasonable price to pay. Instead of 

Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-03 Thread Ben Coman
On Fri, Dec 4, 2015 at 3:26 AM, Chris Cunningham
 wrote:
> 
>
> On Thu, Dec 3, 2015 at 5:48 AM, Ben Coman  wrote:
>>
>>
>>
>> * Points are summable  " { 2@2 . 3@3 } " --> 5@5.   But then  " 2@2 +
>> 1 " --> 3@3   ,   so  " {} sum "  returning  0  would seem to not
>> cause any error in this case.
>>
>>
>> cheers -ben
>
>
> but points aren't commutative:
>
> 2@2 + 1 " = 3@3"
> 1 + 2@2 " = 3@2"
>
> Of course, 0 wouldn't be an issue, unless you wanted to access x or y!
>
> -cbc

whoops?
1 + (2@2)  = 3@3

cheers -ben



Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-02 Thread Sven Van Caekenberghe

> On 02 Dec 2015, at 15:45, Sven Van Caekenberghe  wrote:
> 
> The only change would be in the error behaviour. I think that is a reasonable 
> price to pay. Instead of having #anyOne fail, it will say that #+ cannot add 
> 0 to some object, and in a comment we can point to the alternative API.

Make that: instead of having #anyOne fail (which is pretty obscure) it will 
return 0 which will then probably fail.


Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-02 Thread Nicolai Hess
2015-12-02 15:03 GMT+01:00 Ben Coman :

> On Wed, Dec 2, 2015 at 12:38 AM, Tudor Girba  wrote:
> > Hi,
> >
> >> On Dec 1, 2015, at 5:13 PM, Max Leske  wrote:
> >>
> >> @Doru
> >> You’re missing the point: #anyOne *fails* for empty collections.
> >
> > I am not missing the point at all. I am saying that if you want sum: to
> be generic, it cannot assume a specific Zero object.
> >
> > And sum: should be generic because of its name.
>
> I am missing understanding the other use cases.  Can you describe
> further the generic nature of #sum & #sum: ?  I would have thought by
> default they only applied to numbers.
>

sum can be applied to anything that supports #+, not only numbers
sum: can be applied to any collection with a block that return some object
that supports #+

therefore you can not assume 0 (<- a number) is a proper initial value
therefore you *need* to work with #anyOne
and as you can not assume a proper initial value, you can not assume a
default value for empty collections
-> it should throw an error. If you (the caller of the function) knows what
to do with an empty collection you have
to check, or call inject:into: directly, with a proper initial value.


>
> cheers -ben
>
> >
> >>> On 01 Dec 2015, at 15:31, Esteban A. Maringolo 
> wrote:
> >>>
> >>> I don't want to be heretic (or too orthodox), but why not to delegate
> >>> this behavior to other class (an iterator maybe?).
> >>>
> >>> It's too tempting adding these convenience methods to Collection
> >>> and/or subclasses, but anything that requires an explicit protocol of
> >>> its elements is wrong, IMO.
> >>>
> >>> something like aCollection arithmetic sum: [...] or aCollection
> >>> arithmetic avg.
> >>
> >>
> >> Interesting thought!
> >
> > +100
> >
> > Doru
> >
> >>>
> >>> My two cents for this.
> >>>
> >>> Regards!
> >>>
> >>>
> >>> Esteban A. Maringolo
> >>>
> >>
> >>
> >
> > --
> > www.tudorgirba.com
> >
> > "Every thing has its own flow."
> >
> >
> >
> >
> >
>
>


Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-02 Thread Sven Van Caekenberghe

> On 02 Dec 2015, at 15:21, Nicolai Hess  wrote:
> 
> 
> 
> 2015-12-02 15:03 GMT+01:00 Ben Coman :
> On Wed, Dec 2, 2015 at 12:38 AM, Tudor Girba  wrote:
> > Hi,
> >
> >> On Dec 1, 2015, at 5:13 PM, Max Leske  wrote:
> >>
> >> @Doru
> >> You’re missing the point: #anyOne *fails* for empty collections.
> >
> > I am not missing the point at all. I am saying that if you want sum: to be 
> > generic, it cannot assume a specific Zero object.
> >
> > And sum: should be generic because of its name.
> 
> I am missing understanding the other use cases.  Can you describe
> further the generic nature of #sum & #sum: ?  I would have thought by
> default they only applied to numbers.
> 
> sum can be applied to anything that supports #+, not only numbers
> sum: can be applied to any collection with a block that return some object 
> that supports #+
> 
> therefore you can not assume 0 (<- a number) is a proper initial value 
> therefore you *need* to work with #anyOne
> and as you can not assume a proper initial value, you can not assume a 
> default value for empty collections
> -> it should throw an error. If you (the caller of the function) knows what 
> to do with an empty collection you have
> to check, or call inject:into: directly, with a proper initial value.

I am sorry but I am getting really tired of this, you should read what is being 
said.

I am not suggesting to stop using #anyOne because I like why it is there and 
what it can do.

The change I want is what happens with an empty collection when using the 
simplest selector, #sum.

I do not want to say to some collection of numbers #sumIfEmpty: [0], because 
summing numbers starting from zero is the most common case and everybody 
expects that, hence the unary selector fits.

I want the less common cases to use the more complicated API, as in some 
collection of colors #sumIfEmpty: [ Color black ]

In my book that is common sense API design.

Doing that I do no take anything away, because today you already have to make 
sure the collection is not empty.

The only change would be in the error behaviour. I think that is a reasonable 
price to pay. Instead of having #anyOne fail, it will say that #+ cannot add 0 
to some object, and in a comment we can point to the alternative API.

http://izquotes.com/quote/242740 right ?

> cheers -ben
> 
> >
> >>> On 01 Dec 2015, at 15:31, Esteban A. Maringolo  
> >>> wrote:
> >>>
> >>> I don't want to be heretic (or too orthodox), but why not to delegate
> >>> this behavior to other class (an iterator maybe?).
> >>>
> >>> It's too tempting adding these convenience methods to Collection
> >>> and/or subclasses, but anything that requires an explicit protocol of
> >>> its elements is wrong, IMO.
> >>>
> >>> something like aCollection arithmetic sum: [...] or aCollection
> >>> arithmetic avg.
> >>
> >>
> >> Interesting thought!
> >
> > +100
> >
> > Doru
> >
> >>>
> >>> My two cents for this.
> >>>
> >>> Regards!
> >>>
> >>>
> >>> Esteban A. Maringolo
> >>>
> >>
> >>
> >
> > --
> > www.tudorgirba.com
> >
> > "Every thing has its own flow."
> >
> >
> >
> >
> >




Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-02 Thread Max Leske
Even though we haven’t been able to completely agree on the resolution, I feel 
we can agree that we need to change something. I’ve opened an issue and copied 
the messages from this thread into it for documentation.

https://pharo.fogbugz.com/f/cases/17174/Unify-sum-sum-sumNumbers-and-detectSum

Cheers,
Max


> On 01 Dec 2015, at 18:41, Sven Van Caekenberghe  wrote:
> 
> 
>> On 01 Dec 2015, at 17:43, Tudor Girba  wrote:
>> 
>> Hi,
>> 
>>> On Dec 1, 2015, at 3:24 PM, Sven Van Caekenberghe  wrote:
>>> 
>>> Doru,
>>> 
 On 01 Dec 2015, at 15:11, Tudor Girba  wrote:
 
 Hi,
 
> On Dec 1, 2015, at 12:52 PM, Sven Van Caekenberghe  wrote:
> 
> 
>> On 01 Dec 2015, at 12:45, Stephan Eggermont  wrote:
>> 
>> On 01-12-15 11:46, Sven Van Caekenberghe wrote:
>>> The basic question for me is, what should
>>> 
>>> #() sum
>>> 
>>> return. Right now, it is an error, I would very much like that for this 
>>> common case the result would be 0. There is a lot of power (easy of 
>>> use) in a unary selector, we should not destroy that with semantics 
>>> that force a test before using it.
>> 
>> I like the error, it aligns with most of our collection protocol.
> 
> I hate the error, a lot ;-)
> 
>> It shows the need for #sum:ifEmpty: though
> 
> Yes, as long as #() sum == 0 
 
 That won’t work :).
>>> 
>>> Why ? Please explain.
>>> 
> I want the simplest case to be simple, having a non-0 default is a 
> special case IMHO
 
 That is why you have sumNumbers:. We could also add Collection>>sumNumbers.
 
 We had this discussion at length before Pharo 4, and this is when we 
 agreed to add sumNumbers: and let sum: be generic (like the name says it 
 should be) and not assume that it should work with Numbers.
>>> 
>>> It is not about numbers or not, you are still using #+ in your generic 
>>> case, that is numeric in my book. It is about the zero element and how to 
>>> deal with an empty collection.
>>> 
>>> The current solution, which was indeed recently added, leaves the problem 
>>> of what to do with an empty collection. There is no general solution, you 
>>> have to specify a zero element.
>> 
>> Exactly.
>> 
>>> But for most people in most cases that will be effectively 0, so lets make 
>>> the unary #sum respect that. (And unary #sum will also work for non-empty 
>>> non-zero based objects). The less common case can then use the longer 
>>> message.
>> 
>> You said it correctly: “most” :). That is why, a generic meaning should be 
>> left generic and provide a solution that will work with “all” cases :).
>> 
>> It’s a matter of choice, but sum: has a too generic meaning to have it 
>> confined to numbers.
> 
> I think we all mean the same thing and understand each other's point.
> 
> But the first meaning of 'sum' in Wikipedia leads to 
> https://en.wikipedia.org/wiki/Summation which talks about numbers. I studied 
> partly Mathematics, so I know there are different numeric systems and 
> abstractions. My point is: the common case is adding (simple) numbers, the 
> special case is the more general one, hence the best selector, #sum, should 
> work for the common case, including for the empty one.
> 
> Consider also Ben's link:
> 
> https://en.wikipedia.org/wiki/Empty_sum
> 
> Hence my suggestion to change #sum to
> 
> | sum sample |
> self isEmpty ifTrue: [ ^ 0 ].
> sample := self anyOne.
> sum := self inject: sample into: [ :accum :each | accum + each ].
> ^ sum - sample
> 
> And the same for #sum:
> 
> Note that the above *will* work for all like today, just not if they are 
> empty. Now, of course we will need the ifEmpty: variants for what I consider 
> the less common cases. 
> 
> Can I also remark that both #inject:into: and #fold: are perfectly fine for 
> more involved cases. We have a lot of API ;-)
> 
>> Cheers,
>> Doru
>> 
 Cheers,
 Doru
 
> 
>> Stephan
>> 
>> 
>> 
> 
> 
 
 --
 www.tudorgirba.com
 
 "Speaking louder won't make the point worthier."
>>> 
>>> 
>> 
>> --
>> www.tudorgirba.com
>> 
>> "Next time you see your life passing by, say 'hi' and get to know her."
> 
> 




Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-02 Thread Ben Coman
On Wed, Dec 2, 2015 at 12:38 AM, Tudor Girba  wrote:
> Hi,
>
>> On Dec 1, 2015, at 5:13 PM, Max Leske  wrote:
>>
>> @Doru
>> You’re missing the point: #anyOne *fails* for empty collections.
>
> I am not missing the point at all. I am saying that if you want sum: to be 
> generic, it cannot assume a specific Zero object.
>
> And sum: should be generic because of its name.

I am missing understanding the other use cases.  Can you describe
further the generic nature of #sum & #sum: ?  I would have thought by
default they only applied to numbers.

cheers -ben

>
>>> On 01 Dec 2015, at 15:31, Esteban A. Maringolo  wrote:
>>>
>>> I don't want to be heretic (or too orthodox), but why not to delegate
>>> this behavior to other class (an iterator maybe?).
>>>
>>> It's too tempting adding these convenience methods to Collection
>>> and/or subclasses, but anything that requires an explicit protocol of
>>> its elements is wrong, IMO.
>>>
>>> something like aCollection arithmetic sum: [...] or aCollection
>>> arithmetic avg.
>>
>>
>> Interesting thought!
>
> +100
>
> Doru
>
>>>
>>> My two cents for this.
>>>
>>> Regards!
>>>
>>>
>>> Esteban A. Maringolo
>>>
>>
>>
>
> --
> www.tudorgirba.com
>
> "Every thing has its own flow."
>
>
>
>
>



Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-01 Thread J.F. Rick
Lovely little discussion which would be great for beginning OO programmers
to see. The question of whether to return 0 for an empty collection is
interesting. While other things can be summed, we tend to think of sums
returning numbers. In that sense, 0 is a great default return. On the other
hand, having a specific object for a generic sum function is problematic
(+1). There is a real tension and that would be a great discussion for
people to have. Either way, the need for sumIfEmpty: is obvious.

Cheers,

Jeff

On Tue, Dec 1, 2015 at 11:19 AM Ben Coman  wrote:

> On Tue, Dec 1, 2015 at 10:24 PM, Sven Van Caekenberghe 
> wrote:
> > Doru,
> >
> >> On 01 Dec 2015, at 15:11, Tudor Girba  wrote:
> >>
> >> Hi,
> >>
> >>> On Dec 1, 2015, at 12:52 PM, Sven Van Caekenberghe 
> wrote:
> >>>
> >>>
>  On 01 Dec 2015, at 12:45, Stephan Eggermont  wrote:
> 
>  On 01-12-15 11:46, Sven Van Caekenberghe wrote:
> > The basic question for me is, what should
> >
> > #() sum
> >
> > return. Right now, it is an error, I would very much like that for
> this common case the result would be 0. There is a lot of power (easy of
> use) in a unary selector, we should not destroy that with semantics that
> force a test before using it.
> 
>  I like the error, it aligns with most of our collection protocol.
> >>>
> >>> I hate the error, a lot ;-)
> >>>
>  It shows the need for #sum:ifEmpty: though
> >>>
> >>> Yes, as long as #() sum == 0
> >>
> >> That won’t work :).
> >
> > Why ? Please explain.
> >
> >>> I want the simplest case to be simple, having a non-0 default is a
> special case IMHO
> >>
> >> That is why you have sumNumbers:. We could also add
> Collection>>sumNumbers.
> >>
> >> We had this discussion at length before Pharo 4, and this is when we
> agreed to add sumNumbers: and let sum: be generic (like the name says it
> should be) and not assume that it should work with Numbers.
> >
> > It is not about numbers or not, you are still using #+ in your generic
> case, that is numeric in my book. It is about the zero element and how to
> deal with an empty collection.
> >
> > The current solution, which was indeed recently added, leaves the
> problem of what to do with an empty collection. There is no general
> solution, you have to specify a zero element.
> >
> > But for most people in most cases that will be effectively 0, so lets
> make the unary #sum respect that. (And unary #sum will also work for
> non-empty non-zero based objects). The less common case can then use the
> longer message.
>
> https://en.wikipedia.org/wiki/Empty_sum
>
>


Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-01 Thread Tudor Girba
Hi,

> On Dec 1, 2015, at 3:24 PM, Sven Van Caekenberghe  wrote:
> 
> Doru,
> 
>> On 01 Dec 2015, at 15:11, Tudor Girba  wrote:
>> 
>> Hi,
>> 
>>> On Dec 1, 2015, at 12:52 PM, Sven Van Caekenberghe  wrote:
>>> 
>>> 
 On 01 Dec 2015, at 12:45, Stephan Eggermont  wrote:
 
 On 01-12-15 11:46, Sven Van Caekenberghe wrote:
> The basic question for me is, what should
> 
> #() sum
> 
> return. Right now, it is an error, I would very much like that for this 
> common case the result would be 0. There is a lot of power (easy of use) 
> in a unary selector, we should not destroy that with semantics that force 
> a test before using it.
 
 I like the error, it aligns with most of our collection protocol.
>>> 
>>> I hate the error, a lot ;-)
>>> 
 It shows the need for #sum:ifEmpty: though
>>> 
>>> Yes, as long as #() sum == 0 
>> 
>> That won’t work :).
> 
> Why ? Please explain.
> 
>>> I want the simplest case to be simple, having a non-0 default is a special 
>>> case IMHO
>> 
>> That is why you have sumNumbers:. We could also add Collection>>sumNumbers.
>> 
>> We had this discussion at length before Pharo 4, and this is when we agreed 
>> to add sumNumbers: and let sum: be generic (like the name says it should be) 
>> and not assume that it should work with Numbers.
> 
> It is not about numbers or not, you are still using #+ in your generic case, 
> that is numeric in my book. It is about the zero element and how to deal with 
> an empty collection.
> 
> The current solution, which was indeed recently added, leaves the problem of 
> what to do with an empty collection. There is no general solution, you have 
> to specify a zero element.

Exactly.

> But for most people in most cases that will be effectively 0, so lets make 
> the unary #sum respect that. (And unary #sum will also work for non-empty 
> non-zero based objects). The less common case can then use the longer message.

You said it correctly: “most” :). That is why, a generic meaning should be left 
generic and provide a solution that will work with “all” cases :).

It’s a matter of choice, but sum: has a too generic meaning to have it confined 
to numbers.

Cheers,
Doru

>> Cheers,
>> Doru
>> 
>>> 
 Stephan
 
 
 
>>> 
>>> 
>> 
>> --
>> www.tudorgirba.com
>> 
>> "Speaking louder won't make the point worthier."
> 
> 

--
www.tudorgirba.com

"Next time you see your life passing by, say 'hi' and get to know her."






Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-01 Thread Sven Van Caekenberghe

> On 01 Dec 2015, at 17:43, Tudor Girba  wrote:
> 
> Hi,
> 
>> On Dec 1, 2015, at 3:24 PM, Sven Van Caekenberghe  wrote:
>> 
>> Doru,
>> 
>>> On 01 Dec 2015, at 15:11, Tudor Girba  wrote:
>>> 
>>> Hi,
>>> 
 On Dec 1, 2015, at 12:52 PM, Sven Van Caekenberghe  wrote:
 
 
> On 01 Dec 2015, at 12:45, Stephan Eggermont  wrote:
> 
> On 01-12-15 11:46, Sven Van Caekenberghe wrote:
>> The basic question for me is, what should
>> 
>> #() sum
>> 
>> return. Right now, it is an error, I would very much like that for this 
>> common case the result would be 0. There is a lot of power (easy of use) 
>> in a unary selector, we should not destroy that with semantics that 
>> force a test before using it.
> 
> I like the error, it aligns with most of our collection protocol.
 
 I hate the error, a lot ;-)
 
> It shows the need for #sum:ifEmpty: though
 
 Yes, as long as #() sum == 0 
>>> 
>>> That won’t work :).
>> 
>> Why ? Please explain.
>> 
 I want the simplest case to be simple, having a non-0 default is a special 
 case IMHO
>>> 
>>> That is why you have sumNumbers:. We could also add Collection>>sumNumbers.
>>> 
>>> We had this discussion at length before Pharo 4, and this is when we agreed 
>>> to add sumNumbers: and let sum: be generic (like the name says it should 
>>> be) and not assume that it should work with Numbers.
>> 
>> It is not about numbers or not, you are still using #+ in your generic case, 
>> that is numeric in my book. It is about the zero element and how to deal 
>> with an empty collection.
>> 
>> The current solution, which was indeed recently added, leaves the problem of 
>> what to do with an empty collection. There is no general solution, you have 
>> to specify a zero element.
> 
> Exactly.
> 
>> But for most people in most cases that will be effectively 0, so lets make 
>> the unary #sum respect that. (And unary #sum will also work for non-empty 
>> non-zero based objects). The less common case can then use the longer 
>> message.
> 
> You said it correctly: “most” :). That is why, a generic meaning should be 
> left generic and provide a solution that will work with “all” cases :).
> 
> It’s a matter of choice, but sum: has a too generic meaning to have it 
> confined to numbers.

I think we all mean the same thing and understand each other's point.

But the first meaning of 'sum' in Wikipedia leads to 
https://en.wikipedia.org/wiki/Summation which talks about numbers. I studied 
partly Mathematics, so I know there are different numeric systems and 
abstractions. My point is: the common case is adding (simple) numbers, the 
special case is the more general one, hence the best selector, #sum, should 
work for the common case, including for the empty one.

Consider also Ben's link:

https://en.wikipedia.org/wiki/Empty_sum

Hence my suggestion to change #sum to

| sum sample |
self isEmpty ifTrue: [ ^ 0 ].
sample := self anyOne.
sum := self inject: sample into: [ :accum :each | accum + each ].
^ sum - sample

And the same for #sum:

Note that the above *will* work for all like today, just not if they are empty. 
Now, of course we will need the ifEmpty: variants for what I consider the less 
common cases. 

Can I also remark that both #inject:into: and #fold: are perfectly fine for 
more involved cases. We have a lot of API ;-)

> Cheers,
> Doru
> 
>>> Cheers,
>>> Doru
>>> 
 
> Stephan
> 
> 
> 
 
 
>>> 
>>> --
>>> www.tudorgirba.com
>>> 
>>> "Speaking louder won't make the point worthier."
>> 
>> 
> 
> --
> www.tudorgirba.com
> 
> "Next time you see your life passing by, say 'hi' and get to know her."




Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-01 Thread Thierry Goubier
Note that the sum with #anyOne is wrong.

#(1 2 3 4 5) inject: #(1 2 3 4 5) anyOne into: [ :sum :each | sum + each ]

returns 16 instead of 15.

Thierry

2015-12-01 10:18 GMT+01:00 Ben Coman :

> On Tue, Dec 1, 2015 at 4:45 PM, Sven Van Caekenberghe 
> wrote:
> > I am all for a cleanup, the current situation is confusing.
> > The basic #sum should be fast AND work for empty collections with 0 as
> starting element.
>
> > I know why the #anyOne is used, and that use case should be preserved,
> but it is less common IMHO.
>
> I'm curious to be learn why?
> cheers -ben
>
> >
> >> On 01 Dec 2015, at 09:38, Thierry Goubier 
> wrote:
> >>
> >> Hi Max,
> >>
> >> Interesting results...
> >>
> >> replacing the #yourself in newSum: cuts the runtime by a factor of two.
> >> using an [:x | x ] block cost 10% compared to a direct version of sum.
> >>
> >> So the fastest sum is:
> >>
> >> sum
> >>   ^ self
> >>   inject:
> >>   (self ifEmpty: [ ^ 0 ] ifNotEmpty: [ self anyOne
> ])
> >>   into: [ :sum :each | sum + each ]
> >>
> >> And
> >>
> >> sum
> >> ^ self sum: [:x | x ]
> >>
> >> is 10% slower.
> >>
> >> And
> >>
> >> sum
> >> ^ self sum: #yourself
> >>
> >> is 100% slower (i.e. x2)
> >>
> >> It may be wise to avoid using #yourself for a block.
> >>
> >> Thierry
> >>
> >>
> >> 2015-12-01 9:17 GMT+01:00 Max Leske :
> >> Hi guys,
> >>
> >> Collection defines #sum:, #detectSum: and #sumNumbers:, all of which
> accomplish the same (in principal) but with subtle differences:
> >>
> >> #sum:
> >> - uses #inject:into: with #anyOne as the injected element and will thus
> fail for empty collections
> >>
> >> #detectSum:
> >> - uses “nextValue + sum” instead of “sum + nextValue” which makes it a
> lot slower when dealing with large numbers (primitive fails and number
> conversion is necessary)
> >>
> >> #sumNumbers:
> >> - same as #sum but doesn’t fail for empty collections. Only good for
> numbers though.
> >>
> >>
> >> Benchmarks:
> >>
> >> [ 100 timesRepeat: [ (1 to: 100) sum: #yourself ] ] timeToRun 18062
> >> [ 100 timesRepeat: [ (1 to: 100) detectSum: #yourself ] ] timeToRun
> 42391
> >> [ 100 timesRepeat: [ (1 to: 100) sumNumbers: #yourself ] ]
> timeToRun 18096
> >>
> >>
> >>
> >> Can we settle for a single implementation? Such as (modified from
> #sumNumbers:):
> >>
> >> newSum: aBlock
> >> ^ self
> >> inject: (self
> >> ifEmpty: [ 0 ]
> >> ifNotEmpty: [ self anyOne ])
> >> into: [ :sum :each |  sum + (aBlock value: each) ]
> >>
> >> This implementation combines the best of the three implementations I
> think. Benchmark:
> >>
> >> [ 100 timesRepeat: [ (1 to: 100) newSum: #yourself ] ] timeToRun
> 17955
> >>
> >>
> >> BTW, there is also the message #sum, which suffers from the same
> problem as #sum: (the implementation is basically a copy). #sum could be
> implemented as
> >>
> >> sum
> >> ^ self sum: [ :x | x ]
> >>
> >>
> >> As for the name for the new method, I suggest #sum:.
> >>
> >> Cheers,
> >> Max
> >>
> >
> >
>
>


Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-01 Thread Thierry Goubier
Hi Max,

Interesting results...

replacing the #yourself in newSum: cuts the runtime by a factor of two.
using an [:x | x ] block cost 10% compared to a direct version of sum.

So the fastest sum is:

sum
^ self
inject:
(self ifEmpty: [ ^ 0 ] ifNotEmpty: [ self anyOne ])
into: [ :sum :each | sum + each ]

And

sum
^ self sum: [:x | x ]

is 10% slower.

And

sum
^ self sum: #yourself

is 100% slower (i.e. x2)

It may be wise to avoid using #yourself for a block.

Thierry


2015-12-01 9:17 GMT+01:00 Max Leske :

> Hi guys,
>
> Collection defines #sum:, #detectSum: and #sumNumbers:, all of which
> accomplish the same (in principal) but with subtle differences:
>
> #sum:
> - uses #inject:into: with #anyOne as the injected element and will thus
> fail for empty collections
>
> #detectSum:
> - uses “nextValue + sum” instead of “sum + nextValue” which makes it a lot
> slower when dealing with large numbers (primitive fails and number
> conversion is necessary)
>
> #sumNumbers:
> - same as #sum but doesn’t fail for empty collections. Only good for
> numbers though.
>
>
> Benchmarks:
>
> [ 100 timesRepeat: [ (1 to: 100) sum: #yourself ] ] timeToRun 18062
> [ 100 timesRepeat: [ (1 to: 100) detectSum: #yourself ] ] timeToRun
> 42391
> [ 100 timesRepeat: [ (1 to: 100) sumNumbers: #yourself ] ] timeToRun
> 18096
>
>
>
> Can we settle for a single implementation? Such as (modified from
> #sumNumbers:):
>
> newSum: aBlock
> ^ self
> inject: (self
> ifEmpty: [ 0 ]
> ifNotEmpty: [ self anyOne ])
> into: [ :sum :each |  sum + (aBlock value: each) ]
>
> This implementation combines the best of the three implementations I
> think. Benchmark:
>
> [ 100 timesRepeat: [ (1 to: 100) newSum: #yourself ] ] timeToRun 17955
>
>
> BTW, there is also the message #sum, which suffers from the same problem
> as #sum: (the implementation is basically a copy). #sum could be
> implemented as
>
> sum
> ^ self sum: [ :x | x ]
>
>
> As for the name for the new method, I suggest #sum:.
>
> Cheers,
> Max
>


Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-01 Thread Peter Uhnak
The differences between #sum: and #sumNumbers: are well described in
the respective method comments, but I agree that this may be a problem
as most people will go for #sum: even for basic numeric collections.
(And I personally got bit by this.)

So maybe #sum: could adopt #sumNumbers: implementation, and the current
#sum: implementation would be moved to #domainSum: (or some other
appropriate name...)?

As for #detectSum: I think this method has confusing name and is
functionally duplicate to #sum:.

The swapped arguments there may make sense when you overload #+, however
the same thing can be achieved from the provided block ...


On 12/01, Max Leske wrote:
> Hi guys,
> 
> Collection defines #sum:, #detectSum: and #sumNumbers:, all of which 
> accomplish the same (in principal) but with subtle differences:
> 
> #sum:
> - uses #inject:into: with #anyOne as the injected element and will thus fail 
> for empty collections
> 
> #detectSum:
> - uses “nextValue + sum” instead of “sum + nextValue” which makes it a lot 
> slower when dealing with large numbers (primitive fails and number conversion 
> is necessary)
> 
> #sumNumbers:
> - same as #sum but doesn’t fail for empty collections. Only good for numbers 
> though.
> 
> 
> Benchmarks:
> 
> [ 100 timesRepeat: [ (1 to: 100) sum: #yourself ] ] timeToRun 18062
> [ 100 timesRepeat: [ (1 to: 100) detectSum: #yourself ] ] timeToRun 42391
> [ 100 timesRepeat: [ (1 to: 100) sumNumbers: #yourself ] ] timeToRun 18096
> 
> 
> 
> Can we settle for a single implementation? Such as (modified from 
> #sumNumbers:):
> 
> newSum: aBlock
>   ^ self 
>   inject: (self
>   ifEmpty: [ 0 ]
>   ifNotEmpty: [ self anyOne ]) 
>   into: [ :sum :each |  sum + (aBlock value: each) ]
> 
> This implementation combines the best of the three implementations I think. 
> Benchmark:
> 
> [ 100 timesRepeat: [ (1 to: 100) newSum: #yourself ] ] timeToRun 17955
> 
> 
> BTW, there is also the message #sum, which suffers from the same problem as 
> #sum: (the implementation is basically a copy). #sum could be implemented as
> 
> sum
>   ^ self sum: [ :x | x ]
> 
> 
> As for the name for the new method, I suggest #sum:.
> 
> Cheers,
> Max

-- 
Peter



Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-01 Thread Sven Van Caekenberghe
I am all for a cleanup, the current situation is confusing.
The basic #sum should be fast AND work for empty collections with 0 as starting 
element.
I know why the #anyOne is used, and that use case should be preserved, but it 
is less common IMHO.

> On 01 Dec 2015, at 09:38, Thierry Goubier  wrote:
> 
> Hi Max,
> 
> Interesting results...
> 
> replacing the #yourself in newSum: cuts the runtime by a factor of two.
> using an [:x | x ] block cost 10% compared to a direct version of sum.
> 
> So the fastest sum is:
> 
> sum
>   ^ self
>   inject:
>   (self ifEmpty: [ ^ 0 ] ifNotEmpty: [ self anyOne ])
>   into: [ :sum :each | sum + each ]
> 
> And
> 
> sum
> ^ self sum: [:x | x ]
> 
> is 10% slower.
> 
> And
> 
> sum
> ^ self sum: #yourself
> 
> is 100% slower (i.e. x2)
> 
> It may be wise to avoid using #yourself for a block.
> 
> Thierry
> 
> 
> 2015-12-01 9:17 GMT+01:00 Max Leske :
> Hi guys,
> 
> Collection defines #sum:, #detectSum: and #sumNumbers:, all of which 
> accomplish the same (in principal) but with subtle differences:
> 
> #sum:
> - uses #inject:into: with #anyOne as the injected element and will thus fail 
> for empty collections
> 
> #detectSum:
> - uses “nextValue + sum” instead of “sum + nextValue” which makes it a lot 
> slower when dealing with large numbers (primitive fails and number conversion 
> is necessary)
> 
> #sumNumbers:
> - same as #sum but doesn’t fail for empty collections. Only good for numbers 
> though.
> 
> 
> Benchmarks:
> 
> [ 100 timesRepeat: [ (1 to: 100) sum: #yourself ] ] timeToRun 18062
> [ 100 timesRepeat: [ (1 to: 100) detectSum: #yourself ] ] timeToRun 42391
> [ 100 timesRepeat: [ (1 to: 100) sumNumbers: #yourself ] ] timeToRun 18096
> 
> 
> 
> Can we settle for a single implementation? Such as (modified from 
> #sumNumbers:):
> 
> newSum: aBlock
> ^ self
> inject: (self
> ifEmpty: [ 0 ]
> ifNotEmpty: [ self anyOne ])
> into: [ :sum :each |  sum + (aBlock value: each) ]
> 
> This implementation combines the best of the three implementations I think. 
> Benchmark:
> 
> [ 100 timesRepeat: [ (1 to: 100) newSum: #yourself ] ] timeToRun 17955
> 
> 
> BTW, there is also the message #sum, which suffers from the same problem as 
> #sum: (the implementation is basically a copy). #sum could be implemented as
> 
> sum
> ^ self sum: [ :x | x ]
> 
> 
> As for the name for the new method, I suggest #sum:.
> 
> Cheers,
> Max
> 




Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-01 Thread Ben Coman
On Tue, Dec 1, 2015 at 4:45 PM, Sven Van Caekenberghe  wrote:
> I am all for a cleanup, the current situation is confusing.
> The basic #sum should be fast AND work for empty collections with 0 as 
> starting element.

> I know why the #anyOne is used, and that use case should be preserved, but it 
> is less common IMHO.

I'm curious to be learn why?
cheers -ben

>
>> On 01 Dec 2015, at 09:38, Thierry Goubier  wrote:
>>
>> Hi Max,
>>
>> Interesting results...
>>
>> replacing the #yourself in newSum: cuts the runtime by a factor of two.
>> using an [:x | x ] block cost 10% compared to a direct version of sum.
>>
>> So the fastest sum is:
>>
>> sum
>>   ^ self
>>   inject:
>>   (self ifEmpty: [ ^ 0 ] ifNotEmpty: [ self anyOne ])
>>   into: [ :sum :each | sum + each ]
>>
>> And
>>
>> sum
>> ^ self sum: [:x | x ]
>>
>> is 10% slower.
>>
>> And
>>
>> sum
>> ^ self sum: #yourself
>>
>> is 100% slower (i.e. x2)
>>
>> It may be wise to avoid using #yourself for a block.
>>
>> Thierry
>>
>>
>> 2015-12-01 9:17 GMT+01:00 Max Leske :
>> Hi guys,
>>
>> Collection defines #sum:, #detectSum: and #sumNumbers:, all of which 
>> accomplish the same (in principal) but with subtle differences:
>>
>> #sum:
>> - uses #inject:into: with #anyOne as the injected element and will thus fail 
>> for empty collections
>>
>> #detectSum:
>> - uses “nextValue + sum” instead of “sum + nextValue” which makes it a lot 
>> slower when dealing with large numbers (primitive fails and number 
>> conversion is necessary)
>>
>> #sumNumbers:
>> - same as #sum but doesn’t fail for empty collections. Only good for numbers 
>> though.
>>
>>
>> Benchmarks:
>>
>> [ 100 timesRepeat: [ (1 to: 100) sum: #yourself ] ] timeToRun 18062
>> [ 100 timesRepeat: [ (1 to: 100) detectSum: #yourself ] ] timeToRun 42391
>> [ 100 timesRepeat: [ (1 to: 100) sumNumbers: #yourself ] ] timeToRun 
>> 18096
>>
>>
>>
>> Can we settle for a single implementation? Such as (modified from 
>> #sumNumbers:):
>>
>> newSum: aBlock
>> ^ self
>> inject: (self
>> ifEmpty: [ 0 ]
>> ifNotEmpty: [ self anyOne ])
>> into: [ :sum :each |  sum + (aBlock value: each) ]
>>
>> This implementation combines the best of the three implementations I think. 
>> Benchmark:
>>
>> [ 100 timesRepeat: [ (1 to: 100) newSum: #yourself ] ] timeToRun 17955
>>
>>
>> BTW, there is also the message #sum, which suffers from the same problem as 
>> #sum: (the implementation is basically a copy). #sum could be implemented as
>>
>> sum
>> ^ self sum: [ :x | x ]
>>
>>
>> As for the name for the new method, I suggest #sum:.
>>
>> Cheers,
>> Max
>>
>
>



Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-01 Thread Sven Van Caekenberghe

> On 01 Dec 2015, at 10:24, Thierry Goubier  wrote:
> 
> Note that the sum with #anyOne is wrong.
> 
> #(1 2 3 4 5) inject: #(1 2 3 4 5) anyOne into: [ :sum :each | sum + each ]
> 
> returns 16 instead of 15.

You have subtract the element you picked with #anyOne !

> Thierry
> 
> 2015-12-01 10:18 GMT+01:00 Ben Coman :
> On Tue, Dec 1, 2015 at 4:45 PM, Sven Van Caekenberghe  wrote:
> > I am all for a cleanup, the current situation is confusing.
> > The basic #sum should be fast AND work for empty collections with 0 as 
> > starting element.
> 
> > I know why the #anyOne is used, and that use case should be preserved, but 
> > it is less common IMHO.
> 
> I'm curious to be learn why?
> cheers -ben
> 
> >
> >> On 01 Dec 2015, at 09:38, Thierry Goubier  
> >> wrote:
> >>
> >> Hi Max,
> >>
> >> Interesting results...
> >>
> >> replacing the #yourself in newSum: cuts the runtime by a factor of two.
> >> using an [:x | x ] block cost 10% compared to a direct version of sum.
> >>
> >> So the fastest sum is:
> >>
> >> sum
> >>   ^ self
> >>   inject:
> >>   (self ifEmpty: [ ^ 0 ] ifNotEmpty: [ self anyOne ])
> >>   into: [ :sum :each | sum + each ]
> >>
> >> And
> >>
> >> sum
> >> ^ self sum: [:x | x ]
> >>
> >> is 10% slower.
> >>
> >> And
> >>
> >> sum
> >> ^ self sum: #yourself
> >>
> >> is 100% slower (i.e. x2)
> >>
> >> It may be wise to avoid using #yourself for a block.
> >>
> >> Thierry
> >>
> >>
> >> 2015-12-01 9:17 GMT+01:00 Max Leske :
> >> Hi guys,
> >>
> >> Collection defines #sum:, #detectSum: and #sumNumbers:, all of which 
> >> accomplish the same (in principal) but with subtle differences:
> >>
> >> #sum:
> >> - uses #inject:into: with #anyOne as the injected element and will thus 
> >> fail for empty collections
> >>
> >> #detectSum:
> >> - uses “nextValue + sum” instead of “sum + nextValue” which makes it a lot 
> >> slower when dealing with large numbers (primitive fails and number 
> >> conversion is necessary)
> >>
> >> #sumNumbers:
> >> - same as #sum but doesn’t fail for empty collections. Only good for 
> >> numbers though.
> >>
> >>
> >> Benchmarks:
> >>
> >> [ 100 timesRepeat: [ (1 to: 100) sum: #yourself ] ] timeToRun 18062
> >> [ 100 timesRepeat: [ (1 to: 100) detectSum: #yourself ] ] timeToRun 
> >> 42391
> >> [ 100 timesRepeat: [ (1 to: 100) sumNumbers: #yourself ] ] timeToRun 
> >> 18096
> >>
> >>
> >>
> >> Can we settle for a single implementation? Such as (modified from 
> >> #sumNumbers:):
> >>
> >> newSum: aBlock
> >> ^ self
> >> inject: (self
> >> ifEmpty: [ 0 ]
> >> ifNotEmpty: [ self anyOne ])
> >> into: [ :sum :each |  sum + (aBlock value: each) ]
> >>
> >> This implementation combines the best of the three implementations I 
> >> think. Benchmark:
> >>
> >> [ 100 timesRepeat: [ (1 to: 100) newSum: #yourself ] ] timeToRun 17955
> >>
> >>
> >> BTW, there is also the message #sum, which suffers from the same problem 
> >> as #sum: (the implementation is basically a copy). #sum could be 
> >> implemented as
> >>
> >> sum
> >> ^ self sum: [ :x | x ]
> >>
> >>
> >> As for the name for the new method, I suggest #sum:.
> >>
> >> Cheers,
> >> Max
> >>
> >
> >
> 
> 




Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-01 Thread Sven Van Caekenberghe

> On 01 Dec 2015, at 10:18, Ben Coman  wrote:
> 
> On Tue, Dec 1, 2015 at 4:45 PM, Sven Van Caekenberghe  wrote:
>> I am all for a cleanup, the current situation is confusing.
>> The basic #sum should be fast AND work for empty collections with 0 as 
>> starting element.
> 
>> I know why the #anyOne is used, and that use case should be preserved, but 
>> it is less common IMHO.
> 
> I'm curious to be learn why?

How many times have you summed a collection of things, where (1) you could not 
start from the number 0 and (2) the operation was #+ ? Me, never, and if I 
would need that, I would do an #inject:into: myself. Any counter examples that 
occur a lot ?

> cheers -ben
> 
>> 
>>> On 01 Dec 2015, at 09:38, Thierry Goubier  wrote:
>>> 
>>> Hi Max,
>>> 
>>> Interesting results...
>>> 
>>> replacing the #yourself in newSum: cuts the runtime by a factor of two.
>>> using an [:x | x ] block cost 10% compared to a direct version of sum.
>>> 
>>> So the fastest sum is:
>>> 
>>> sum
>>>  ^ self
>>>  inject:
>>>  (self ifEmpty: [ ^ 0 ] ifNotEmpty: [ self anyOne ])
>>>  into: [ :sum :each | sum + each ]
>>> 
>>> And
>>> 
>>> sum
>>>^ self sum: [:x | x ]
>>> 
>>> is 10% slower.
>>> 
>>> And
>>> 
>>> sum
>>>^ self sum: #yourself
>>> 
>>> is 100% slower (i.e. x2)
>>> 
>>> It may be wise to avoid using #yourself for a block.
>>> 
>>> Thierry
>>> 
>>> 
>>> 2015-12-01 9:17 GMT+01:00 Max Leske :
>>> Hi guys,
>>> 
>>> Collection defines #sum:, #detectSum: and #sumNumbers:, all of which 
>>> accomplish the same (in principal) but with subtle differences:
>>> 
>>> #sum:
>>> - uses #inject:into: with #anyOne as the injected element and will thus 
>>> fail for empty collections
>>> 
>>> #detectSum:
>>> - uses “nextValue + sum” instead of “sum + nextValue” which makes it a lot 
>>> slower when dealing with large numbers (primitive fails and number 
>>> conversion is necessary)
>>> 
>>> #sumNumbers:
>>> - same as #sum but doesn’t fail for empty collections. Only good for 
>>> numbers though.
>>> 
>>> 
>>> Benchmarks:
>>> 
>>> [ 100 timesRepeat: [ (1 to: 100) sum: #yourself ] ] timeToRun 18062
>>> [ 100 timesRepeat: [ (1 to: 100) detectSum: #yourself ] ] timeToRun 
>>> 42391
>>> [ 100 timesRepeat: [ (1 to: 100) sumNumbers: #yourself ] ] timeToRun 
>>> 18096
>>> 
>>> 
>>> 
>>> Can we settle for a single implementation? Such as (modified from 
>>> #sumNumbers:):
>>> 
>>> newSum: aBlock
>>>^ self
>>>inject: (self
>>>ifEmpty: [ 0 ]
>>>ifNotEmpty: [ self anyOne ])
>>>into: [ :sum :each |  sum + (aBlock value: each) ]
>>> 
>>> This implementation combines the best of the three implementations I think. 
>>> Benchmark:
>>> 
>>> [ 100 timesRepeat: [ (1 to: 100) newSum: #yourself ] ] timeToRun 17955
>>> 
>>> 
>>> BTW, there is also the message #sum, which suffers from the same problem as 
>>> #sum: (the implementation is basically a copy). #sum could be implemented as
>>> 
>>> sum
>>>^ self sum: [ :x | x ]
>>> 
>>> 
>>> As for the name for the new method, I suggest #sum:.
>>> 
>>> Cheers,
>>> Max
>>> 
>> 
>> 
> 




Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-01 Thread Nicolai Hess
2015-12-01 10:26 GMT+01:00 Sven Van Caekenberghe :

>
> > On 01 Dec 2015, at 10:24, Thierry Goubier 
> wrote:
> >
> > Note that the sum with #anyOne is wrong.
> >
> > #(1 2 3 4 5) inject: #(1 2 3 4 5) anyOne into: [ :sum :each | sum + each
> ]
> >
> > returns 16 instead of 15.
>
> You have subtract the element you picked with #anyOne !
>

I think he means the suggested implementation for newSum is wrong, just
because of this reason.



>
> > Thierry
> >
> > 2015-12-01 10:18 GMT+01:00 Ben Coman :
> > On Tue, Dec 1, 2015 at 4:45 PM, Sven Van Caekenberghe 
> wrote:
> > > I am all for a cleanup, the current situation is confusing.
> > > The basic #sum should be fast AND work for empty collections with 0 as
> starting element.
> >
> > > I know why the #anyOne is used, and that use case should be preserved,
> but it is less common IMHO.
> >
> > I'm curious to be learn why?
> > cheers -ben
> >
> > >
> > >> On 01 Dec 2015, at 09:38, Thierry Goubier 
> wrote:
> > >>
> > >> Hi Max,
> > >>
> > >> Interesting results...
> > >>
> > >> replacing the #yourself in newSum: cuts the runtime by a factor of
> two.
> > >> using an [:x | x ] block cost 10% compared to a direct version of sum.
> > >>
> > >> So the fastest sum is:
> > >>
> > >> sum
> > >>   ^ self
> > >>   inject:
> > >>   (self ifEmpty: [ ^ 0 ] ifNotEmpty: [ self
> anyOne ])
> > >>   into: [ :sum :each | sum + each ]
> > >>
> > >> And
> > >>
> > >> sum
> > >> ^ self sum: [:x | x ]
> > >>
> > >> is 10% slower.
> > >>
> > >> And
> > >>
> > >> sum
> > >> ^ self sum: #yourself
> > >>
> > >> is 100% slower (i.e. x2)
> > >>
> > >> It may be wise to avoid using #yourself for a block.
> > >>
> > >> Thierry
> > >>
> > >>
> > >> 2015-12-01 9:17 GMT+01:00 Max Leske :
> > >> Hi guys,
> > >>
> > >> Collection defines #sum:, #detectSum: and #sumNumbers:, all of which
> accomplish the same (in principal) but with subtle differences:
> > >>
> > >> #sum:
> > >> - uses #inject:into: with #anyOne as the injected element and will
> thus fail for empty collections
> > >>
> > >> #detectSum:
> > >> - uses “nextValue + sum” instead of “sum + nextValue” which makes it
> a lot slower when dealing with large numbers (primitive fails and number
> conversion is necessary)
> > >>
> > >> #sumNumbers:
> > >> - same as #sum but doesn’t fail for empty collections. Only good for
> numbers though.
> > >>
> > >>
> > >> Benchmarks:
> > >>
> > >> [ 100 timesRepeat: [ (1 to: 100) sum: #yourself ] ] timeToRun
> 18062
> > >> [ 100 timesRepeat: [ (1 to: 100) detectSum: #yourself ] ]
> timeToRun 42391
> > >> [ 100 timesRepeat: [ (1 to: 100) sumNumbers: #yourself ] ]
> timeToRun 18096
> > >>
> > >>
> > >>
> > >> Can we settle for a single implementation? Such as (modified from
> #sumNumbers:):
> > >>
> > >> newSum: aBlock
> > >> ^ self
> > >> inject: (self
> > >> ifEmpty: [ 0 ]
> > >> ifNotEmpty: [ self anyOne ])
> > >> into: [ :sum :each |  sum + (aBlock value: each) ]
> > >>
> > >> This implementation combines the best of the three implementations I
> think. Benchmark:
> > >>
> > >> [ 100 timesRepeat: [ (1 to: 100) newSum: #yourself ] ] timeToRun
> 17955
> > >>
> > >>
> > >> BTW, there is also the message #sum, which suffers from the same
> problem as #sum: (the implementation is basically a copy). #sum could be
> implemented as
> > >>
> > >> sum
> > >> ^ self sum: [ :x | x ]
> > >>
> > >>
> > >> As for the name for the new method, I suggest #sum:.
> > >>
> > >> Cheers,
> > >> Max
> > >>
> > >
> > >
> >
> >
>
>
>


Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-01 Thread Nicolai Hess
2015-12-01 10:26 GMT+01:00 Sven Van Caekenberghe :

>
> > On 01 Dec 2015, at 10:18, Ben Coman  wrote:
> >
> > On Tue, Dec 1, 2015 at 4:45 PM, Sven Van Caekenberghe 
> wrote:
> >> I am all for a cleanup, the current situation is confusing.
> >> The basic #sum should be fast AND work for empty collections with 0 as
> starting element.
> >
> >> I know why the #anyOne is used, and that use case should be preserved,
> but it is less common IMHO.
> >
> > I'm curious to be learn why?
>
> How many times have you summed a collection of things, where (1) you could
> not start from the number 0 and (2) the operation was #+ ? Me, never, and
> if I would need that, I would do an #inject:into: myself. Any counter
> examples that occur a lot ?
>

wokring with things like Color

(Color wheel:10) sum "works"
(Color wheel:10) newSum:#yourself " would not work"



>
> > cheers -ben
> >
> >>
> >>> On 01 Dec 2015, at 09:38, Thierry Goubier 
> wrote:
> >>>
> >>> Hi Max,
> >>>
> >>> Interesting results...
> >>>
> >>> replacing the #yourself in newSum: cuts the runtime by a factor of two.
> >>> using an [:x | x ] block cost 10% compared to a direct version of sum.
> >>>
> >>> So the fastest sum is:
> >>>
> >>> sum
> >>>  ^ self
> >>>  inject:
> >>>  (self ifEmpty: [ ^ 0 ] ifNotEmpty: [ self anyOne
> ])
> >>>  into: [ :sum :each | sum + each ]
> >>>
> >>> And
> >>>
> >>> sum
> >>>^ self sum: [:x | x ]
> >>>
> >>> is 10% slower.
> >>>
> >>> And
> >>>
> >>> sum
> >>>^ self sum: #yourself
> >>>
> >>> is 100% slower (i.e. x2)
> >>>
> >>> It may be wise to avoid using #yourself for a block.
> >>>
> >>> Thierry
> >>>
> >>>
> >>> 2015-12-01 9:17 GMT+01:00 Max Leske :
> >>> Hi guys,
> >>>
> >>> Collection defines #sum:, #detectSum: and #sumNumbers:, all of which
> accomplish the same (in principal) but with subtle differences:
> >>>
> >>> #sum:
> >>> - uses #inject:into: with #anyOne as the injected element and will
> thus fail for empty collections
> >>>
> >>> #detectSum:
> >>> - uses “nextValue + sum” instead of “sum + nextValue” which makes it a
> lot slower when dealing with large numbers (primitive fails and number
> conversion is necessary)
> >>>
> >>> #sumNumbers:
> >>> - same as #sum but doesn’t fail for empty collections. Only good for
> numbers though.
> >>>
> >>>
> >>> Benchmarks:
> >>>
> >>> [ 100 timesRepeat: [ (1 to: 100) sum: #yourself ] ] timeToRun 18062
> >>> [ 100 timesRepeat: [ (1 to: 100) detectSum: #yourself ] ]
> timeToRun 42391
> >>> [ 100 timesRepeat: [ (1 to: 100) sumNumbers: #yourself ] ]
> timeToRun 18096
> >>>
> >>>
> >>>
> >>> Can we settle for a single implementation? Such as (modified from
> #sumNumbers:):
> >>>
> >>> newSum: aBlock
> >>>^ self
> >>>inject: (self
> >>>ifEmpty: [ 0 ]
> >>>ifNotEmpty: [ self anyOne ])
> >>>into: [ :sum :each |  sum + (aBlock value: each) ]
> >>>
> >>> This implementation combines the best of the three implementations I
> think. Benchmark:
> >>>
> >>> [ 100 timesRepeat: [ (1 to: 100) newSum: #yourself ] ] timeToRun
> 17955
> >>>
> >>>
> >>> BTW, there is also the message #sum, which suffers from the same
> problem as #sum: (the implementation is basically a copy). #sum could be
> implemented as
> >>>
> >>> sum
> >>>^ self sum: [ :x | x ]
> >>>
> >>>
> >>> As for the name for the new method, I suggest #sum:.
> >>>
> >>> Cheers,
> >>> Max
> >>>
> >>
> >>
> >
>
>
>


Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-01 Thread Thierry Goubier
2015-12-01 10:29 GMT+01:00 Nicolai Hess :

>
>
> 2015-12-01 10:26 GMT+01:00 Sven Van Caekenberghe :
>
>>
>> > On 01 Dec 2015, at 10:24, Thierry Goubier 
>> wrote:
>> >
>> > Note that the sum with #anyOne is wrong.
>> >
>> > #(1 2 3 4 5) inject: #(1 2 3 4 5) anyOne into: [ :sum :each | sum +
>> each ]
>> >
>> > returns 16 instead of 15.
>>
>> You have subtract the element you picked with #anyOne !
>>
>
> I think he means the suggested implementation for newSum is wrong, just
> because of this reason.
>
> Exactly ;)

Thierry


Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-01 Thread Sven Van Caekenberghe
The basic question for me is, what should

  #() sum

return. Right now, it is an error, I would very much like that for this common 
case the result would be 0. There is a lot of power (easy of use) in a unary 
selector, we should not destroy that with semantics that force a test before 
using it.

If we agree on that, we could change the #sum to

| sum sample |
self isEmpty ifTrue: [ ^ 0 ].
sample := self anyOne.
sum := self inject: sample into: [ :accum :each | accum + each ].
^ sum - sample

And the same for #sum:

As for #detectSum: that should be removed I think.

> On 01 Dec 2015, at 10:33, Nicolai Hess  wrote:
> 
> 
> 
> 2015-12-01 10:26 GMT+01:00 Sven Van Caekenberghe :
> 
> > On 01 Dec 2015, at 10:18, Ben Coman  wrote:
> >
> > On Tue, Dec 1, 2015 at 4:45 PM, Sven Van Caekenberghe  wrote:
> >> I am all for a cleanup, the current situation is confusing.
> >> The basic #sum should be fast AND work for empty collections with 0 as 
> >> starting element.
> >
> >> I know why the #anyOne is used, and that use case should be preserved, but 
> >> it is less common IMHO.
> >
> > I'm curious to be learn why?
> 
> How many times have you summed a collection of things, where (1) you could 
> not start from the number 0 and (2) the operation was #+ ? Me, never, and if 
> I would need that, I would do an #inject:into: myself. Any counter examples 
> that occur a lot ?
> 
> wokring with things like Color
> 
> (Color wheel:10) sum "works"
> (Color wheel:10) newSum:#yourself " would not work"
> 
>  
> 
> > cheers -ben
> >
> >>
> >>> On 01 Dec 2015, at 09:38, Thierry Goubier  
> >>> wrote:
> >>>
> >>> Hi Max,
> >>>
> >>> Interesting results...
> >>>
> >>> replacing the #yourself in newSum: cuts the runtime by a factor of two.
> >>> using an [:x | x ] block cost 10% compared to a direct version of sum.
> >>>
> >>> So the fastest sum is:
> >>>
> >>> sum
> >>>  ^ self
> >>>  inject:
> >>>  (self ifEmpty: [ ^ 0 ] ifNotEmpty: [ self anyOne ])
> >>>  into: [ :sum :each | sum + each ]
> >>>
> >>> And
> >>>
> >>> sum
> >>>^ self sum: [:x | x ]
> >>>
> >>> is 10% slower.
> >>>
> >>> And
> >>>
> >>> sum
> >>>^ self sum: #yourself
> >>>
> >>> is 100% slower (i.e. x2)
> >>>
> >>> It may be wise to avoid using #yourself for a block.
> >>>
> >>> Thierry
> >>>
> >>>
> >>> 2015-12-01 9:17 GMT+01:00 Max Leske :
> >>> Hi guys,
> >>>
> >>> Collection defines #sum:, #detectSum: and #sumNumbers:, all of which 
> >>> accomplish the same (in principal) but with subtle differences:
> >>>
> >>> #sum:
> >>> - uses #inject:into: with #anyOne as the injected element and will thus 
> >>> fail for empty collections
> >>>
> >>> #detectSum:
> >>> - uses “nextValue + sum” instead of “sum + nextValue” which makes it a 
> >>> lot slower when dealing with large numbers (primitive fails and number 
> >>> conversion is necessary)
> >>>
> >>> #sumNumbers:
> >>> - same as #sum but doesn’t fail for empty collections. Only good for 
> >>> numbers though.
> >>>
> >>>
> >>> Benchmarks:
> >>>
> >>> [ 100 timesRepeat: [ (1 to: 100) sum: #yourself ] ] timeToRun 18062
> >>> [ 100 timesRepeat: [ (1 to: 100) detectSum: #yourself ] ] timeToRun 
> >>> 42391
> >>> [ 100 timesRepeat: [ (1 to: 100) sumNumbers: #yourself ] ] timeToRun 
> >>> 18096
> >>>
> >>>
> >>>
> >>> Can we settle for a single implementation? Such as (modified from 
> >>> #sumNumbers:):
> >>>
> >>> newSum: aBlock
> >>>^ self
> >>>inject: (self
> >>>ifEmpty: [ 0 ]
> >>>ifNotEmpty: [ self anyOne ])
> >>>into: [ :sum :each |  sum + (aBlock value: each) ]
> >>>
> >>> This implementation combines the best of the three implementations I 
> >>> think. Benchmark:
> >>>
> >>> [ 100 timesRepeat: [ (1 to: 100) newSum: #yourself ] ] timeToRun 17955
> >>>
> >>>
> >>> BTW, there is also the message #sum, which suffers from the same problem 
> >>> as #sum: (the implementation is basically a copy). #sum could be 
> >>> implemented as
> >>>
> >>> sum
> >>>^ self sum: [ :x | x ]
> >>>
> >>>
> >>> As for the name for the new method, I suggest #sum:.
> >>>
> >>> Cheers,
> >>> Max
> >>>
> >>
> >>
> >
> 
> 
> 




Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-01 Thread Thierry Goubier
2015-12-01 11:46 GMT+01:00 Sven Van Caekenberghe :

> The basic question for me is, what should
>
>   #() sum
>
> return. Right now, it is an error, I would very much like that for this
> common case the result would be 0. There is a lot of power (easy of use) in
> a unary selector, we should not destroy that with semantics that force a
> test before using it.
>

Yes, this is just that a 0 value is returned for an empty collection, and,
if you're expecting a sum of Colors, then this is a bit strange.

Returning an error on a sum for an empty collection is maybe an overall
cleaner concept

Which can be expressed as:

I prefer this code:

aCollectionOfColors isEmpty
ifTrue: [ sumOfColors := aDefaultColor ]
ifFalse: [ sumOfColors := aCollectionOfColors sum ]

To this code:

sumOfColors := aCollectionOfColors sum.
sumOfColors = 0
ifTrue: [ sumOfColors := aDefaultColor ]


>
> If we agree on that, we could change the #sum to
>
> | sum sample |
> self isEmpty ifTrue: [ ^ 0 ].
> sample := self anyOne.
> sum := self inject: sample into: [ :accum :each | accum + each ].
> ^ sum - sample
>

Ok, now I really like this implementation. Elegant.

Thierry


>
> And the same for #sum:
>
> As for #detectSum: that should be removed I think.
>
> > On 01 Dec 2015, at 10:33, Nicolai Hess  wrote:
> >
> >
> >
> > 2015-12-01 10:26 GMT+01:00 Sven Van Caekenberghe :
> >
> > > On 01 Dec 2015, at 10:18, Ben Coman  wrote:
> > >
> > > On Tue, Dec 1, 2015 at 4:45 PM, Sven Van Caekenberghe 
> wrote:
> > >> I am all for a cleanup, the current situation is confusing.
> > >> The basic #sum should be fast AND work for empty collections with 0
> as starting element.
> > >
> > >> I know why the #anyOne is used, and that use case should be
> preserved, but it is less common IMHO.
> > >
> > > I'm curious to be learn why?
> >
> > How many times have you summed a collection of things, where (1) you
> could not start from the number 0 and (2) the operation was #+ ? Me, never,
> and if I would need that, I would do an #inject:into: myself. Any counter
> examples that occur a lot ?
> >
> > wokring with things like Color
> >
> > (Color wheel:10) sum "works"
> > (Color wheel:10) newSum:#yourself " would not work"
> >
> >
> >
> > > cheers -ben
> > >
> > >>
> > >>> On 01 Dec 2015, at 09:38, Thierry Goubier 
> wrote:
> > >>>
> > >>> Hi Max,
> > >>>
> > >>> Interesting results...
> > >>>
> > >>> replacing the #yourself in newSum: cuts the runtime by a factor of
> two.
> > >>> using an [:x | x ] block cost 10% compared to a direct version of
> sum.
> > >>>
> > >>> So the fastest sum is:
> > >>>
> > >>> sum
> > >>>  ^ self
> > >>>  inject:
> > >>>  (self ifEmpty: [ ^ 0 ] ifNotEmpty: [ self
> anyOne ])
> > >>>  into: [ :sum :each | sum + each ]
> > >>>
> > >>> And
> > >>>
> > >>> sum
> > >>>^ self sum: [:x | x ]
> > >>>
> > >>> is 10% slower.
> > >>>
> > >>> And
> > >>>
> > >>> sum
> > >>>^ self sum: #yourself
> > >>>
> > >>> is 100% slower (i.e. x2)
> > >>>
> > >>> It may be wise to avoid using #yourself for a block.
> > >>>
> > >>> Thierry
> > >>>
> > >>>
> > >>> 2015-12-01 9:17 GMT+01:00 Max Leske :
> > >>> Hi guys,
> > >>>
> > >>> Collection defines #sum:, #detectSum: and #sumNumbers:, all of which
> accomplish the same (in principal) but with subtle differences:
> > >>>
> > >>> #sum:
> > >>> - uses #inject:into: with #anyOne as the injected element and will
> thus fail for empty collections
> > >>>
> > >>> #detectSum:
> > >>> - uses “nextValue + sum” instead of “sum + nextValue” which makes it
> a lot slower when dealing with large numbers (primitive fails and number
> conversion is necessary)
> > >>>
> > >>> #sumNumbers:
> > >>> - same as #sum but doesn’t fail for empty collections. Only good for
> numbers though.
> > >>>
> > >>>
> > >>> Benchmarks:
> > >>>
> > >>> [ 100 timesRepeat: [ (1 to: 100) sum: #yourself ] ] timeToRun
> 18062
> > >>> [ 100 timesRepeat: [ (1 to: 100) detectSum: #yourself ] ]
> timeToRun 42391
> > >>> [ 100 timesRepeat: [ (1 to: 100) sumNumbers: #yourself ] ]
> timeToRun 18096
> > >>>
> > >>>
> > >>>
> > >>> Can we settle for a single implementation? Such as (modified from
> #sumNumbers:):
> > >>>
> > >>> newSum: aBlock
> > >>>^ self
> > >>>inject: (self
> > >>>ifEmpty: [ 0 ]
> > >>>ifNotEmpty: [ self anyOne ])
> > >>>into: [ :sum :each |  sum + (aBlock value: each) ]
> > >>>
> > >>> This implementation combines the best of the three implementations I
> think. Benchmark:
> > >>>
> > >>> [ 100 timesRepeat: [ (1 to: 100) newSum: #yourself ] ] timeToRun
> 17955
> > >>>
> > >>>
> > >>> BTW, there is also the message #sum, which suffers from the same
> problem as #sum: (the implementation is basically a copy). #sum could be
> 

Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-01 Thread Peter Uhnak
On 12/01, Thierry Goubier wrote:
> 2015-12-01 11:46 GMT+01:00 Sven Van Caekenberghe :
> 
> > The basic question for me is, what should
> >
> >   #() sum
> >
> > return. Right now, it is an error, I would very much like that for this
> > common case the result would be 0. There is a lot of power (easy of use) in
> > a unary selector, we should not destroy that with semantics that force a
> > test before using it.
> >
> 
> Yes, this is just that a 0 value is returned for an empty collection, and,
> if you're expecting a sum of Colors, then this is a bit strange.
> 
> Returning an error on a sum for an empty collection is maybe an overall
> cleaner concept
> 
> Which can be expressed as:
> 
> I prefer this code:
> 
> aCollectionOfColors isEmpty
> ifTrue: [ sumOfColors := aDefaultColor ]
> ifFalse: [ sumOfColors := aCollectionOfColors sum ]
> 
> To this code:
> 
> sumOfColors := aCollectionOfColors sum.
> sumOfColors = 0
> ifTrue: [ sumOfColors := aDefaultColor ]

or

sumOfColors := (aCollectionOfColors ifEmpty: [ {aDefaultColor} ]) sum.

> 
> 
> >
> > If we agree on that, we could change the #sum to
> >
> > | sum sample |
> > self isEmpty ifTrue: [ ^ 0 ].
> > sample := self anyOne.
> > sum := self inject: sample into: [ :accum :each | accum + each ].
> > ^ sum - sample
> >
> 
> Ok, now I really like this implementation. Elegant.

Why the temp variables?

self ifEmpty: [ ^ 0 ].
^ self inject: self anyOne negated into: [ :sum :each | sum + each ]

But more importantly, if the empty/default is 0 then what is the reason for 
#anyOne?
Otherwise you are mixing things.

self ifEmpty: [ ^ 0 ].
^ self inject: 0 into: [ :sum :each | sum + each ].

Peter

> 
> Thierry
> 
> 
> >
> > And the same for #sum:
> >
> > As for #detectSum: that should be removed I think.
> >
> > > On 01 Dec 2015, at 10:33, Nicolai Hess  wrote:
> > >
> > >
> > >
> > > 2015-12-01 10:26 GMT+01:00 Sven Van Caekenberghe :
> > >
> > > > On 01 Dec 2015, at 10:18, Ben Coman  wrote:
> > > >
> > > > On Tue, Dec 1, 2015 at 4:45 PM, Sven Van Caekenberghe 
> > wrote:
> > > >> I am all for a cleanup, the current situation is confusing.
> > > >> The basic #sum should be fast AND work for empty collections with 0
> > as starting element.
> > > >
> > > >> I know why the #anyOne is used, and that use case should be
> > preserved, but it is less common IMHO.
> > > >
> > > > I'm curious to be learn why?
> > >
> > > How many times have you summed a collection of things, where (1) you
> > could not start from the number 0 and (2) the operation was #+ ? Me, never,
> > and if I would need that, I would do an #inject:into: myself. Any counter
> > examples that occur a lot ?
> > >
> > > wokring with things like Color
> > >
> > > (Color wheel:10) sum "works"
> > > (Color wheel:10) newSum:#yourself " would not work"
> > >
> > >
> > >
> > > > cheers -ben
> > > >
> > > >>
> > > >>> On 01 Dec 2015, at 09:38, Thierry Goubier 
> > wrote:
> > > >>>
> > > >>> Hi Max,
> > > >>>
> > > >>> Interesting results...
> > > >>>
> > > >>> replacing the #yourself in newSum: cuts the runtime by a factor of
> > two.
> > > >>> using an [:x | x ] block cost 10% compared to a direct version of
> > sum.
> > > >>>
> > > >>> So the fastest sum is:
> > > >>>
> > > >>> sum
> > > >>>  ^ self
> > > >>>  inject:
> > > >>>  (self ifEmpty: [ ^ 0 ] ifNotEmpty: [ self
> > anyOne ])
> > > >>>  into: [ :sum :each | sum + each ]
> > > >>>
> > > >>> And
> > > >>>
> > > >>> sum
> > > >>>^ self sum: [:x | x ]
> > > >>>
> > > >>> is 10% slower.
> > > >>>
> > > >>> And
> > > >>>
> > > >>> sum
> > > >>>^ self sum: #yourself
> > > >>>
> > > >>> is 100% slower (i.e. x2)
> > > >>>
> > > >>> It may be wise to avoid using #yourself for a block.
> > > >>>
> > > >>> Thierry
> > > >>>
> > > >>>
> > > >>> 2015-12-01 9:17 GMT+01:00 Max Leske :
> > > >>> Hi guys,
> > > >>>
> > > >>> Collection defines #sum:, #detectSum: and #sumNumbers:, all of which
> > accomplish the same (in principal) but with subtle differences:
> > > >>>
> > > >>> #sum:
> > > >>> - uses #inject:into: with #anyOne as the injected element and will
> > thus fail for empty collections
> > > >>>
> > > >>> #detectSum:
> > > >>> - uses “nextValue + sum” instead of “sum + nextValue” which makes it
> > a lot slower when dealing with large numbers (primitive fails and number
> > conversion is necessary)
> > > >>>
> > > >>> #sumNumbers:
> > > >>> - same as #sum but doesn’t fail for empty collections. Only good for
> > numbers though.
> > > >>>
> > > >>>
> > > >>> Benchmarks:
> > > >>>
> > > >>> [ 100 timesRepeat: [ (1 to: 100) sum: #yourself ] ] timeToRun
> > 18062
> > > >>> [ 100 timesRepeat: [ (1 to: 100) detectSum: #yourself ] ]
> > timeToRun 42391
> > > >>> [ 100 timesRepeat: [ (1 to: 100) sumNumbers: #yourself ] ]
> > timeToRun 18096
> > > >>>
> > > 

Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-01 Thread Stephan Eggermont

On 01-12-15 11:46, Sven Van Caekenberghe wrote:

The basic question for me is, what should

   #() sum

return. Right now, it is an error, I would very much like that for this common 
case the result would be 0. There is a lot of power (easy of use) in a unary 
selector, we should not destroy that with semantics that force a test before 
using it.


I like the error, it aligns with most of our collection protocol.
It shows the need for #sum:ifEmpty: though

Stephan





Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-01 Thread Sven Van Caekenberghe

> On 01 Dec 2015, at 12:45, Stephan Eggermont  wrote:
> 
> On 01-12-15 11:46, Sven Van Caekenberghe wrote:
>> The basic question for me is, what should
>> 
>>   #() sum
>> 
>> return. Right now, it is an error, I would very much like that for this 
>> common case the result would be 0. There is a lot of power (easy of use) in 
>> a unary selector, we should not destroy that with semantics that force a 
>> test before using it.
> 
> I like the error, it aligns with most of our collection protocol.

I hate the error, a lot ;-)

> It shows the need for #sum:ifEmpty: though

Yes, as long as #() sum == 0 

I want the simplest case to be simple, having a non-0 default is a special case 
IMHO

> Stephan
> 
> 
> 




Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-01 Thread Yuriy Tymchuk
#sum:ifEmpty: looks nice

> On 01 Dec 2015, at 12:45, Stephan Eggermont  wrote:
> 
> On 01-12-15 11:46, Sven Van Caekenberghe wrote:
>> The basic question for me is, what should
>> 
>>   #() sum
>> 
>> return. Right now, it is an error, I would very much like that for this 
>> common case the result would be 0. There is a lot of power (easy of use) in 
>> a unary selector, we should not destroy that with semantics that force a 
>> test before using it.
> 
> I like the error, it aligns with most of our collection protocol.
> It shows the need for #sum:ifEmpty: though
> 
> Stephan
> 
> 
> 




Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-01 Thread Sven Van Caekenberghe
Doru,

> On 01 Dec 2015, at 15:11, Tudor Girba  wrote:
> 
> Hi,
> 
>> On Dec 1, 2015, at 12:52 PM, Sven Van Caekenberghe  wrote:
>> 
>> 
>>> On 01 Dec 2015, at 12:45, Stephan Eggermont  wrote:
>>> 
>>> On 01-12-15 11:46, Sven Van Caekenberghe wrote:
 The basic question for me is, what should
 
 #() sum
 
 return. Right now, it is an error, I would very much like that for this 
 common case the result would be 0. There is a lot of power (easy of use) 
 in a unary selector, we should not destroy that with semantics that force 
 a test before using it.
>>> 
>>> I like the error, it aligns with most of our collection protocol.
>> 
>> I hate the error, a lot ;-)
>> 
>>> It shows the need for #sum:ifEmpty: though
>> 
>> Yes, as long as #() sum == 0 
> 
> That won’t work :).

Why ? Please explain.

>> I want the simplest case to be simple, having a non-0 default is a special 
>> case IMHO
> 
> That is why you have sumNumbers:. We could also add Collection>>sumNumbers.
> 
> We had this discussion at length before Pharo 4, and this is when we agreed 
> to add sumNumbers: and let sum: be generic (like the name says it should be) 
> and not assume that it should work with Numbers.

It is not about numbers or not, you are still using #+ in your generic case, 
that is numeric in my book. It is about the zero element and how to deal with 
an empty collection.

The current solution, which was indeed recently added, leaves the problem of 
what to do with an empty collection. There is no general solution, you have to 
specify a zero element.

But for most people in most cases that will be effectively 0, so lets make the 
unary #sum respect that. (And unary #sum will also work for non-empty non-zero 
based objects). The less common case can then use the longer message.

> Cheers,
> Doru
> 
>> 
>>> Stephan
>>> 
>>> 
>>> 
>> 
>> 
> 
> --
> www.tudorgirba.com
> 
> "Speaking louder won't make the point worthier."




Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-01 Thread Esteban A. Maringolo
I don't want to be heretic (or too orthodox), but why not to delegate
this behavior to other class (an iterator maybe?).

It's too tempting adding these convenience methods to Collection
and/or subclasses, but anything that requires an explicit protocol of
its elements is wrong, IMO.

something like aCollection arithmetic sum: [...] or aCollection
arithmetic avg.

My two cents for this.

Regards!


Esteban A. Maringolo



Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-01 Thread Tudor Girba
Hi,

> On Dec 1, 2015, at 3:21 PM, Yuriy Tymchuk  wrote:
> 
>> 
>> On 01 Dec 2015, at 15:11, Tudor Girba  wrote:
>> 
>> Hi,
>> 
>>> On Dec 1, 2015, at 12:52 PM, Sven Van Caekenberghe  wrote:
>>> 
>>> 
 On 01 Dec 2015, at 12:45, Stephan Eggermont  wrote:
 
 On 01-12-15 11:46, Sven Van Caekenberghe wrote:
> The basic question for me is, what should
> 
> #() sum
> 
> return. Right now, it is an error, I would very much like that for this 
> common case the result would be 0. There is a lot of power (easy of use) 
> in a unary selector, we should not destroy that with semantics that force 
> a test before using it.
 
 I like the error, it aligns with most of our collection protocol.
>>> 
>>> I hate the error, a lot ;-)
>>> 
 It shows the need for #sum:ifEmpty: though
>>> 
>>> Yes, as long as #() sum == 0 
>> 
>> That won’t work :).
> 
> But wouldn’t it be nice to have #sum:ifEmpty:? I think that this is a nice 
> way to describe summing. Otherwise I have to do ifEmpty: [ something ] 
> ifNotEmpty: [ :col | col sum: … ]

Sure. That would be fine, and would leave the meaning of sum to work with 
non-numbers objects.

But, of course, you can also use sumNumbers: which starts from 0 not from 
anyOne and you will need no ifEmpty:.

Cheers,
Doru

> 
> Cheers.
> Uko
> 
>> 
>>> I want the simplest case to be simple, having a non-0 default is a special 
>>> case IMHO
>> 
>> That is why you have sumNumbers:. We could also add Collection>>sumNumbers.
>> 
>> We had this discussion at length before Pharo 4, and this is when we agreed 
>> to add sumNumbers: and let sum: be generic (like the name says it should be) 
>> and not assume that it should work with Numbers.
>> 
>> Cheers,
>> Doru
>> 
>>> 
 Stephan
 
 
 
>>> 
>>> 
>> 
>> --
>> www.tudorgirba.com
>> 
>> "Speaking louder won't make the point worthier."

--
www.tudorgirba.com

"There are no old things, there are only old ways of looking at them."






Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-01 Thread Max Leske
Well, I’m glad I've struck a nerve there :)

I agree that signalling an exception isn’t wrong, it’s just annoying because 
you have to do the check manually each time. I think I like #sum:ifEmpty:. When 
you look through the methods in Collection you’ll see #sum, #sum: and 
#sum:ifEmpty together in one place and it will be clear how to use them.

> On 01 Dec 2015, at 12:52, Sven Van Caekenberghe  wrote:
> 
> 
>> On 01 Dec 2015, at 12:45, Stephan Eggermont  wrote:
>> 
>> On 01-12-15 11:46, Sven Van Caekenberghe wrote:
>>> The basic question for me is, what should
>>> 
>>>  #() sum
>>> 
>>> return. Right now, it is an error, I would very much like that for this 
>>> common case the result would be 0. There is a lot of power (easy of use) in 
>>> a unary selector, we should not destroy that with semantics that force a 
>>> test before using it.
>> 
>> I like the error, it aligns with most of our collection protocol.
> 
> I hate the error, a lot ;-)

+1

> 
>> It shows the need for #sum:ifEmpty: though
> 
> Yes, as long as #() sum == 0 

+100

That allows for nice Smalltalk like “myNumbers sum isZero …”.



> 
> I want the simplest case to be simple, having a non-0 default is a special 
> case IMHO
> 
>> Stephan
>> 
>> 
>> 
> 
> 




Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-01 Thread Tudor Girba
Hi,

> On Dec 1, 2015, at 12:52 PM, Sven Van Caekenberghe  wrote:
> 
> 
>> On 01 Dec 2015, at 12:45, Stephan Eggermont  wrote:
>> 
>> On 01-12-15 11:46, Sven Van Caekenberghe wrote:
>>> The basic question for me is, what should
>>> 
>>>  #() sum
>>> 
>>> return. Right now, it is an error, I would very much like that for this 
>>> common case the result would be 0. There is a lot of power (easy of use) in 
>>> a unary selector, we should not destroy that with semantics that force a 
>>> test before using it.
>> 
>> I like the error, it aligns with most of our collection protocol.
> 
> I hate the error, a lot ;-)
> 
>> It shows the need for #sum:ifEmpty: though
> 
> Yes, as long as #() sum == 0 

That won’t work :).

> I want the simplest case to be simple, having a non-0 default is a special 
> case IMHO

That is why you have sumNumbers:. We could also add Collection>>sumNumbers.

We had this discussion at length before Pharo 4, and this is when we agreed to 
add sumNumbers: and let sum: be generic (like the name says it should be) and 
not assume that it should work with Numbers.

Cheers,
Doru

> 
>> Stephan
>> 
>> 
>> 
> 
> 

--
www.tudorgirba.com

"Speaking louder won't make the point worthier."




Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-01 Thread Yuriy Tymchuk

> On 01 Dec 2015, at 15:11, Tudor Girba  wrote:
> 
> Hi,
> 
>> On Dec 1, 2015, at 12:52 PM, Sven Van Caekenberghe  wrote:
>> 
>> 
>>> On 01 Dec 2015, at 12:45, Stephan Eggermont  wrote:
>>> 
>>> On 01-12-15 11:46, Sven Van Caekenberghe wrote:
 The basic question for me is, what should
 
 #() sum
 
 return. Right now, it is an error, I would very much like that for this 
 common case the result would be 0. There is a lot of power (easy of use) 
 in a unary selector, we should not destroy that with semantics that force 
 a test before using it.
>>> 
>>> I like the error, it aligns with most of our collection protocol.
>> 
>> I hate the error, a lot ;-)
>> 
>>> It shows the need for #sum:ifEmpty: though
>> 
>> Yes, as long as #() sum == 0 
> 
> That won’t work :).

But wouldn’t it be nice to have #sum:ifEmpty:? I think that this is a nice way 
to describe summing. Otherwise I have to do ifEmpty: [ something ] ifNotEmpty: 
[ :col | col sum: … ]

Cheers.
Uko

> 
>> I want the simplest case to be simple, having a non-0 default is a special 
>> case IMHO
> 
> That is why you have sumNumbers:. We could also add Collection>>sumNumbers.
> 
> We had this discussion at length before Pharo 4, and this is when we agreed 
> to add sumNumbers: and let sum: be generic (like the name says it should be) 
> and not assume that it should work with Numbers.
> 
> Cheers,
> Doru
> 
>> 
>>> Stephan
>>> 
>>> 
>>> 
>> 
>> 
> 
> --
> www.tudorgirba.com
> 
> "Speaking louder won't make the point worthier."
> 
> 




Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-01 Thread Max Leske
@Doru
You’re missing the point: #anyOne *fails* for empty collections.

> On 01 Dec 2015, at 15:31, Esteban A. Maringolo  wrote:
> 
> I don't want to be heretic (or too orthodox), but why not to delegate
> this behavior to other class (an iterator maybe?).
> 
> It's too tempting adding these convenience methods to Collection
> and/or subclasses, but anything that requires an explicit protocol of
> its elements is wrong, IMO.
> 
> something like aCollection arithmetic sum: [...] or aCollection
> arithmetic avg.


Interesting thought!

> 
> My two cents for this.
> 
> Regards!
> 
> 
> Esteban A. Maringolo
> 




Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-01 Thread Ben Coman
On Tue, Dec 1, 2015 at 10:24 PM, Sven Van Caekenberghe  wrote:
> Doru,
>
>> On 01 Dec 2015, at 15:11, Tudor Girba  wrote:
>>
>> Hi,
>>
>>> On Dec 1, 2015, at 12:52 PM, Sven Van Caekenberghe  wrote:
>>>
>>>
 On 01 Dec 2015, at 12:45, Stephan Eggermont  wrote:

 On 01-12-15 11:46, Sven Van Caekenberghe wrote:
> The basic question for me is, what should
>
> #() sum
>
> return. Right now, it is an error, I would very much like that for this 
> common case the result would be 0. There is a lot of power (easy of use) 
> in a unary selector, we should not destroy that with semantics that force 
> a test before using it.

 I like the error, it aligns with most of our collection protocol.
>>>
>>> I hate the error, a lot ;-)
>>>
 It shows the need for #sum:ifEmpty: though
>>>
>>> Yes, as long as #() sum == 0
>>
>> That won’t work :).
>
> Why ? Please explain.
>
>>> I want the simplest case to be simple, having a non-0 default is a special 
>>> case IMHO
>>
>> That is why you have sumNumbers:. We could also add Collection>>sumNumbers.
>>
>> We had this discussion at length before Pharo 4, and this is when we agreed 
>> to add sumNumbers: and let sum: be generic (like the name says it should be) 
>> and not assume that it should work with Numbers.
>
> It is not about numbers or not, you are still using #+ in your generic case, 
> that is numeric in my book. It is about the zero element and how to deal with 
> an empty collection.
>
> The current solution, which was indeed recently added, leaves the problem of 
> what to do with an empty collection. There is no general solution, you have 
> to specify a zero element.
>
> But for most people in most cases that will be effectively 0, so lets make 
> the unary #sum respect that. (And unary #sum will also work for non-empty 
> non-zero based objects). The less common case can then use the longer message.

https://en.wikipedia.org/wiki/Empty_sum



Re: [Pharo-dev] #sum:, #detectSum:, #sumNumbers:

2015-12-01 Thread Tudor Girba
Hi,

> On Dec 1, 2015, at 5:13 PM, Max Leske  wrote:
> 
> @Doru
> You’re missing the point: #anyOne *fails* for empty collections.

I am not missing the point at all. I am saying that if you want sum: to be 
generic, it cannot assume a specific Zero object.

And sum: should be generic because of its name.

>> On 01 Dec 2015, at 15:31, Esteban A. Maringolo  wrote:
>> 
>> I don't want to be heretic (or too orthodox), but why not to delegate
>> this behavior to other class (an iterator maybe?).
>> 
>> It's too tempting adding these convenience methods to Collection
>> and/or subclasses, but anything that requires an explicit protocol of
>> its elements is wrong, IMO.
>> 
>> something like aCollection arithmetic sum: [...] or aCollection
>> arithmetic avg.
> 
> 
> Interesting thought!

+100

Doru

>> 
>> My two cents for this.
>> 
>> Regards!
>> 
>> 
>> Esteban A. Maringolo
>> 
> 
> 

--
www.tudorgirba.com

"Every thing has its own flow."