{"id":16800260,"url":"https://github.com/camsaul/external-fn","last_synced_at":"2025-06-10T12:35:14.794Z","repository":{"id":62431371,"uuid":"192035178","full_name":"camsaul/external-fn","owner":"camsaul","description":"Small Clojure lib to define functions whose implementations will be provided elsewhere","archived":false,"fork":false,"pushed_at":"2019-06-15T05:37:44.000Z","size":16,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-11T00:34:25.585Z","etag":null,"topics":["clojure","dependency-injection","external","external-fn"],"latest_commit_sha":null,"homepage":null,"language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/camsaul.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":".github/CODEOWNERS","security":null,"support":null}},"created_at":"2019-06-15T04:09:25.000Z","updated_at":"2023-04-13T20:50:35.000Z","dependencies_parsed_at":"2022-11-01T21:00:55.430Z","dependency_job_id":null,"html_url":"https://github.com/camsaul/external-fn","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/camsaul%2Fexternal-fn","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/camsaul%2Fexternal-fn/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/camsaul%2Fexternal-fn/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/camsaul%2Fexternal-fn/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/camsaul","download_url":"https://codeload.github.com/camsaul/external-fn/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/camsaul%2Fexternal-fn/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259076457,"owners_count":22801752,"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":["clojure","dependency-injection","external","external-fn"],"created_at":"2024-10-13T09:32:02.125Z","updated_at":"2025-06-10T12:35:14.732Z","avatar_url":"https://github.com/camsaul.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Downloads](https://versions.deps.co/camsaul/external-fn/downloads.svg)](https://versions.deps.co/camsaul/external-fn)\n[![Dependencies Status](https://versions.deps.co/camsaul/external-fn/status.svg)](https://versions.deps.co/camsaul/external-fn)\n[![Circle CI](https://circleci.com/gh/camsaul/external-fn.svg?style=svg)](https://circleci.com/gh/camsaul/external-fn)\n[![License](https://img.shields.io/badge/license-Eclipse%20Public%20License-blue.svg)](https://raw.githubusercontent.com/camsaul/external-fn/master/LICENSE)\n[![cljdoc badge](https://cljdoc.org/badge/camsaul/external-fn)](https://cljdoc.org/d/camsaul/external-fn/CURRENT)\n\n[![Clojars Project](https://clojars.org/camsaul/external-fn/latest-version.svg)](http://clojars.org/camsaul/external-fn)\n\nA small Clojure utility library for defining abstract functions whose implementation will be provided elsewhere\n(perhaps externally). Useful for dependency injection and otherwise nicely\ndecoupling different modules of your project from one another.\n\nThis library provides a function, `external-fn`, that you can use to create an externally-defined function.\nThis resulting object works exactly like a normal Clojure function, but will throw an Exception if invoked before\nan instance has been provided:\n\n```clj\n(require '[external-function.core :as external-fn])\n\n(def f (external-fn/external-fn))\n\n(f) ;-\u003e AbstractMethodError\n```\n\nYou can provide an implementation with `provide-impl!`:\n\n```clj\n;; provide an implementation\n(external-fn/provide-impl! f (constantly :ok))\n\n;; now function will work as expected\n(f) ;-\u003e :ok\n```\n\nThis library also provides a `defexternal` macro to define an external function with almost the exact same syntax as `defn`; the usual\nnice-to-have metadata like `:arglists` is provided as well.\n\n\n```clj\n(external-fn/defexternal my-fn\n  \"You can add docstrings\"\n  {:can-add-attribute-maps? true}\n  [x])\n\n(external-fn/provide-impl! my-fn (fn [x] (+ x x)))\n\n(my-fn 2) ;-\u003e 4\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcamsaul%2Fexternal-fn","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcamsaul%2Fexternal-fn","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcamsaul%2Fexternal-fn/lists"}