{"id":21701626,"url":"https://github.com/flintinatux/tinyfunk","last_synced_at":"2025-04-12T13:50:19.322Z","repository":{"id":148663678,"uuid":"104014983","full_name":"flintinatux/tinyfunk","owner":"flintinatux","description":"The tiniest of functional libraries","archived":false,"fork":false,"pushed_at":"2020-06-27T05:15:38.000Z","size":138,"stargazers_count":26,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-26T08:22:58.932Z","etag":null,"topics":["functional-programming","javascript","tiny"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/flintinatux.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-09-19T02:19:20.000Z","updated_at":"2024-02-08T19:53:32.000Z","dependencies_parsed_at":"2023-05-20T19:30:18.927Z","dependency_job_id":null,"html_url":"https://github.com/flintinatux/tinyfunk","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flintinatux%2Ftinyfunk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flintinatux%2Ftinyfunk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flintinatux%2Ftinyfunk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flintinatux%2Ftinyfunk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flintinatux","download_url":"https://codeload.github.com/flintinatux/tinyfunk/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248575434,"owners_count":21127185,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["functional-programming","javascript","tiny"],"created_at":"2024-11-25T20:24:53.708Z","updated_at":"2025-04-12T13:50:19.285Z","avatar_url":"https://github.com/flintinatux.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\" style=\"background:#c1282d;padding:20px;\"\u003e\n  \u003ca href=\"#\"\u003e\n    \u003cimg src=\"https://user-images.githubusercontent.com/888052/31304558-89193d0e-aaf1-11e7-8b46-3c2cd35347cf.png\" alt=\"tinyfunk\" style=\"max-width:100%;\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  The tiniest of functional libraries.\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.npmjs.com/package/tinyfunk\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/tinyfunk.svg\" alt=\"npm version\" style=\"max-width:100%;\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.npmjs.com/package/tinyfunk\"\u003e\u003cimg src=\"https://img.shields.io/npm/dm/tinyfunk.svg\" alt=\"npm downloads\" style=\"max-width:100%;\"\u003e\u003c/a\u003e\n  \u003ca href=\"#\"\u003e\u003cimg src=\"https://img.shields.io/badge/gzip--size-1.57%20kB-blue.svg\" alt=\"gzip-size\" style=\"max-width:100%;\"\u003e\u003c/a\u003e\n  \u003cbr /\u003e\n  \u003ca href=\"https://travis-ci.org/flintinatux/tinyfunk\"\u003e\u003cimg src=\"https://travis-ci.org/flintinatux/tinyfunk.svg?branch=master\" alt=\"Build Status\" style=\"max-width:100%;\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://coveralls.io/github/flintinatux/tinyfunk?branch=master\"\u003e\u003cimg src=\"https://coveralls.io/repos/github/flintinatux/tinyfunk/badge.svg?branch=master\" alt=\"Coverage Status\" style=\"max-width:100%;\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n## Documentation\n\n- [Motivation](#motivation)\n- [Caveat Emptor](#caveat-emptor)\n- [API](#api)\n- [Dependents](#dependents)\n\n## Motivation\n\nMost popular functional libraries, like [Ramda](https://www.npmjs.com/package/ramda), are quite large.  To use them in a frontend project, it's common to import only the bits you need (to keep the bundle size down) like this:\n\n```js\nconst assoc = require('ramda/src/assoc')\nconst map   = require('ramda/src/map')\nconst merge = require('ramda/src/merge')\n// etc.\n```\n\nBut multiple `require` statements take up extra space, since many `js` code compression tools (including [`uglify-js`](https://www.npmjs.com/package/uglify-js)) don't mangle strings.  The AST overhead required to bundle the various modules adds an additional size penalty, not to mention the extra compute time to parse the twisted flow of the AST, which adds to a longer perceived load time.\n\n`tinyfunk` takes a different approach. It exports a single module to minimize AST overhead and obviate the repeated require statements.  You just destructure the functions you need in one go:\n\n```js\nconst { assoc, map, merge } = require('tinyfunk')\n```\n\nWhere possible, it also composes more complex functions by reusing basic ones.  A good example is `compose`, implemented as so:\n\n```js\nconst compose = unapply(flip(reduceRight(thrush)))\n```\n\nWith [`uglify-es`](https://www.npmjs.com/package/uglify-es), this mangles down to the following.  I doubt you'll find a smaller implementation.\n\n```js\nconst I=r(b(B(E)))\n```\n\n## Caveat emptor\n\nIn an effort to keep `tinyfunk` lean and mean - and most of all, tiny - I've taken a few shortcuts.\n\n1.  **None of the exported functions perform type-checking of arguments.**\u003cbr/\u003eIf type-checking is a runtime debug tool you tend to lean on, then you'll need to look elsewhere.\n\n2.  **Many of the function combinators only support unary functions.**\u003cbr/\u003eThis includes `compose`, `converge`, `juxt`, `pipe`, `thrush`, etc.  Unary functions are easily composable, readily portable, and so much simpler (ie: tinier) to support.\n\n3.  **Unlike other popular FP libraries, each exported function only has a single job.**\u003cbr/\u003eFor example, Ramda's `map` supports \"mapping\" over functors, objects, and even functions.  In `tinyfunk`, those various jobs are supported instead by `map`, `mapObj`, and `compose` respectfully.  So be sure to use the right tool for the job at hand.\n\n## API\n\nIf you've lived with FP long enough, you are likely familiar with most of the functions listed below.  So I've opted to leave out the lengthy descriptions and include only the signatures.  I'll be adding more functions as I need them, but if you see any of your favorites missing, just [post an issue](https://github.com/flintinatux/tinyfunk/issues) and I'll be sure to consider it.\n\n| Function | Signature |\n| -------- | --------- |\n| `add` | `Number -\u003e Number -\u003e Number` |\n| `append` | `a -\u003e [a] -\u003e [a]` |\n| `apply` | `(a... -\u003e b) -\u003e [a] -\u003e b` |\n| `assoc` | `k -\u003e v -\u003e { k: v } -\u003e { k: v }` |\n| `assocPath` | `[k] -\u003e v -\u003e { k: v } -\u003e { k: v }` |\n| `call` | `(a... -\u003e b) -\u003e a... -\u003e b` |\n| `compose` | `((y -\u003e z), ..., (a -\u003e b)) -\u003e a -\u003e z` |\n| `composeP` | `((y -\u003e Promise z), ..., (a -\u003e Promise b)) -\u003e a -\u003e Promise z` |\n| `concat` | `Semigroup a =\u003e a -\u003e a -\u003e a` |\n| `cond` | `[[(a -\u003e Boolean), (a -\u003e b)]] -\u003e a -\u003e b` |\n| `constant` | `a -\u003e () -\u003e a` |\n| `converge` | `(b... -\u003e c) -\u003e [(a -\u003e b)] -\u003e a -\u003e c` |\n| `curry` | `((a, b, ...) -\u003e z) -\u003e a -\u003e b -\u003e ... -\u003e z` |\n| `curryN` | `Number -\u003e ((a, b, ...) -\u003e z) -\u003e a -\u003e b -\u003e ... -\u003e z` |\n| `defaultTo` | `a -\u003e a -\u003e a` |\n| `dissoc` | `k -\u003e { k: v } -\u003e { k: v }` |\n| `dissocPath` | `[k] -\u003e { k: v } -\u003e { k: v }` |\n| `either` | `(a -\u003e Boolean) -\u003e (a -\u003e Boolean) -\u003e (a -\u003e Boolean)` |\n| `evolve` | `{ k: (v -\u003e v) } -\u003e { k: v } -\u003e { k: v }` |\n| `filter` | `(a -\u003e Boolean) -\u003e [a] -\u003e [a]` |\n| `find` | `(a -\u003e Boolean) -\u003e [a] -\u003e a` |\n| `flatten` | `[a] -\u003e [b]` |\n| `flip` | `(a -\u003e b -\u003e c) -\u003e (b -\u003e a -\u003e c)` |\n| `head` | `[a] -\u003e a` |\n| `identity` | `a -\u003e a` |\n| `ifElse` | `(a -\u003e Boolean) -\u003e (a -\u003e b) -\u003e (a -\u003e b) -\u003e (a -\u003e b)` |\n| `indexBy` | `(v -\u003e k) -\u003e [v] -\u003e { k: v }` |\n| `init` | `[a] -\u003e [a]` |\n| `is` | `Constructor -\u003e a -\u003e Boolean` |\n| `join` | `String -\u003e [a] -\u003e String` |\n| `juxt` | `[(a -\u003e b)] -\u003e a -\u003e [b]` |\n| `keys` | `{ k: v } -\u003e [k]` |\n| `last` | `[a] -\u003e a` |\n| `length` | `[a] -\u003e Number` |\n| `map` | `Functor f =\u003e (a -\u003e b) -\u003e f a -\u003e f b` |\n| `mapObj` | `(v -\u003e k -\u003e v) -\u003e { k: v } -\u003e { k: v }` |\n| `match` | `RegExp -\u003e String -\u003e [String]` |\n| `merge` | `{ k: v } -\u003e { k: v } -\u003e { k: v }` |\n| `multiply` | `Number -\u003e Number -\u003e Number` |\n| `nAry` | `Number -\u003e (a... -\u003e b) -\u003e (a... -\u003e b)` |\n| `not` | `a -\u003e a` |\n| `objOf` | `k -\u003e v -\u003e { k: v }` |\n| `omit` | `[k] -\u003e { k: v } -\u003e { k: v }` |\n| `partial` | `(a... -\u003e b) -\u003e [a] -\u003e a... -\u003e b` |\n| `partialRight` | `(a... -\u003e b) -\u003e [a] -\u003e a... -\u003e b` |\n| `path` | `[k] -\u003e { k: v } -\u003e v` |\n| `pathEq` | `[k] -\u003e v -\u003e { k: v } -\u003e Boolean` |\n| `pick` | `[k] -\u003e { k: v } -\u003e { k: v }` |\n| `pipe` | `((a -\u003e b), ..., (y -\u003e z)) -\u003e a -\u003e z` |\n| `pipeP` | `((a -\u003e Promise b), ..., (y -\u003e Promise z)) -\u003e a -\u003e Promise z` |\n| `pluck` | `k -\u003e [{ k: v }] -\u003e [v]` |\n| `prepend` | `a -\u003e [a] -\u003e [a]` |\n| `prop` | `k -\u003e { k: v } -\u003e v` |\n| `propEq` | `k -\u003e v -\u003e { k: v } -\u003e Boolean` |\n| `props` | `[k] -\u003e { k: v } -\u003e [v]` |\n| `reduce` | `Foldable f =\u003e (b -\u003e a -\u003e b) -\u003e b -\u003e f a -\u003e b` |\n| `reduceObj` | `(a -\u003e v -\u003e k -\u003e a) -\u003e a -\u003e { k: v } -\u003e a` |\n| `reduceP` | `(b -\u003e a -\u003e Promise b) -\u003e b -\u003e [a] -\u003e Promise b` |\n| `reduceRight` | `Foldable f =\u003e (b -\u003e a -\u003e b) -\u003e b -\u003e f a -\u003e b` |\n| `reduceRightP` | `(b -\u003e a -\u003e Promise b) -\u003e b -\u003e [a] -\u003e Promise b` |\n| `replace` | `RegExp -\u003e String -\u003e String -\u003e String` |\n| `slice` | `Number -\u003e Number -\u003e [a] -\u003e [a]` |\n| `sort` | `((a, a) -\u003e Number) -\u003e [a] -\u003e [a]` |\n| `sortBy` | `Ord b =\u003e (a -\u003e b) -\u003e [a] -\u003e [a]` |\n| `split` | `RegExp -\u003e String -\u003e [String]` |\n| `tail` | `[a] -\u003e [a]` |\n| `take` | `Number -\u003e [a] -\u003e [a]` |\n| `tap` | `(a -\u003e b) -\u003e a -\u003e a` |\n| `test` | `RegExp -\u003e String -\u003e Boolean` |\n| `then` | `(a -\u003e Promise b) -\u003e a -\u003e Promise b` |\n| `thrush` | `a -\u003e (a -\u003e b) -\u003e b` |\n| `unapply` | `([a] -\u003e b) -\u003e a... -\u003e b` |\n| `unary` | `(a... -\u003e b) -\u003e (a -\u003e b)` |\n| `uniqBy` | `(a -\u003e String) -\u003e [a] -\u003e [a]` |\n| `unit` | `a -\u003e ()` |\n| `unless` | `(a -\u003e Boolean) -\u003e (a -\u003e a) -\u003e a -\u003e a` |\n| `useWith` | `(b... -\u003e c) -\u003e [(a -\u003e b)] -\u003e a... -\u003e c` |\n| `values` | `{ k: v } -\u003e [v]` |\n| `when` | `(a -\u003e Boolean) -\u003e (a -\u003e a) -\u003e a -\u003e a` |\n| `zipObj` | `[k] -\u003e [v] -\u003e { k: v }` |\n\n## Dependents\n\nI use `tinyfunk` everyday to make cool things.  Maybe you do, too.  If so, let me know with a PR, and we can add your cool things to this list.\n\n- [`puddles`](https://github.com/flintinatux/puddles) - _Tiny vdom app framework. Pure Redux. No boilerplate._ - Built with ❤️ on `tinyfunk`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflintinatux%2Ftinyfunk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflintinatux%2Ftinyfunk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflintinatux%2Ftinyfunk/lists"}