{"id":19813810,"url":"https://github.com/azer0s/hummus","last_synced_at":"2025-05-01T10:31:01.419Z","repository":{"id":57520116,"uuid":"100487168","full_name":"Azer0s/Hummus","owner":"Azer0s","description":"A gluten free LISP (ish) interpreter powered by black magic","archived":false,"fork":false,"pushed_at":"2025-02-23T20:53:58.000Z","size":496,"stargazers_count":14,"open_issues_count":3,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-06T12:06:20.491Z","etag":null,"topics":["actor-model","black-magic","concurrent-programming","gluten-free","hacktoberfest","interpreter","lisp","scripting-language"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Azer0s.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":"2017-08-16T12:32:00.000Z","updated_at":"2025-02-23T20:54:02.000Z","dependencies_parsed_at":"2022-09-05T09:41:37.453Z","dependency_job_id":null,"html_url":"https://github.com/Azer0s/Hummus","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/Azer0s%2FHummus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Azer0s%2FHummus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Azer0s%2FHummus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Azer0s%2FHummus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Azer0s","download_url":"https://codeload.github.com/Azer0s/Hummus/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251859772,"owners_count":21655617,"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":["actor-model","black-magic","concurrent-programming","gluten-free","hacktoberfest","interpreter","lisp","scripting-language"],"created_at":"2024-11-12T09:37:23.325Z","updated_at":"2025-05-01T10:31:01.103Z","avatar_url":"https://github.com/Azer0s.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Powered by](https://img.shields.io/badge/Powered%20By-Black%20Magic-orange.svg?longCache=true\u0026style=flat-square) \n![Open Source Love](https://img.shields.io/badge/Open%20source-%E2%9D%A4%EF%B8%8F-brightgreen.svg?style=flat-square) \n![Gluten free](https://img.shields.io/badge/Gluten-Free-blue.svg?longCache=true\u0026style=flat-square)\n\n## Getting started\n\n```bash\ngit clone https://github.com/Azer0s/Hummus.git\ncd Hummus\n```\n\n### Running locally\n\n```bash\nmake all\necho \"export PATH=\\\"$(pwd)/bin:\\$PATH\"\\\" \u003e\u003e ~/.bashrc \n```\n\n### Creating a Hummus project\n\n```bash\nhummus init helloworld\ncd helloworld\nhummus run\n```\n\n### Running on docker\n\n```bash\ndocker build -t azer0s/hummus:latest .\ndocker run --rm -it azer0s/hummus:latest\n```\n\nOr get the edge image:\n\n```bash\ndocker run --rm -it azer0s/hummus:edge\n```\n\n## Examples\n\n### Variable assignment\n```clojure\n(def a \"Hello world\")\n```\n### Function assignment\n```clojure\n(def square (fn x \n  (* x x)))\n```\n### Anonymous function\n```clojure\n((fn x (* x x)) 4)\n```\n### Use function\n```clojure\n(out (square 4))\n```\n### Structs\n\n```clojure\n(use :\u003cbase\u003e)\n\n(def Animal (struct\n  :name\n  :age\n  :race\n))\n\n(def tom (Animal\n  \"Tom\"\n  1\n  :cat\n))\n\n(out (:name tom) \" is a \" (` (:race tom))) ; prints Tom is a cat\n```\n\n### Parallel processing\n\n````clojure\n(use :\u003cbase\u003e)\n(use :\u003cpipe/parallel\u003e)\n\n(def square (fn x \n  (* x x)))\n\n(pipe/parallel-do 4 out square)\n````\n\n### Maps\n\n```clojure\n(use :\u003cbase\u003e)\n\n(def prices ({}\n  (:tea :1.5$)\n  (:coffee :2$)\n  (:cake :3$)\n))\n\n(out \"Cake costs \" (` (:cake prices)))\n(out \"Tea costs \" (` ([] :tea prices)))\n```\n\n### Macros\n\n```clojure\n(def dotimes (macro times |action|\n; || tells Hummus to not evaluate this argument but to\n; literally take the AstNode as it's input parameter\n  (map (.. 1 times) (fn _ (identity action)))\n))\n\n(dotimes 3 (out \"Hello world\"))\n; Same as writing\n; (out \"Hello world\")\n; (out \"Hello world\")\n; (out \"Hello world\")\n\n(def when (macro |cond| |action|\n  (' :if cond action)\n))\n\n(when (\u003e 4 3) (out \"A\"))\n; same as writing\n; (if (\u003e 4 3)\n;   (out \"A\"))\n```\n\n### Actor model\n\n```clojure\n(use :\u003cbase\u003e)\n(use :\u003csync\u003e)\n\n(def ping (fn\n  (for true\n    (def msg (receive))\n    (def type (nth 0 msg))\n    (def sender (nth 1 msg))\n\n    (if (= type :pong)\n      ((fn\n        (out \"PONG\")\n        (sync/sleep 1 :s)\n        (send sender (list :ping self))\n      ))\n      (out \"Invalid message!\")\n    )\n  )\n))\n\n(def pong (fn\n  (for true\n    (def msg (receive))\n    (def type (nth 0 msg))\n    (def sender (nth 1 msg))\n\n    (if (= type :ping)\n      ((fn\n        (out \"PING\")\n        (sync/sleep 1 :s)\n        (send sender (list :pong self))\n      ))\n      (out \"Invalid message!\")\n    )\n  )\n))\n\n(def pingPid (spawn ping))\n(def pongPid (spawn pong))\n\n(send pongPid (list :ping pingPid))\n(in)\n```\n\n### Map ⇄ Filter ⇄ Reduce\n\n```clojure\n(use :\u003cbase\u003e)\n(use :\u003cstr\u003e)\n\n(def pilots (list\n  ({}\n    (:id 2)\n    (:name \"Wedge Antilles\")\n    (:faction \"Rebels\")\n  )\n  ({}\n    (:id 8)\n    (:name \"Ciena Ree\")\n    (:faction \"Empire\")\n  )\n  ({}\n    (:id 40)\n    (:name \"Iden Versio\")\n    (:faction \"Empire\")\n  )\n  ({}\n    (:id 66)\n    (:name \"Thane Kyrell\")\n    (:faction \"Rebels\")\n  )\n))\n\n(each\n  (map pilots (fn x\n    (str/concat (` (:name x)) \" =\u003e \" (` (:faction x)))\n  ))\n(fn x\n  (out x)\n))\n\n(each\n  (filter pilots (fn x\n    (= (:faction x) \"Empire\")\n  ))\n(fn x\n  (out (:name x))\n))\n\n(out (reduce pilots (fn x acc\n  (if (= (:faction x) \"Empire\")\n    (+ acc 1)\n    acc\n  )\n) 0))\n```\n\n### Function composition\n\n```clojure\n(use :\u003cbase\u003e)\n(use :\u003cpipe\u003e)\n(use :\u003cstr\u003e)\n\n(def add (fn a b\n  (+ a b)\n))\n\n(def square(fn x\n  (* x x)\n))\n\n(def add-square-out (|\u003e add square out))\n\n(add-square-out 3 1) ; prints 16\n\n(pipe/do pilots\n  (map.. (fn x\n    (str/concat (` (:name x)) \" =\u003e \" (` (:faction x)))\n  ))\n  (each.. (fn x\n    (out x)\n  ))\n)\n\n(pipe/do pilots\n  (filter.. (fn x\n    (= (:faction x) \"Empire\")\n  ))\n  (map.. (fn x\n    (:name x)\n  ))\n  (each.. (fn x\n    (out x)\n  ))\n)\n\n(pipe/do pilots\n  (reduce.. (fn x acc\n    (if (= (:faction x) \"Empire\")\n      (+ acc 1)\n      acc\n    )\n  ) 0)\n  out\n)\n```\n\n### HTTP Server\n\n```clojure\n(use :\u003cbase\u003e)\n(use :\u003cnet/http\u003e)\n\n(http/handle \"/\" (fn req\n  (str/concat \"\u003ch1\u003e Hello \" (:method req) \"\u003c/h1\u003e\")\n))\n\n(http/handle \"/test\" (fn req\n  \"\u003ch1\u003e Test \u003c/h1\u003e\"\n))\n\n(http/serve \":8080\")\n```\n\n### Examples\n\n```clojure\n(use :\u003cbase\u003e)\n(use :\u003cstr\u003e)\n\n(def fib (fn n\n  (if (\u003c n 2)\n    1 \n    (+ (fib (- n 2)) (fib (- n 1)))\n  )\n))\n\n(for (range x (list \"Hello\" \"World\"))\n  (out x)\n)\n\n(for (range x (to 10))\n  (out x)\n)\n\n(for true\n  (out \"Hello world\")\n)\n\n(str/concat \"String functions go b\" (str/repeat \"r\" 10))\n```\n\n## Get help\n```clojure\n(use :\u003cinternals\u003e)\n\n(hummus/info-group log)\n```\n\n## Exit the application\n```clojure\n(exit)\n```\n\n## License\n[MIT](https://choosealicense.com/licenses/mit/)\n\n## Credits\n\n* \u003ca href=\"https://github.com/peterh/liner\"\u003epeterh/liner\u003c/a\u003e - used for REPL\n* \u003ca href=\"https://github.com/sirupsen/logrus\"\u003esirupsen/logrus\u003c/a\u003e - used in the log stdlib\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fazer0s%2Fhummus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fazer0s%2Fhummus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fazer0s%2Fhummus/lists"}