{"id":19420558,"url":"https://github.com/karimaziev/fp","last_synced_at":"2025-07-11T07:05:31.363Z","repository":{"id":49775982,"uuid":"485784086","full_name":"KarimAziev/fp","owner":"KarimAziev","description":"A collection of combinators for Elisp","archived":false,"fork":false,"pushed_at":"2024-11-09T13:02:27.000Z","size":74,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-15T04:04:54.459Z","etag":null,"topics":["combinatorics","emacs","emacs-lisp","functional-programming"],"latest_commit_sha":null,"homepage":"","language":"Emacs Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/KarimAziev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null}},"created_at":"2022-04-26T12:50:36.000Z","updated_at":"2024-11-09T13:02:30.000Z","dependencies_parsed_at":"2024-11-09T13:35:48.135Z","dependency_job_id":null,"html_url":"https://github.com/KarimAziev/fp","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/KarimAziev/fp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KarimAziev%2Ffp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KarimAziev%2Ffp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KarimAziev%2Ffp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KarimAziev%2Ffp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/KarimAziev","download_url":"https://codeload.github.com/KarimAziev/fp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KarimAziev%2Ffp/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264752879,"owners_count":23658737,"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":["combinatorics","emacs","emacs-lisp","functional-programming"],"created_at":"2024-11-10T13:23:52.394Z","updated_at":"2025-07-11T07:05:31.341Z","avatar_url":"https://github.com/KarimAziev.png","language":"Emacs Lisp","readme":"# fp\n\nA library of point-free style combinators for Emacs Lisp.\n\n# Table of Contents\n\n\u003e   - [fp](#fp)\n\u003e       - [Requirements](#requirements)\n\u003e       - [Installation](#installation)\n\u003e           - [Manually](#manually)\n\u003e           - [With use-package and\n\u003e             straight](#with-use-package-and-straight)\n\u003e       - [Usage](#usage)\n\u003e           - [Macros](#macros)\n\u003e               - [`fp-pipe` (\\\u0026rest\n\u003e                 functions)](#fp-pipe-rest-functions)\n\u003e               - [`fp-compose` (\\\u0026rest\n\u003e                 functions)](#fp-compose-rest-functions)\n\u003e               - [`fp-partial` (fn \\\u0026rest\n\u003e                 args)](#fp-partial-fn-rest-args)\n\u003e               - [`fp-rpartial` (fn \\\u0026rest\n\u003e                 args)](#fp-rpartial-fn-rest-args)\n\u003e               - [`fp-and` (\\\u0026rest functions)](#fp-and-rest-functions)\n\u003e               - [`fp-or` (\\\u0026rest functions)](#fp-or-rest-functions)\n\u003e               - [`fp-converge` (combine-fn \\\u0026rest\n\u003e                 functions)](#fp-converge-combine-fn-rest-functions)\n\u003e               - [`fp-use-with` (combine-fn \\\u0026rest\n\u003e                 functions)](#fp-use-with-combine-fn-rest-functions)\n\u003e               - [`fp-when` (pred fn)](#fp-when-pred-fn)\n\u003e               - [`fp-unless` (pred fn)](#fp-unless-pred-fn)\n\u003e               - [`fp-const` (value)](#fp-const-value)\n\u003e               - [`fp-ignore-args` (fn)](#fp-ignore-args-fn)\n\u003e               - [`fp-not` (fn)](#fp-not-fn)\n\u003e               - [`fp-cond` (\\\u0026rest pairs)](#fp-cond--rest-pairs)\n\u003e           - [Functions](#functions)\n\u003e               - [`fp-nil` (\\\u0026rest ignored)](#fp-nil--rest-ignored)\n\u003e               - [`fp-t` (\\\u0026rest ignored)](#fp-t--rest-ignored)\n\n## Requirements\n\n  - Emacs \\\u003e= 26.1\n\n## Installation\n\n### Manually\n\nDownload repository and it to your load path in your init file:\n\n``` elisp\n(add-to-list 'load-path \"/path/to/fp\")\n(require 'fp)\n```\n\n### With use-package and straight\n\n``` elisp\n(use-package fp :straight (:repo \"KarimAziev/fp\" :type git :host github))\n```\n\n## Usage\n\n### Macros\n\n#### `fp-pipe` (\\\u0026rest functions)\n\nReturn a left-to-right composition from `functions`. The first argument\nmay have any arity; the remaining arguments must be unary.\n\n``` elisp\n(funcall (fp-pipe upcase split-string) \"some string\")\n;; ⇒ (\"SOME\" \"STRING\")\n```\n\n#### `fp-compose` (\\\u0026rest functions)\n\nReturn a right-to-left composition from `functions`. The last function\nmay have any arity; the remaining arguments must be unary.\n\n``` elisp\n(funcall (fp-compose split-string upcase) \"some string\")\n;; ⇒ (\"SOME\" \"STRING\")\n```\n\n#### `fp-partial` (fn \\\u0026rest args)\n\nReturn a partial application of a function `fn` to left-hand `args`.\n\nArguments `args` is a list of the last `n` arguments to pass to `fn`.\nThe result is a new function that does the same as `fn`, except that the\nlast `n` arguments are fixed at the values with which this function was\ncalled.\n\n``` elisp\n(funcall (fp-partial \u003e 3) 2) ;; ⇒ t\n```\n\n#### `fp-rpartial` (fn \\\u0026rest args)\n\nReturn a partial application of a function `fn` to right-hand arguments\n`args`.\n\nArguments `args` is a list of the last `n` arguments to pass to `fn`.\n\nThe result is a new function which does the same as `fn`, except that\nthe last `n` arguments are fixed at the values with which this function\nwas called.\n\n``` elisp\n(funcall (fp-rpartial plist-get :name) '(:name \"John\" :age 30))\n;; ⇒ \"John\"\n```\n\n#### `fp-and` (\\\u0026rest functions)\n\nReturn a unary function that calls `functions` until one of them yields\nnil. If all functions return non-nil, return the last such value.\n\n``` elisp\n(let ((x 30))\n  (funcall (fp-and numberp 1+) x))\n;; ⇒ 31\n```\n\n#### `fp-or` (\\\u0026rest functions)\n\nExpand to a unary function that calls `functions` until first non-nil\nresult. Return that first non-nil result without calling the remaining\nfunctions. If all functions returned nil, the result will be also nil.\n\n``` elisp\n(seq-filter\n (fp-or numberp stringp)\n '(\"a\" \"b\" (0 1 2 3 4) \"c\" 34 (:name \"John\" :age 30)))\n\n;; ⇒ (\"a\" \"b\" \"c\" 34)\n```\n\n#### `fp-converge` (combine-fn \\\u0026rest functions)\n\nReturn a function to apply `combine-fn` with the results of branching\n`functions`. If the first element of `functions` is a vector, it will be\nused instead.\n\n``` elisp\n(funcall (fp-converge concat [upcase downcase]) \"John\")\n;; ⇒ \"JOHNjohn\"\n```\n\nIf first element of `functions` is a vector, it will be used instead.\n\n``` elisp\n(funcall (fp-converge concat upcase downcase) \"John\")\n;; ⇒ \"JOHNjohn\"\n```\n\n#### `fp-use-with` (combine-fn \\\u0026rest functions)\n\nReturn a function with the arity of length `functions`. Call every\nbranching function with an argument at the same index, and finally,\n`combine-fn` will be applied to the supplied values.\n\n``` elisp\n(funcall (fp-use-with concat [upcase downcase]) \"hello \" \"world\")\n  ;;  ⇒ \"HELLO world\"\n```\n\nIf first element of `functions` is a vector, it will be used instead.\n\n``` elisp\n(funcall (fp-use-with concat upcase downcase) \"hello \" \"world\")\n;;   ⇒ \"HELLO world\"\n```\n\n#### `fp-when` (pred fn)\n\nReturn a function that calls `fn` if the result of calling `pred` is\nnon-nil. Both `pred` and `fn` are called with one argument. If the\nresult of `pred` is nil, return the argument as is.\n\n``` elisp\n(defun truncate-maybe (str len)\n  \"Truncate STR if longer LEN, otherwise return STR.\"\n  (funcall (fp-when\n            (fp-compose (fp-partial \u003c len) length)\n            (fp-rpartial substring 0 len))\n           str))\n\n(list (truncate-maybe \"long string\" 4)\n      (truncate-maybe \"lo\" 4))\n\n;; ⇒ (\"long\" \"lo\")\n```\n\n#### `fp-unless` (pred fn)\n\nReturn a function that calls `fn` if the result of calling `pred` is\nnon-nil.\n\nBoth `pred` and `fn` are called with one argument.\n\nIf the result of `pred` is nil, return the argument as is.Return a unary\nfunction that invokes `fn` if the result of calling `pred` is nil.\nAccept one argument and pass it both to `pred` and `fn`. If the result\nof `pred` is non-nil, return the argument as is.\n\n``` elisp\n(defun divide-maybe (a b)\n  \"Divide A and B unless B is 0.\"\n  (funcall (fp-unless zerop\n                       (fp-partial / a))\n           b))\n\n(list (divide-maybe 10 0)\n      (divide-maybe 10 2))\n\n;; ⇒ '(0 5)\n```\n\n#### `fp-const` (value)\n\nReturn a function that always returns `value`. This function accepts any\nnumber of arguments but ignores them.\n\n``` elisp\n(funcall (fp-const 2) 4) ;; ⇒ 2\n```\n\n#### `fp-ignore-args` (fn)\n\nReturn a function that invokes `fn` without args. This function accepts\nany number of arguments but ignores them.\n\n``` elisp\n(defun my-fn ()\n  \"Show message hello world.\"\n  (message \"Hello world\"))\n\n(funcall (fp-ignore-args my-fn) 4) ;;   ⇒ \"Hello world\"\n```\n\n#### `fp-not` (fn)\n\nReturn a function that negates the result of function `fn`.\n\n``` elisp\n(funcall (fp-not stringp) 4) ;;   ⇒ t\n```\n\n#### `fp-cond` (\\\u0026rest pairs)\n\nReturn a function that expands a list of `pairs` to cond clauses. Every\npair should be either:\n\n  - a vector of \\[predicate transformer\\]\n\n\u003c!-- end list --\u003e\n\n``` elisp\n(funcall (fp-cond\n           [stringp identity]\n           [symbolp symbol-name]\n           [integerp number-to-string]\n           [floatp number-to-string]\n           [t (fp-partial format \"%s\")])\n         2)\n\n;;   ⇒ 4\n```\n\n  - a list of (predicate transformer).\n\n\u003c!-- end list --\u003e\n\n``` elisp\n(funcall (fp-cond\n           (stringp identity)\n           (symbolp symbol-name)\n           (integerp number-to-string)\n           (floatp number-to-string)\n           (t (fp-partial format \"%s\")))\n         2)\n;;   ⇒ 4\n```\n\nThe predicate can also be `t`.\n\nAll of the arguments to function are applied to each of the predicates\nin turn until one returns a \"truthy\" value, at which point fn returns\nthe result of applying its arguments to the corresponding transformer.\n\n### Functions\n\n#### `fp-nil` (\\\u0026rest ignored)\n\nDo nothing and return `t`. This function accepts any number of arguments\nbut ignores them.\n\n``` example\n(fp-nil t)\n    ⇒ nil\n(fp-nil 23)\n    ⇒ nil\n(fp-nil)\n   ⇒ nil\n```\n\n#### `fp-t` (\\\u0026rest ignored)\n\nDo nothing and return `t`. This function accepts any number of\narguments, but ignores them.\n\n``` example\n(fp-t nil)\n   ⇒ t\n (fp-t)\n   ⇒ t\n (fp-t 23)\n   ⇒ t\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkarimaziev%2Ffp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkarimaziev%2Ffp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkarimaziev%2Ffp/lists"}