{"id":21535930,"url":"https://github.com/jahfer/rubytie","last_synced_at":"2026-01-25T17:05:51.918Z","repository":{"id":145785568,"uuid":"117987319","full_name":"jahfer/rubyTIE","owner":"jahfer","description":"Type inference engine for Ruby","archived":false,"fork":false,"pushed_at":"2022-06-26T18:58:46.000Z","size":226,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-10T01:59:17.891Z","etag":null,"topics":["ruby","type-inference"],"latest_commit_sha":null,"homepage":"","language":"OCaml","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/jahfer.png","metadata":{"files":{"readme":"README.md","changelog":null,"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-01-18T13:35:32.000Z","updated_at":"2022-06-26T18:58:49.000Z","dependencies_parsed_at":"2023-07-29T13:16:36.051Z","dependency_job_id":null,"html_url":"https://github.com/jahfer/rubyTIE","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jahfer/rubyTIE","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jahfer%2FrubyTIE","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jahfer%2FrubyTIE/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jahfer%2FrubyTIE/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jahfer%2FrubyTIE/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jahfer","download_url":"https://codeload.github.com/jahfer/rubyTIE/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jahfer%2FrubyTIE/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28755563,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-25T16:32:25.380Z","status":"ssl_error","status_checked_at":"2026-01-25T16:32:09.189Z","response_time":113,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["ruby","type-inference"],"created_at":"2024-11-24T03:16:56.799Z","updated_at":"2026-01-25T17:05:51.906Z","avatar_url":"https://github.com/jahfer.png","language":"OCaml","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Ruby Type Inference Engine (TIE)\n\nVery much a work-in-progress. I have no idea what I'm doing.\n\n## Todo List\n- [ ] Constraint generation\n  - [x] Literals\n  - [x] Subtypes\n  - [ ] Disjuction (list of potential outcomes)\n  - [ ] Class\n- [x] Simplification\n  - [x] Unification of type variables\n- [x] Solver\n- [ ] Type interfaces for built-ins\n\n## Examples\n\n### Type Checking\n\n**Input**\n\n```\n1| x = false\n2| y = 3\n3|\n4| a = x\n5| a = y\n6|\n7| z = a.foo\n8| z\n9| y\n\n```\n\n**Output**\n\n```clj\n(lvasgn `x\n  (false : bool) : bool)\n\n(lvasgn `y\n  (3 : int) : int)\n\n(lvasgn `a\n  (lvar `x : bool) : int|bool)\n\n(lvasgn `a\n  (lvar `y : int) : int|bool)\n\n(lvasgn `z\n  (send\n    (lvar `a : int|bool) `foo : T11) : T11)\n\n(send\n  (lvar `z : T11) `bar : T13)\n\n(lvar `y : int)\n```\n\n### Kitchen Sink\n\n**Input**\n\n```ruby\nfoo\n45\n\nparams = {\n  \"key\": true,\n  \"another\": \"value\"\n}\n\n@x = :my_symbol\n@x\n\nFooBar = 151.56\nFooBar\n\nstmt1 = 3; stmt2 = 1\n\ndef sum0(); false end\n\ndef sum1(thing)\n  45\nend\n\ndef sum2(thing1, thing2) end\n\ndef maybe_sum(a, b, should_do_thing) end\n\nfalse\n\ny = [1,2,3]\ny.first\nz = y.first\n\nfunc1 = -\u003e { x = 45 }\nfunc2 = -\u003e (local) { }\nfunc3 = -\u003e (local, _x) {\n  local.first\n}\nfunc3.call(y)\n\nb = 3\na = b\n\nsum1(5)\nsum2(1,2)\nmaybe_sum(3, 5, false)\n\n-\u003e (local, _x) {\n  local.first\n}\n```\n\n```bash\n$ FILE=data/test_kitchen_sink.rb make run\n```\n\n**Output**\n\n```clj\n(lvar `foo : T1)\n\n(45 : int)\n\n(lvasgn `params\n  ({ \"key\": true, \"another\": \"value\" } : hash) : hash)\n\n(ivasgn @x\n  (:my_symbol : symbol) : symbol)\n\n(ivar `@x : symbol)\n\n(casgn FooBar\n  (151.560000 : float) : float)\n\n(const\n  (nil : T10) `FooBar : float)\n\n(lvasgn `stmt1\n  (3 : int) : int)\n\n(lvasgn `stmt2\n  (1 : int) : int)\n\n(def `sum0 ()\n  (false : T16) : T17)\n\n(def `sum1 (args (arg `thing))\n  (45 : T18) : T19)\n\n(def `sum2 (args (arg `thing1) (arg `thing2))\n  (nil : T20) : T21)\n\n(def `maybe_sum (args (arg `a) (arg `b) (arg `should_do_thing))\n  (nil : T22) : T23)\n\n(false : bool)\n\n(lvasgn `y\n  ([1 2 3] : array\u003cT65\u003e) : array\u003cT65\u003e)\n\n(send\n  (lvar `y : array\u003cT65\u003e) `first : T28)\n\n(lvasgn `z\n  (send\n   (lvar `y : array\u003cT65\u003e) `first : T28) : T28)\n\n(lvasgn `func1\n  (lambda ()\n    (lvasgn `x\n      (45 : int) : int) : lambda\u003c? -\u003e T33\u003e) : lambda\u003c? -\u003e T33\u003e)\n\n(lvasgn `func2\n  (lambda (args (arg `local))\n    (nil : nil) : lambda\u003c? -\u003e T36\u003e) : lambda\u003c? -\u003e T36\u003e)\n\n(lvasgn `func3\n  (lambda (args (arg `local) (arg `_x))\n    (send\n      (lvar `local : T39) `first : T40) : lambda\u003c? -\u003e T40\u003e) : lambda\u003c? -\u003e T40\u003e)\n\n(send\n  (lvar `func3 : lambda\u003c? -\u003e T40\u003e) `call\n    (lvar `y : array\u003cT65\u003e) : T45)\n\n(lvasgn `b\n  (3 : int) : int)\n\n(lvasgn `a\n  (lvar `b : int) : int)\n\n(send\n  (nil : nil) `sum1\n    (5 : int) : T52)\n\n(send\n  (nil : nil) `sum2\n    (1 : int)\n    (2 : int) : T56)\n\n(send\n  (nil : nil) `maybe_sum\n    (3 : int)\n    (5 : int)\n    (false : bool) : T61)\n\n(lambda (args (arg `local) (arg `_x))\n  (send\n    (lvar `local : T39) `first : T40) : lambda\u003c? -\u003e T63\u003e)\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjahfer%2Frubytie","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjahfer%2Frubytie","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjahfer%2Frubytie/lists"}