{"id":19584045,"url":"https://github.com/rishavs/fea","last_synced_at":"2026-05-14T17:40:08.252Z","repository":{"id":147879286,"uuid":"136353317","full_name":"rishavs/fea","owner":"rishavs","description":"A tiny and elegant functional language","archived":false,"fork":false,"pushed_at":"2026-04-23T10:40:11.000Z","size":3750,"stargazers_count":0,"open_issues_count":4,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-04-23T12:24:15.195Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/rishavs.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2018-06-06T16:02:42.000Z","updated_at":"2026-04-23T10:40:15.000Z","dependencies_parsed_at":null,"dependency_job_id":"fc39239c-551e-4c3f-8574-ea08b301f9a5","html_url":"https://github.com/rishavs/fea","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rishavs/fea","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rishavs%2Ffea","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rishavs%2Ffea/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rishavs%2Ffea/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rishavs%2Ffea/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rishavs","download_url":"https://codeload.github.com/rishavs/fea/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rishavs%2Ffea/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33036175,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-13T13:14:54.681Z","status":"online","status_checked_at":"2026-05-14T02:00:06.663Z","response_time":57,"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":"2024-11-11T07:46:22.084Z","updated_at":"2026-05-14T17:40:08.231Z","avatar_url":"https://github.com/rishavs.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Fëa\n\n\u003e A tiny and elegant functional language \n\n## About\n\nThe Fea compiler is written in Nim\n\nInspired by F#, attolang and Keli language.\n\n## Principles (in order of priority)\n1. Dev Exp is most important\n2. Batteries included\n3. Instant compilation\n4. Readability\n5. C like performance\n\n# Rough\n\n\n\nQuick thoughts\n\n- literate. Everything is a comment. \n  Except the bits which are in the markdown code tags \n  \n - each file is a package. see ES6 imports/exports for how modules should behave \n\n- extremely small. all syntax \"should fit on a postcard\"\n\n- compiles to c99. 80% of the performance of C with only 20% of the headache\n\n- Static Typing with type inference\n\n- Impure functional\n\n- only one way to do anything\n\n- filenames as modules and namespaces. start at main.fea always\n\n- fully async, concurrent and parallel by default\n\n- no globals. everything is local scoped\n\n- no vars?\n\n- utf8 strings\n\n- FRP?\n\n- memory. ARC vs Immix?\n\n- has algebraic types and maybes\n\n- how to error? railroad?\n\n- hot reloading? with a aot release version for speedup?\n- All keywords can be fully internationalized\n\n- build types [dev(fastest compilation), debug, release(fastest execution and low overhead)]\n\n- opinionated formatter in compiler itself with opt-out\n\n- Test block part of function definition?\n\n- Only way for a statement to access a var in the immediate parent scope is to use the parent.x or parentid.x\n\n- Declarations and control flow constructs are expressions too. “everything is an expression” . To do that, for each “statement-like” construct in the language, you need to decide what value it evaluates to. eg\n\n  - A variable declaration evaluates to the value of the variable.\n  - A block evaluates to the result of the last expression in the sequence.\n  - An `if` expression evaluates to the result of whichever branch is chosen. Likewise, a `switch` or other multi-way branch evaluates to whichever case is picked\n\n- Everything is either code or data.\n\n  all data is a key value object. every data object must be of a basic type or a composed type.\n\n  all code is either expression or function.\n\n```\nint a is 2\n\ndefine Circle as {\n    radius: Int,\n    circumference:Int\n    }\nend\n\nCircle new_circle is {\n    radius is 10,\n    circumference is 20\n    }\n\ndefine LotsaCircles as\n    List of Circle\nend\n\ndefine Answer as\n    | Yes\n    | No\nend\n\n\n// retruns/retrun/returning are all same//\n\ndo substract int a, int b return int as\n    if a \u003c b and a \u003e 0 and b \u003e 0\n        say \"Can't do. 0 is my best offer!\"\n        0\n    else \n        a - b\n    end\nend\n\n\n\ndo additionof a, b as a + b end\n\nint a is additionof 2, 3\n\ndo add_then_square_and_check_even \n    int a, int b \n    return \n        fact, string \n    as\n        x   is checkifeven square add a,b\n        x   is flow add a,b then square then checkifeven end\n\nend\n\ndo ifelseflow fact isTrue return \n    say \"Is True\"\n\n// builtin?\ndefine case as {\n    path1: do,\n    path2:  block\n    }\nend\n\nCase caseflow is {\n    4 : fncall1,\n    5 : fncall2,\n    _ : fncall3  \n}\n\nmap caseflow int k, block v \n\neval ( int x) return int as\n    y is \n    if x \u003c 5 then \n        something\n    elseif x \u003e10 then something\n    else something\n    end\n\n```\n\n# Rough\n\nCompiler Starts\n\n- read program file \n- Extract code part\n- Stitch code blocks in a file\n- stitch code blocks from other files into a single string\n- Tokenize and parse grammar into ordered array of tokens\n- raise syntax and parsing errors\n- detail error and hint by analyzing characters\n- identify identifier scoping\n- Compile time evaluation/constant folding??\n- unfold blocks like loops, functions etc into nodes\n- raise recursion errors\n- Stitch modules and calls\n- raise semantic errors like missing branches in conditionals\n\nAST Generated\n\n- check types\n- infer types for missing ones\n- raise type errors, if conflict\n- Basic tree shaking/folding??\n\nClean AST Generated\n\nTransform To X AST/IR/Codegen\n\n#### Error\n\nLine number, char number of token\n\ntype\n\nmessage\n\nHint\n\n#### Flow\n\n\n\nSearch for ```\n\n​\tIf any instance of ``` is not appended by BOL + optional whitespace raise error\n\n​\tif ``` doesnt have a closing counterpart, raise error\n\n​\telse extract all text between 2 consecutive ``` and save somewhere\n\nstitch all extracted text\n\nstart parsing\n\n\n\n\n\n\n\n\n\nParts of the lang:\n\n* MDText\n  * CodeText\n    * Code\n      * Expression\n        * Operators (infix?)\n      * Statement\n      * id \n      * typeassign\n      * type\n        - BasicType\n        - ComplexType\n          - SumType\n          - ObjectType\n      * valueassign\n      * codeblockassign\n      * Symbols\n        * BOF\n        * EOF\n        * Whitespace\n        * EOL\n        * BOL\n      * Comment\n  * LitText\n* \n\nMemory only stack based? using linked lists internally?\n\neverything is an assignment and a function\n\na:int -\u003e 10\n\nis same as a\n\na:int (_:null) -\u003e 10 end\n\nIf is itself a function taking arguments (expression, truthi returnable, falsey returnable)?\n\nif add(6,4) == 10:\n\n​\tthen print \"10 is the truth\"\n\n​\telse print \"10 is not the truth\"\n\n\n\nx:truth -\u003e equals (add(6,4), 10)\n\n\n\n\n\nadd:task (x:int, y:int):int -\u003e\n    x + y\nend\n\nn:int is add x, y\n\ndo add(y:int):int -\u003e\n    x + y\nend\n\nd:list:int -\u003e [2,3]\ne:obj:{str =\u003e str} -\u003e {\"key\" =\u003e \"value\"}\n\nx:int -\u003e 2\n\ndo add (y:int):int -\u003e\n    x + y\nend\n\nstart ():int -\u003e\n    _ -\u003e show add (1)\n    0\nend\n\nany var, const, module object that needs to be shared should have $ suffix\nlocal scope will always take precedence. if a var form another scope is to be used, use the full path module.var eg main.x in the add func.\nNo modules. the file name is the module namespace. if namespace needs to be changed, change file\nshow is a builtin func which pretty prints to console\n\n? checks if a val exists\n\nstd:book    -\u003e read stdlib // no need to use brackets if only 1 argument\nBO::book    -\u003e read BasicOprerations from ('../path')\n\n@Const\n#addresses\n$shared\n\na:int -\u003e 10\nstart (a:int):int\n\n```\nflow with a\n    |\u003e BO.substract #, 5    \u003e\u003e BO.multiply #, 10        \u003e\u003e val is #     \u003e\u003e say #\n    |\u003e amplify #, 2         \u003e\u003e val is #                 \u003e\u003e say #\n    |\u003e say #                \u003e\u003e std.formatter.pretty #\nend\n\nreturn 0\n\ncatching error \n    if typeof(error) == # // pattern matching\n        # == WrongType -\u003e\n            say(\"The error type is {{#}}\")\n        # == else -\u003e\n            say (\"Some unhandled error was found\")\n    end\nend\n```\n\nend\n\nstart\n\ntake a\n|\u003e fna \u003e\u003e fnb\n|\u003e fnc \u003e\u003e fnd\n\ntypedef = recipe?\n\n------\n\na:int -\u003e 20\n\nshare amplify (x:int, y:int):int -\u003e\n    x^y\nend\n\na:int -\u003e 30\n\ndo $substract (x:int, y:int):int -\u003e // $ makes a func public\n    x - y\nend\n\ndo $add (x:int, y:int):int -\u003e\n    let z = x + y\n    return z\nend\n\nmultiply (x:int, y:int):int -\u003e x * y\n\nexpose(add, substract, multiply)\n\n\n\n```nim\nCoder:define =\u003e\n  \t| Person:{    \t\n  \t\tname:string,\n    \tage:int\n    }\n  \t| Employee:Person\n  \t| \"whelp\":str\nend\n\npeep:Coder =\u003e {name = \"Rick\", age = 35}\n```\n\n\n\n## License\n\nCopyright (c) 2018\n\nLicensed under the [MIT license](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frishavs%2Ffea","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frishavs%2Ffea","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frishavs%2Ffea/lists"}