{"id":24433883,"url":"https://github.com/windler/funky","last_synced_at":"2025-04-12T15:09:00.803Z","repository":{"id":6157624,"uuid":"7387131","full_name":"windler/Funky","owner":"windler","description":"A bridge between java and a functional programming language","archived":false,"fork":false,"pushed_at":"2018-01-04T21:41:02.000Z","size":52,"stargazers_count":8,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-04-12T15:08:54.993Z","etag":null,"topics":["bridge","clojure","concurrent","cross-language","functional-languages","java"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"CppCon/CppCon2014","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/windler.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}},"created_at":"2012-12-31T13:09:41.000Z","updated_at":"2024-03-20T18:21:37.000Z","dependencies_parsed_at":"2022-08-31T21:03:22.218Z","dependency_job_id":null,"html_url":"https://github.com/windler/Funky","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/windler%2FFunky","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/windler%2FFunky/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/windler%2FFunky/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/windler%2FFunky/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/windler","download_url":"https://codeload.github.com/windler/Funky/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248586235,"owners_count":21128997,"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":["bridge","clojure","concurrent","cross-language","functional-languages","java"],"created_at":"2025-01-20T16:51:06.396Z","updated_at":"2025-04-12T15:09:00.784Z","avatar_url":"https://github.com/windler.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Funky\n\n`Funky` is a `java`library that lets you run `clojure` code within your `java` app.\n\n## Idea\nObject orientated and functional languages have there benefits. One of the big advantage of functional languages is the immutability. This gets handy e.g. when you have to deal with money values. No ones likes unnoticed side effets when calculating with money.\n\nAt this point `Funky` comes into play. Use the advantages of `Java` and `Clojure` and keep the languages completely seperated. \n\n## Main concept\nCreate some clojure source you like, e.g.\n```clojure\n(ns de.windler.example)\n\n(def multi (fn [x y] (* x y)))\n```\n\nTo make this accessable from Java you have to create a enum extending `FunkyFunction`\n```java\npublic enum ClojureFunctions implements FunkyFunction {\n\tCLOJ_MULTI(\"multi\", \"de.windler.example\");\n\n\tprivate final String name;\n\tprivate final String namespace;\n\n\tprivate ClojureFunctions(final String name, final String namespace) {\n\t\tthis.name = name;\n\t\tthis.namespace = namespace;\n\t}\n\n\t@Override\n\tpublic final String getName() {\n\t\treturn name;\n\t}\n\n\t@Override\n\tpublic String getNamespace() {\n\t\treturn namespace;\n\t}\n}\n```\n\nNext, you a need a java class that extending the `FunkyBridge` which will be annotated to use our created clojure functin\n```java\n@Funky(driver = FunkyDriver.CLOJURE, target = \"de/windler/example/calculations.clj\")\npublic class SimpleEngine extends FunkyBridge {\n\n\tpublic SimpleEngine() throws FunkyException {\n\t\tsuper();\n\t}\n\n\tpublic long multiply(int x, in y) throws FunkyException {\n\t\treturn invoke(ClojureFunctions.CLOJ_MULTI, Long.class, x, y).getValue();\n\t}\n}\n```\n\nThats it. You can now run your clojure functions by calling your java method\n```java\n(new SimpleEngine()).multiply(10, 5);\n```\n\n### Async execution\nYou can also run `async` function like the following\n```clojure\n(defn async [i] \n  (if (= i 0) 1\n    (+ 1 (async (- i 1)))))\n```\n\nInstead of waiting for the result you can now use the `invokeAndNotify` instead of the `invoke` method within your java service\n```java\npublic void calcAsync(FunkyInvocationFinishedListener\u003c?\u003e listener) throws FunkyException {\n\tinvokeAndNotify(listener, ClojureFunctions.CLOJ_ADD_ASYNC, 1000);\n}\n```\n\nWhen the executions finishes the `FunkyInvocationFinishedListener` will be called.\n\n### Load clojure source on demand\nWhen the `FunkyBridge` is created the source file will be parsed. If you want to parse it when `invoke` is called then just annotate `@FunkyLoadOnDemand`.\n\n## Initialize bridge in thread\nIf you want to init the `FunkyBridge` immidiatly but in background you can annotate `@FunkyInitializeInThread`. By calling `FunkyBridge#addInitializedListener` you can register a callback that is called when the thread finished.\n\n### Constants from clojure\nIf you want a field in your `FunkyBridge` to be a constant from the clojure source then just create a field with the name of the `def` to call and annotate it with `@FunkyConstant`. Remmeber that this `def` must not need any arguments. Alternatively, you can annotate `@FunkyImmutableConstant` and make the field of type `FunkyImmutableValue`.\n\n```clojure\n(defn pi [] (/ 3.14 1))\n```\n\n```java \n//...extends FunkyBridge\n//(...)\n\n@FunkyConstant\nprivate Double pi;\n\n@FunkyImmutableConstant\nprivate FunkyImmutableValue\u003cDouble\u003e pi;\n```\n\n## Future work\nThis projects was a proof of concept and is no longer under active development. If you like the project feel free to contact me, create issues or fork the project. There are also some trivial examples located within the sources.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwindler%2Ffunky","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwindler%2Ffunky","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwindler%2Ffunky/lists"}