Collection>sum fails on empty collection

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Collection>sum fails on empty collection

timrowledge
#() sum -> errorEmptyCollection.

#sum uses #reduce: and I can see why #reduce might consider an empty collection an error - but I also see that #sum of an empty collection probably ought to be 0, at least in a lot of cases. And I'd note that using a simple #inject:into: - in the case of a million item Array, at least - took about 60% of the time of the current #sum.

Why did this come up? In an MVC Project I tested
  PluggableFileList getFolderDialog openLabel: 'foo'
whilst seeing if PluggableFileList had any uses. It turns out that building a PluggableFileList in MVC doesn't work. Somewhere we end up trying to build a pluggablepanel with no children, which makes the logic in MVCToolBuilder>>setLayout:in: get upset. I don't care enough about making MVC stuff work to be willing to spend time on that.

tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
Fractured Idiom:- RIGOR MORRIS - The cat is dead



Reply | Threaded
Open this post in threaded view
|

Re: Collection>sum fails on empty collection

Eliot Miranda-2
Hi Tim,

On Tue, Jan 8, 2019 at 11:36 AM tim Rowledge <[hidden email]> wrote:
#() sum -> errorEmptyCollection.

#sum uses #reduce: and I can see why #reduce might consider an empty collection an error - but I also see that #sum of an empty collection probably ought to be 0, at least in a lot of cases. And I'd note that using a simple #inject:into: - in the case of a million item Array, at least - took about 60% of the time of the current #sum.

Why did this come up? In an MVC Project I tested
  PluggableFileList getFolderDialog openLabel: 'foo'
whilst seeing if PluggableFileList had any uses. It turns out that building a PluggableFileList in MVC doesn't work. Somewhere we end up trying to build a pluggablepanel with no children, which makes the logic in MVCToolBuilder>>setLayout:in: get upset. I don't care enough about making MVC stuff work to be willing to spend time on that.

IIRC we discussed this issue carefully.  The issue was typing.  Clearly one should only be able to compute the sum of a collection of numbers (or things that answer to + and can be an argument to 0 + ...).  So we wanted to check that there was at least one numbers element in the receiver and hence chose that sum should indeed fail for an empty collection.  It still seems like a reasonable choice to me.  see e.g. http://forum.world.st/squeak-dev-Re-Collection-gt-gt-sum-implementation-td77002.html#a77008

_,,,^..^,,,_
best, Eliot


Reply | Threaded
Open this post in threaded view
|

Re: Collection>sum fails on empty collection

timrowledge


> On 2019-01-08, at 12:10 PM, Eliot Miranda <[hidden email]> wrote:
>
> IIRC we discussed this issue carefully.  The issue was typing.  Clearly one should only be able to compute the sum of a collection of numbers (or things that answer to + and can be an argument to 0 + ...).  So we wanted to check that there was at least one numbers element in the receiver and hence chose that sum should indeed fail for an empty collection.  It still seems like a reasonable choice to me.  see e.g. http://forum.world.st/squeak-dev-Re-Collection-gt-gt-sum-implementation-td77002.html#a77008

I'm sure much thought was put into it; it's never easy trying to make really well crafted high-generality code. I certainly see the value for the #reduce: code as a general thing. I always did have a problem with messages like sum, average, median, and so on being implemented for general collections, for exactly the reason you point out - collections aren't all that often of purely numeric things.

In the particular case I stumbled over, the usage of #sum carries way too many assumptions and provides no way to recover from them. Indeed the entire algorithm in that part of the code collapses with a big "oh bugger".

tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
Useful Latin Phrases:- Sentio aliquos togatos contra me conspirare = I think some people in togas are plotting against me.



Reply | Threaded
Open this post in threaded view
|

Re: Collection>sum fails on empty collection

Nicolas Cellier
You can always write:

    ^collec inject: 0 into: #+

or whatever default zero you need:

   ^collec inject: 0@0 into: #+

Le mar. 8 janv. 2019 à 21:18, tim Rowledge <[hidden email]> a écrit :


> On 2019-01-08, at 12:10 PM, Eliot Miranda <[hidden email]> wrote:
>
> IIRC we discussed this issue carefully.  The issue was typing.  Clearly one should only be able to compute the sum of a collection of numbers (or things that answer to + and can be an argument to 0 + ...).  So we wanted to check that there was at least one numbers element in the receiver and hence chose that sum should indeed fail for an empty collection.  It still seems like a reasonable choice to me.  see e.g. http://forum.world.st/squeak-dev-Re-Collection-gt-gt-sum-implementation-td77002.html#a77008

I'm sure much thought was put into it; it's never easy trying to make really well crafted high-generality code. I certainly see the value for the #reduce: code as a general thing. I always did have a problem with messages like sum, average, median, and so on being implemented for general collections, for exactly the reason you point out - collections aren't all that often of purely numeric things.

In the particular case I stumbled over, the usage of #sum carries way too many assumptions and provides no way to recover from them. Indeed the entire algorithm in that part of the code collapses with a big "oh bugger".

tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
Useful Latin Phrases:- Sentio aliquos togatos contra me conspirare = I think some people in togas are plotting against me.





Reply | Threaded
Open this post in threaded view
|

Re: Collection>sum fails on empty collection

timrowledge


> On 2019-01-08, at 1:54 PM, Nicolas Cellier <[hidden email]> wrote:
>
> You can always write:
>
>     ^collec inject: 0 into: #+

I'd not spotted that particular neat trick before - like it. It's a really interesting example of Smalltalk cleverness to make a simple symbol work as a block. Nice!

tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
Multitasking:  Screwing up several things at once...



Reply | Threaded
Open this post in threaded view
|

Re: Collection>sum fails on empty collection

Levente Uzonyi
In reply to this post by timrowledge
Use #detectSum::

#() detectSum: #yourself. "==> 0"

It also gives you full control:

#(true false 1 2 3.5 'foo') detectSum: [ :each |
  each isNumber "Yes, this won't work for complex numbers and quaternions"
  ifTrue: [ each ]
  ifFalse: [ 0 ] ]. "==> 6.5"


Levente

On Tue, 8 Jan 2019, tim Rowledge wrote:

> #() sum -> errorEmptyCollection.
>
> #sum uses #reduce: and I can see why #reduce might consider an empty collection an error - but I also see that #sum of an empty collection probably ought to be 0, at least in a lot of cases. And I'd note that using a simple #inject:into: - in the case of a million item Array, at least - took about 60% of the time of the current #sum.
>
> Why did this come up? In an MVC Project I tested
>  PluggableFileList getFolderDialog openLabel: 'foo'
> whilst seeing if PluggableFileList had any uses. It turns out that building a PluggableFileList in MVC doesn't work. Somewhere we end up trying to build a pluggablepanel with no children, which makes the logic in MVCToolBuilder>>setLayout:in: get upset. I don't care enough about making MVC stuff work to be willing to spend time on that.
>
> tim
> --
> tim Rowledge; [hidden email]; http://www.rowledge.org/tim
> Fractured Idiom:- RIGOR MORRIS - The cat is dead

Reply | Threaded
Open this post in threaded view
|

Re: Collection>sum fails on empty collection

timrowledge


> On 2019-01-08, at 2:26 PM, Levente Uzonyi <[hidden email]> wrote:
>
> Use #detectSum::

Also cool and previously unknown to me. Neat!

tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
Strange OpCodes: RDRI: Rotate Disk Right Immediate