Add `fp` export
Add es-toolkit/fp export to support functional programming and pipeline syntax.
// example
pipe(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
filter(isEven),
map(double),
join(", "),
) // Expect: "4, 8, 12, 16, 20"
TODO
Scripts
- [x] Write a script to clone and convert existing functions into 'pipable' functions for pipelining.
- [ ] Enhance a script to clone and convert existing specs to fp-version specs.
Codes
- [ ] Write basic functions for fp (ex.
pipe,map,filter...) - [ ] Convert all available existing functions
Documents
- [ ] Write documents about
es-toolkit/fp
The latest updates on your projects. Learn more about Vercel for Git ↗︎
| Name | Status | Preview | Comments | Updated (UTC) |
|---|---|---|---|---|
| es-toolkit | ✅ Ready (Inspect) | Visit Preview | 💬 Add feedback | Jan 22, 2025 9:54am |
any progress on this thread?
While I am trying to work as quickly as possible, but it is not a very high priority, so I am falling behind. I hope to be able to work on it this week. 🥲
The syntax for the pipe function is planned as follows.
function toString(value: unknown) {
return `string:${value}`;
}
function toStringAsync(value: unknown) {
return Promise.resolve(`string:${value}`);
}
function length(value: string) {
return value.length;
}
const result = pipe(1, toString, length);
console.log(result); // 8
// Use pipe with async function
const asyncResult = await pipe(1, toStringAsync, length);
console.log(asyncResult); // 8
// Use pipe with curried function
const mapKeyResult = await pipe(
{ a: 1, b: 2 },
mapKeys((value, key) => key + value)
);
console.log(mapKeyResult); // { a1: 1, b2: 2 }
- receive the initial value as first parameter
- receive functions that process the value from the second parameter onward
- can handle async functions
bench result of pipe
As far as I remember, this team was not interested in that work, but it is a work that I am interested in.
But is there a reason why I have to copy the implementation? It also looks good to refer to the original function with curring to take the consistency of the implementation.
const pipeableCountBy = <T>(fn: (arg: T) => boolean) => (arr: Array<T>) => countBy(arr, fn);
pipe(
[1, 2, 3, 4],
pipeableCountBy(v => v % 2 == 0)
);
If you're not going to make it in consideration of curring from the beginning, like fxts, that seems to be the best option.
The advantage of p.spipe comes as a delay assessment. That's the linq of dotnet, that's the fxts, that's the effect-ts.
Maybe we don't need to copy original implementation even if there is a script for copying it... I agree with that idea.
But it would be better to keep current design that 'auto-currying' the function by number of received argument to avoid situations like the one below.
// BAD
import { omit } from "es-toolkit";
import { omit as pipableOmit } from "es-toolkit/fp";
const omitted = omit(obj, ['a', 'b']); // usage without pipe
// ...
pipe(
obj,
pipableOmit(['a', 'b'])
); // usage with pipe
// GOOD
import { omit } from "es-toolkit/fp";
const omitted = omit(obj, ['a', 'b']); // usage without pipe
// ...
pipe(
obj,
omit(['a', 'b'])
); // usage with pipe
I gonna fix the implementation and script to refer it, not copy the implementation of original one.
I think that's a good idea, too. The core of my story is to refer to the feature implementation to follow the original, but only to change the interface.
functions list in fp
array
- at
- chunk
- countBy
- difference
- differenceBy
- differenceWith
- drop
- dropRight
- dropRightWhile
- dropWhile
- every
- fill
- filter
- find
- findIndex
- flatMap
- flatMapDeep
- forEach
- forEachRight
- groupBy
- includes
- intersection
- intersectionBy
- intersectionWith
- isSubset
- join
- keyBy
- map
- maxBy
- minBy
- orderBy
- partition
- pullAt
- sampleSize
- slice
- some
- sort
- sortBy
- take
- takeRight
- takeRightWhile
- takeWhile
- union
- unionBy
- unionWith
- uniq
- uniqBy
- uniqWith
- unzipWith
- xor
- xorBy
- xorWith
- zipObject
core
- pipe
object
- mapKeys
- mapValues
- merge
- mergeWith
- omit
- omitBy
- pick
- pickBy
- toMerged
Are there already plans to review/merge this PR? Thanks
Are there already plans to review/merge this PR? Thanks
Sorry for late reply.
We're doing some discussions about details and there will be some changes in implementations!
Will fp package implement structural sharing based on object prototyping like lodash/fp does?
I'm planning to close this PR since it was not updated it for a long time.
If you plan to resume work on it, feel free to reopen.
Hi everyone, thanks a lot for your awesome work and dedication.
Is there any update regarding this? pipe and /fp?