On 04 Dec 2015, at 01:49, Ben Coman <btc@openInWorld.com> wrote:
On Fri, Dec 4, 2015 at 4:23 AM, Nicolai Hess <nicolaihess@gmail.com <mailto:nicolaihess@gmail.com>> wrote:
2015-12-03 14:48 GMT+01:00 Ben Coman <btc@openinworld.com>:
On Wed, Dec 2, 2015 at 10:45 PM, Sven Van Caekenberghe <sven@stfx.eu> wrote:
On 02 Dec 2015, at 15:21, Nicolai Hess <nicolaihess@gmail.com> wrote:
2015-12-02 15:03 GMT+01:00 Ben Coman <btc@openinworld.com>: On Wed, Dec 2, 2015 at 12:38 AM, Tudor Girba <tudor@tudorgirba.com> wrote:
Hi,
On Dec 1, 2015, at 5:13 PM, Max Leske <maxleske@gmail.com> 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&oq=define+sum
https://www.google.com.au/search?q=define+concatenate&oq=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 usually are happy to work with numbers (which are already objects in Smalltalk anyway) and theyâre fast.
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 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 <emaringolo@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 arithmetic avg.
On Fri, Dec 4, 2015 at 3:26 AM, Chris Cunningham <cunningham.cb@gmail.com <mailto:cunningham.cb@gmail.com>> wrote:
<uncontrolled snipping>
On Thu, Dec 3, 2015 at 5:48 AM, Ben Coman <btc@openinworld.com <mailto:btc@openinworld.com>> 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.
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!