{"id":13760327,"url":"https://github.com/metosin/tilakone","last_synced_at":"2025-06-23T02:10:46.345Z","repository":{"id":50945452,"uuid":"144505432","full_name":"metosin/tilakone","owner":"metosin","description":"Minimalistic finite state machine (FSM) in Clojure","archived":false,"fork":false,"pushed_at":"2024-02-15T09:44:02.000Z","size":102,"stargazers_count":198,"open_issues_count":5,"forks_count":20,"subscribers_count":17,"default_branch":"develop","last_synced_at":"2025-06-21T05:40:34.311Z","etag":null,"topics":["clojure","clojure-library","finite-state-machine","fsm-library","metosin-deprecated"],"latest_commit_sha":null,"homepage":"","language":"Clojure","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/metosin.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2018-08-12T22:33:29.000Z","updated_at":"2025-06-10T18:22:55.000Z","dependencies_parsed_at":"2024-01-15T03:42:35.357Z","dependency_job_id":"2efd4e10-13a1-4e8b-8b41-5b933116176a","html_url":"https://github.com/metosin/tilakone","commit_stats":{"total_commits":56,"total_committers":3,"mean_commits":"18.666666666666668","dds":0.0357142857142857,"last_synced_commit":"616410a17f26ebd83a7ee20d6b0cd49bc5b89c64"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/metosin/tilakone","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metosin%2Ftilakone","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metosin%2Ftilakone/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metosin%2Ftilakone/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metosin%2Ftilakone/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/metosin","download_url":"https://codeload.github.com/metosin/tilakone/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metosin%2Ftilakone/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261397490,"owners_count":23152492,"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","clojure-library","finite-state-machine","fsm-library","metosin-deprecated"],"created_at":"2024-08-03T13:01:07.932Z","updated_at":"2025-06-23T02:10:41.330Z","avatar_url":"https://github.com/metosin.png","language":"Clojure","funding_links":[],"categories":["Clojure"],"sub_categories":[],"readme":"# tilakone\n\nMinimalistic finite state machine (FSM) in Clojure.\n\nStatus: [Deprecated](https://github.com/topics/metosin-deprecated).\n\n\u003e **Tilakone (_eng._ State machine)**\n\u003e \n\u003e Noun\n\u003e  \n\u003e   state machine (plural state machines)\n\u003e  \n\u003e      (computing theory) A formalism for describing computation, consisting of a set of \n\u003e      states and a transition function describing when to move from one state to another.\n\u003e\n\u003e    _source: [wiktionary.org](https://en.wiktionary.org/wiki/state_machine)_\n\n[![Clojars Project](https://img.shields.io/clojars/v/metosin/tilakone.svg)](https://clojars.org/metosin/tilakone)\n\n## Usage\n\nTested with Clojure `1.10.0`\n\nAll bundled:\n\n```clj\n[metosin/tilakone \"0.0.4\"]\n```\n\nOptionally, the modules can be required separately:\n\n```clj\n[metosin/tilakone.core \"0.0.4\"]\n[metosin/tilakone.schema \"0.0.4\"]\n```\n\n## Intro\n\nThe excellent [cdorrat/reduce-fsm](https://github.com/cdorrat/reduce-fsm) library\nhas a nice FSM [example](/cdorrat/reduce-fsm#basic-fsm):\n\n```clj\n; from https://github.com/cdorrat/reduce-fsm#basic-fsm\n\n(defn inc-val [val \u0026 _] (inc val))\n\n(fsm/defsm count-ab\n  [[:start\n    \\a -\u003e :found-a]\n   [:found-a\n    \\a -\u003e  :found-a\n    \\b -\u003e {:action inc-val} :start\n    _ -\u003e :start]])\n\n;; We can use the generated fsm like any function\n(map (partial count-ab 0) [\"abaaabc\" \"aaacb\" \"bbbcab\"])\n;; returns =\u003e (2 0 1)\n``` \n\nThis is very nice and works for many cases. The _reduce-fsm_ library uses \nmacros to define the FSM and actions are functions. This makes the _reduce-fsm_ less\nsuitable if you need to serialize your FSMs.\n\n_Tilakone_ is a similar FSM library, but it uses pure data to define the FSM states\n(no macros needed) and the action functions can be defined separately.\n\nHere's the same example with _tilakone_:\n\n```clj\n(ns example.count-ab-example\n  (:require [tilakone.core :as tk :refer [_]]))\n\n; State definitions, pure data here:\n\n(def count-ab-states\n  [{::tk/name        :start\n    ::tk/transitions [{::tk/on \\a, ::tk/to :found-a}\n                      {::tk/on _}]}\n   {::tk/name        :found-a\n    ::tk/transitions [{::tk/on \\a}\n                      {::tk/on \\b, ::tk/to :start, ::tk/actions [:inc-val]}\n                      {::tk/on _, ::tk/to :start}]}])\n\n; FSM has states, a function to execute actions, and current state and value:\n\n(def count-ab\n  {::tk/states  count-ab-states\n   ::tk/action! (fn [{::tk/keys [action] :as fsm}]\n                  (case action\n                    :inc-val (update fsm :count inc)))\n   ::tk/state   :start\n   :count       0})\n\n; Lets apply same inputs to our FSM:\n\n(-\u003e\u003e [\"abaaabc\" \"aaacb\" \"bbbcab\"]\n     (map (partial reduce tk/apply-signal count-ab))\n     (map :count))\n;=\u003e (2 0 1)\n```\n\nNote that the state definitions in `count-ab-states` are pure data.\n\nAlso, there is one extra state transfer defined in _tilakone_ example from\nstate `:start`. In _reduce_fsm_ the default behaviour for signal (that is, if no \ntransition is found for signal) is to stay at the current state, but _tilakone_ \ntreats all undeclared state transfers as errors. For this purpose the above example \ndeclares an explicit rule to allow any unmatched signal (`_`) in state `:start` to be \nhandled as transition to state `:start`.\n\nThe `count-ab` is the actual FSM. It contains the state declarations,\noptional actions function (more of actions later), current state and current\nvalue. Note that the state and value can be any clojure value.\n\nThe `tilakone.core/apply-signal` function accepts an FSM and a signal. It\nreturns the FSM with possibly updated state and value. \n\n## Documentation\n\n* TODO\n\n## Comparing reduce-fsm and Tilakone\n\n* reduce-fsm is older project with far more users\n* reduce-fsm is faster (at least at the moment)\n* reduce-fsm is more feature complete\n* tilakone FSMs are pure data™\n* tilakone code is quite a bit simpler with no macros and less code (reduce-fsm 592 lines, tilakone 145 lines)\n\n## TODO\n\n* proper documentation\n* examples on :enter/:leave actions, state guards, etc\n* add tilakone visualization\n* add perf tests\n\n## License\n\nCopyright \u0026copy; 2019 [Metosin Oy](https://www.metosin.fi/)\n\nDistributed under the Eclipse Public License, the same as Clojure.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmetosin%2Ftilakone","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmetosin%2Ftilakone","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmetosin%2Ftilakone/lists"}