{"id":32192049,"url":"https://github.com/arohner/spectrum","last_synced_at":"2025-10-22T01:57:22.365Z","repository":{"id":62434722,"uuid":"62584453","full_name":"arohner/spectrum","owner":"arohner","description":null,"archived":false,"fork":false,"pushed_at":"2021-04-17T12:41:59.000Z","size":1379,"stargazers_count":602,"open_issues_count":14,"forks_count":20,"subscribers_count":38,"default_branch":"master","last_synced_at":"2025-10-22T01:57:10.784Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/arohner.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2016-07-04T19:43:52.000Z","updated_at":"2025-09-14T22:03:40.000Z","dependencies_parsed_at":"2022-11-01T21:16:13.552Z","dependency_job_id":null,"html_url":"https://github.com/arohner/spectrum","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/arohner/spectrum","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arohner%2Fspectrum","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arohner%2Fspectrum/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arohner%2Fspectrum/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arohner%2Fspectrum/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arohner","download_url":"https://codeload.github.com/arohner/spectrum/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arohner%2Fspectrum/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280365591,"owners_count":26318385,"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","status":"online","status_checked_at":"2025-10-21T02:00:06.614Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":[],"created_at":"2025-10-22T01:57:21.137Z","updated_at":"2025-10-22T01:57:22.359Z","avatar_url":"https://github.com/arohner.png","language":"Clojure","funding_links":[],"categories":["Code Analysis and Linter"],"sub_categories":[],"readme":"[![CircleCI](https://circleci.com/gh/arohner/spectrum.svg?style=svg)](https://circleci.com/gh/arohner/spectrum)\n[![Clojars Project](https://img.shields.io/clojars/v/spectrum.svg)](https://clojars.org/spectrum)\n\n# spectrum\n\nA library for doing static analysis of Clojure code, catching clojure.spec conform errors at compile time.\n\n**Wait what?**\n\nIt's like core.typed, but it relies on clojure.spec annotations.\n\n**So it's an optional static type system?**\n\nKind-of. It finds errors at compile time, and predicates kind of look like types. So sure.\n\n![Proving contracts ahead of time](https://pbs.twimg.com/media/CphGpB5VUAAJyGL.jpg)\n\n## Current Status\n\nDeveloper Preview, not yet ready for any kind of use.\n\nCurrent development is working towards making spectrum self-check.\n\n## Goals\n\n- usable\n- pragmatic\n- readable implementation\n- fast\n- configurable strictness levels\n- incremental checking\n\n## Non-goals\n\n- perfection\n- correctness\n- requiring 100% spec coverage.\n\nIn particular, spectrum aims to be fast and usable, and catching\nbugs. It aims to have low false positives, at the expense of\npotentially not catching 100% of type errors.\n\nA tool that catches 80% of bugs that you use every day is better\nthan a 100% tool that you don't use. Spectrum will converge on 100% correct,\nbut won't guarantee correctness for a while.\n\n## Usage\n\nStill under active development, so this is incomplete.\n\nUse clojure.spec as normal. Then, at the repl:\n\n```clojure\n(require '[spectrum.flow :as f])\n(require '[spectrum.types :as t])\n\n(f/infer-var #'foo)\n```\n\n\nThere is also\n\n```clojure\n(f/infer-form '(foo 3))\n```\nwhich is useful when you want to debug the signature of a form.\n\n`infer-form` can optionally take a map of keywordized variables to types\n\n```clojure\n(f/infer-form '(string? x) {:x #'string?})\n#Value[true]\n\n(f/infer-form '(string? x) {:x (t/value-t 3)})\n#Value[false]\n```\n\n## Limitations\n\n- It's still very early.\n\n## Justification\n\n- because I could\n- working example of types = proofs = predicates\n- Some properties of a program are easier to prove at runtime. Some at compile-time\n- this is extra checking on top of spec, not a replacement for it\n- to get HN to shut up about how adding a static type system to a dynamic language is impossible\n- why not just use spec by itself?\n - `instrument` doesn't check return values\n - `check` works best on pure functions with good generators.\n  - Not all clojure code is pure\n  - Not always easy to write a good generator for all functions (hello, any fn that takes a DB connection)\n  - Not always easy to write a generator w/ 100% coverage\n - you can't spec non-defn functions\n - you can't spec higher order functions\n - generative testing with side-effects doesn't work well\n - generative testing gives false negatives on rare codepaths\n - static typing guarantees all codepaths are checked\n - spec doesn't deal with non-fn vars at all (binding, alter-var-root, set!, etc)\n - generative testing can be slow\n\n## Plan\n\nSpectrum is still very early, and not ready for production use. Current development is focused on making spectrum self-check.\n\n## License\n\nCopyright © 2019 Allen Rohner\n\nCreative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farohner%2Fspectrum","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farohner%2Fspectrum","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farohner%2Fspectrum/lists"}