nullobject/fkit

Feature request: expand the partition function

Closed this issue · 4 comments

First, I should say, what a fantastic library! A few more features for objects and I can see completely replacing UnderscoreJS or LodashJS.

Concerning the partition function, it would really be nice to see the function expanded to what we see here in the Mathematica documentation (http://reference.wolfram.com/language/ref/Partition.html), at least to the extent of the 4 cases below. I often times need to simply group elements in an array by nothing more complicated than the number of elements. If the index were exposed during iteration, there would be a way to do it with FLOOR. But it's inelegant.

I propose the following:

partition (n, as)
partition (a, as)
partition (n, o, as)
partition (a, o, as)

where n is an integer > 0, a is an array, and o is an offset >= 0. This would give the following:

partition (2, [1, 2, 4, 5, 7, 8, 9, 0, 3]) = [[1, 2], [4, 5], [7, 8], [9, 0], [3]]
partition([2, 2], [1, 2, 4, 5, 7, 8, 9, 0, 3]) = [[[1, 2], [4, 5]], [[7, 8 ], [9, 0]], [[3]]]
partition(2, 1, [1, 2, 4, 5, 7, 8, 9, 0, 3]) = [[1, 2], [2, 4], [4, 5], [5, 7], [7, 8], [8, 9], [9, 0], [0, 3]]
partition([2, 2], 1, [1, 2, 4, 5, 7, 8, 9, 0, 3]) = [[[1, 2], [2, 4]], [[4, 5 ], [5, 7]], [[7, 8], [8, 9]], [[9, 0], [0, 3]]]

Would you consider this a reasonable suggestion?

👎

Several reasons:

  • The optional argument in the middle makes it extremely difficult to curry effectively. (I am new to FKit, but have been working on a similar library Ramda for more than a year; we've essentially forbidden optional arguments entirely.)
  • The name partition has been used by Haskell as well as in other JS libraries such as Underscore and Ramda with pretty much the same semantics as it currently has in FKit.

If you want a function as described, I'd suggest you request a different name, maybe something like moduloList. I don't know FKit well enough yet to know how easy it would be to implement. In Ramda, a simplified version of it might just be

var moduloList = R.useWith(R.compose(R.values, R.groupBy), R.flip(R.modulo), R.I);

But this wouldn't handle the initial array or the offset.

Yes, I agree that currying must be taken into consideration, of course. I was merely expressing an idea or a notion of the format.

As for calling it something else, I would have to disagree. At base, functional libraries of this type must be rooted in the formalities of mathematics. There was sort of a reverse confusion for me when I encountered "partition" in Lodash and Underscore (not familiar with Ramda). It turns out their usage of the term is a bit of a misnomer, in my opinion: partitioning != conditional grouping.

Partitioning is a broad notion. Partitioning by what is essentially a modulus operation is only one possibility. The partitioning that these libraries are doing is based on a predicate function, splitting the input set into those that match the predicate and those that don't. I don't find that any less legitimate.

Ramda includes a separate notion, called groupBy, which allows you to group by the results of an arbitrary function. That function was also called partition at one point until we synchronized with the usage in other languages/libraries. I've gone and looked since the last message, and this is the same behavior in Scala. Clojure has one more like you're suggesting.

I do disagree somewhat with this:

[F]unctional libraries of this time must be rooted in the formalities of mathematics

Functional libraries of course take some of their inspiration from mathematics, but I don't think there is a reason to expect particularly deep roots in mathematical material. I know there is such a tradition, but I believe that it just as often hinders as it helps. (And my university training was in mathematics, so I'm not speaking entirely as an outsider.) When mathematical formalities conflict with other of our principles, I feel perfectly free to drop those formalities.

Hi @estaylorco, thanks for the suggestion.

I'm reluctant to move away from my current implementation of partition as it's pretty much the same as the Haskell version. I'm also deliberately avoiding overloading function parameters in FKit, my mandate is to keep things simple.

Let me know if you need help writing your function with FKit.