{"id":22942454,"url":"https://github.com/stardustdl/scheme-from-python","last_synced_at":"2025-07-28T02:04:12.942Z","repository":{"id":97887119,"uuid":"543534342","full_name":"StardustDL/scheme-from-python","owner":"StardustDL","description":"An experimental scheme interpreter in Python.","archived":false,"fork":false,"pushed_at":"2023-04-13T15:02:36.000Z","size":67,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-08T16:04:14.150Z","etag":null,"topics":["functional-programming","python","scheme","scheme-interpreter"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/StardustDL.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-09-30T09:53:47.000Z","updated_at":"2024-04-17T22:32:51.000Z","dependencies_parsed_at":"2023-05-31T11:45:32.680Z","dependency_job_id":null,"html_url":"https://github.com/StardustDL/scheme-from-python","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/StardustDL/scheme-from-python","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StardustDL%2Fscheme-from-python","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StardustDL%2Fscheme-from-python/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StardustDL%2Fscheme-from-python/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StardustDL%2Fscheme-from-python/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/StardustDL","download_url":"https://codeload.github.com/StardustDL/scheme-from-python/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StardustDL%2Fscheme-from-python/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267451489,"owners_count":24089312,"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-07-28T02:00:09.689Z","response_time":68,"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":["functional-programming","python","scheme","scheme-interpreter"],"created_at":"2024-12-14T13:47:52.857Z","updated_at":"2025-07-28T02:04:12.896Z","avatar_url":"https://github.com/StardustDL.png","language":"Python","readme":"# ![scheme-from-python](https://socialify.git.ci/StardustDL/scheme-from-python/image?description=1\u0026font=Bitter\u0026forks=1\u0026issues=1\u0026language=1\u0026owner=1\u0026pulls=1\u0026stargazers=1\u0026theme=Light \"scheme-from-python\")\n\n[![](https://github.com/StardustDL/scheme-from-python/workflows/CI/badge.svg)](https://github.com/StardustDL/scheme-from-python/actions) [![](https://img.shields.io/github/license/StardustDL/scheme-from-python.svg)](https://github.com/StardustDL/coxbuild/blob/master/LICENSE)\n\u003c!--[![](https://img.shields.io/pypi/v/scheme-from-python)](https://pypi.org/project/scheme-from-python/) [![Downloads](https://pepy.tech/badge/scheme-from-python?style=flat)](https://pepy.tech/project/scheme-from-python)--\u003e\n\n[scheme-from-python](https://github.com/StardustDL/scheme-from-python) is an experimental scheme interpreter in Python.\n\nhttps://user-images.githubusercontent.com/34736356/193305337-c5a48c83-2d31-4a46-9ff8-370619967530.mov\n\n- Scheme core\n  - [x] define\n  - [x] if\n  - [x] lambda (with closures)\n  - [x] macro (without capturing context)\n- Builtin functions\n  - [x] Boolean operators\n  - [x] Arithmetic operators (integer, float, complex)\n  - [x] Comparing operators\n  - [x] Input / Output functions\n- Interoperation\n  - [x] Auto signature inferring from Python to Scheme\n  - [x] Lazy or non-lazy functions\n  - [x] Capturing the evaluation context (symbol table)\n  - [x] Call pure Python functions\n- Interpreter\n  - [x] File / command-line expression\n  - [x] Auto-indented multi-line\n  - [x] Auto fixing missing right parentheses\n\n\u003e For sequence expression, the final value is the value of the last sub-expression, e.g., `1 2 3` = `3`.\n\n## Python Interoperation\n\nMost static Python functions can be accessed in sfpy, by the qualified name `:builtinAttribute`, `module:`, `module:attribue` or `module:class.attribue`, e.g., `:dir`, `os:getcwd`, `os.path:split`.\n\nsfpy tries to wrap the Python function to adapt to the scheme environment. Have fun to try this experimental feature!\n\n```\n\u003e sys:version\n3.10.4 | packaged by conda-forge | (main, Mar 30 2022, 08:38:02) [MSC v.1916 64 bit (AMD64)]\n\u003e os:getcwd\n(lambda () (...))\n\u003e (os:getcwd)\nD:\\scheme-from-python\\src\n\u003e (:dir math:)\nObject(['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'comb', 'copysign', 'cos', 'cosh', 'degrees', 'dist', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'isqrt', 'lcm', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'nextafter', 'perm', 'pi', 'pow', 'prod', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc', 'ulp'])\n```\n\n## Values\n\n- Boolean: `#t` true, `#f` false\n- Integer: `0`, `-1`, `2`, ...\n- Float: `0.1`, `1.5`, ...\n- Complex: `1+2j`, `3+4j`, ...\n- Symbol: `a`, `b`, `c`, `+`, `-`, ...\n- String: `a`, `b`, `c`, `+`, `-`, ...\n- Function: `(lambda (x) (+ x 1))`, ...\n- Empty: `\u003cempty\u003e` only as return value\n\n## Builtins\n\n### Core\n\n**`(define symbol_name value_expression)`**\n\nDefine a symbol with exact value, and return the value, `def` for a short alternative.\n\n**`(if predicate_expression true_expression false_expresion)`**\n\nBranch expression, if `predicate_expression` is not `#f`, then evaluate and return the value of `true_expression`, otherwise evaluate and return the value of `false_expression`.\n\n**`(lambda (p1 p2 ... pn) body_expression`**\n\nLambda expresion, define an anonymous function (closure) with the parameters named `p1`, `p2`, ..., `pn` (can be empty, i.e., `()`), and the function body, `lam` for a short alternative.\n\nThe lambda function creates a sub-symbol-table, so `define` in a lambda function can only write current symbols, and cannot write upstream symbols (can hidden them by define symbols in the same name). Here is an example code snippet.\n\n```scheme\n\u003e\u003e\u003e ((lambda () (define x 1)))\nx\n\u003e\u003e\u003e x\nUndefined symbol: x\n```\n\n**`(macro (p1 p2 ... pn) body_expression)`**\n\nMacro expression, define a macro, for text replacement with the parameters named `p1`, `p2`, ..., `pn` (can be empty, i.e., `()`), and the macro body, `mac` for a short alternative, no capturing context.\n\n### Boolean\n\n**`(not b)`**\n\n$$=\\neg b$$\n\n**`(and b1 b2 ... bn)`** *without short circuit*\n\n$$=\\bigwedge_{i=1}^n b_i$$\n\n**`(or b1 b2 ... bn)`** *without short circuit*\n\n$$=\\bigvee_{i=1}^n b_i$$\n\n### Arithmetic\n\nThe operands must be integers.\n\n**`(+ v1 v2 ... vn)`**\n\n$$=\\sum_{i=1}^n v_i$$\n\n**`(- v1 v2)`**\n\n$$=v_1 - v_2$$\n\n**`(* v1 v2 ... vn)`**\n\n$$=\\prod_{i=1}^n v_i$$\n\n**`(// v1 v2)`**\n\n$$=\\lfloor v_1 / v_2 \\rfloor$$\n\n**`(/ v1 v2)`**\n\n$$=v_1 / v_2$$\n\n**`(% v1 v2)`**\n\n$$=v_1 \\% v_2$$\n\n**`(^ v1 v2)`**\n\n$$=v_1^{v_2}$$\n\n**`(max v1 v2 ... vn)`**\n\n$$=\\max_{i=1}^n v_i$$\n\n**`(min v1 v2 ... vn)`**\n\n$$=\\min_{i=1}^n v_i$$\n\n### Comparing\n\n**`(\u003c v1 v2)`**\n\n$$=\\textbf{boolean}(v_1 \u003c v_2)$$\n\n**`(\u003c= v1 v2)`**\n\n$$=\\textbf{boolean}(v_1 \\le v_2)$$\n\n**`(\u003e v1 v2)`**\n\n$$=\\textbf{boolean}(v_1 \u003e v_2)$$\n\n**`(\u003e= v1 v2)`**\n\n$$=\\textbf{boolean}(v_1 \\ge v_2)$$\n\n**`(= v1 v2)`**\n\n$$=\\textbf{boolean}(v_1 = v_2)$$\n\n**`(!= v1 v2)`**\n\n$$=\\textbf{boolean}(v_1 \\ne v_2)$$\n\n### Input / Output\n\n**`(print v)`**\n\nPrint the value and return empty.\n\n**`(from filePath)`**\n\nInterprete a source file and return the evaluated value.\n\n**`(symbols)`**\n\nReturn all symbols in the current context, `syms` for a short alternative.\n\n## Install\n\n```sh\nconda create -n sfpy python=3.10\nconda activate sfpy\ncd src\npip install -r requirements.txt\n```\n\n## Usage\n\nsfpy supports interactor (for user input) and interpreter (for file input) mode.\n\n### Interactor Mode\n\n```sh\npython -m sfpy\n```\n\n- Use `_` to access last value.\n\n### Interpreter Mode\n\n```sh\npython -m sfpy -f your_scheme_file\n\npython -m sfpy -e \"your scheme expression\"\n\npython -m sfpy -f ./demo/arithmetic.scm\npython -m sfpy -f ./demo/lambda.scm\npython -m sfpy -f ./demo/factorial.scm\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstardustdl%2Fscheme-from-python","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstardustdl%2Fscheme-from-python","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstardustdl%2Fscheme-from-python/lists"}