{"id":13780848,"url":"https://github.com/burz/cfl","last_synced_at":"2025-08-23T06:13:03.627Z","repository":{"id":25238165,"uuid":"28662779","full_name":"burz/cfl","owner":"burz","description":"a Compileable statically typed Functional programming Language","archived":false,"fork":false,"pushed_at":"2015-06-11T18:41:30.000Z","size":1216,"stargazers_count":11,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-11T17:49:19.975Z","etag":null,"topics":["compiler","functional-programming","interpreter","llvm"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/burz.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}},"created_at":"2014-12-31T09:56:27.000Z","updated_at":"2024-09-24T16:46:27.000Z","dependencies_parsed_at":"2022-08-23T22:00:46.144Z","dependency_job_id":null,"html_url":"https://github.com/burz/cfl","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/burz/cfl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/burz%2Fcfl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/burz%2Fcfl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/burz%2Fcfl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/burz%2Fcfl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/burz","download_url":"https://codeload.github.com/burz/cfl/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/burz%2Fcfl/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271745703,"owners_count":24813518,"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-08-23T02:00:09.327Z","response_time":69,"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":["compiler","functional-programming","interpreter","llvm"],"created_at":"2024-08-03T18:01:20.417Z","updated_at":"2025-08-23T06:13:03.566Z","avatar_url":"https://github.com/burz.png","language":"C","funding_links":[],"categories":["C"],"sub_categories":[],"readme":"cfl\n===================================\n\nAuthor: Anthony Burzillo\n\n******\n\ncfl (standing for C-based Functional Language) is a statically typed\nfunctional programming language.\n\n## Usage\n\nTo see the usage simply run `./cfl`. If LLVM is already installed (can be installed by running\n`brew install llvm` or `apt-get install llvm`, etc.) then the usage will be\n```\n$ ./cfl\nUSAGE: cfl filename       :: compile the program\n           -ast filename  :: print the AST of the program\n           -type filename :: print the high level types of the program\n           -deep filename :: print all the types of the program\n           -eval filename :: evaluate the program\n           -ll filename   :: print out the llvm code for the program\n           -asm filename  :: print out native assembly code for the program\n           -jit filename  :: evaluate the program using Just-In-Time compiling\n```\nNote that you can still run cfl without LLVM but you will not have LLVM related options like\n-jit or compilation.\n\n## Example\n\nObligatory hello world:\n```\nmain = \"hello world!\"\n```\nNote that every cfl program must end with a `main` and global definitions are followed by\na semicolon.\n\nThe quicksort algorithm can be written in cfl as\n```\nsplit x xs l r = case xs of\n      []       -\u003e (l, r)\n    | (y : ys) -\u003e let (l', r') = split x ys l r in if y \u003c= x\n        then (y : l', r')\n        else (l', y : r');\n\nquicksort x = case x of\n      []       -\u003e []\n    | (y : ys) -\u003e let (l, r) = split y ys [] []\n        in quicksort l ++ y : quicksort r;\n\n// random x is a globally defined function returning a random integer\n// between 0 and x inclusive\nrandom_list x l = if x == 0 then [] else random l : random_list (x - 1) l;\n\nmain = quicksort $ random_list 100 500\n```\n\nRunning `./cfl -ast` will output\n```\nsplit ::= function ~F0 -\u003e (let rec split x = (function xs -\u003e (function l -\u003e (function r -\u003e (case (xs) of [] -\u003e ((l, r)) | (y : ys) -\u003e ((function (l', r') -\u003e (if (((y) \u003c (x)) || ((y) == (x))) then (((y) : (l'), r')) else ((l', (y) : (r'))))) (((((split) (x)) (ys)) (l)) (r))))))) in ((split) (~F0)))\nquicksort ::= function ~F1 -\u003e (let rec quicksort x = (case (x) of [] -\u003e ([]) | (y : ys) -\u003e ((function (l, r) -\u003e (((quicksort) (l)) ++ ((y) : ((quicksort) (r))))) (((((split) (y)) (ys)) ([])) ([])))) in ((quicksort) (~F1)))\nrandom_list ::= function ~F2 -\u003e (let rec random_list x = (function l -\u003e (if ((x) == (0)) then ([]) else (((random) (l)) : (((random_list) ((x) + ((-1) * (1)))) (l))))) in ((random_list) (~F2)))\nmain ::= (quicksort) (((random_list) (100)) (500))\n```\n\nRunning `./cfl -type` will output\n```\nsplit =\u003e (Integer -\u003e ([Integer] -\u003e ([Integer] -\u003e ([Integer] -\u003e ([Integer], [Integer])))))\nquicksort =\u003e ([Integer] -\u003e [Integer])\nrandom_list =\u003e (Integer -\u003e (Integer -\u003e [Integer]))\nmain =\u003e [Integer]\n```\n\nRunning `./cfl -deep` will output\n```\nsplit ~\u003e\u003e function (~F0 :: Integer) -\u003e (let rec (split :: (Integer -\u003e ([Integer] -\u003e ([Integer] -\u003e ([Integer] -\u003e ([Integer], [Integer])))))) (x :: Integer) = (function (xs :: [Integer]) -\u003e (function (l :: [Integer]) -\u003e (function (r :: [Integer]) -\u003e (case (xs :: [Integer]) of [] -\u003e ((l :: [Integer], r :: [Integer]) :: ([Integer], [Integer])) | ((y :: Integer) : (ys :: [Integer])) -\u003e ((function ((l' :: [Integer], r' :: [Integer]) :: ([Integer], [Integer])) -\u003e (if (((y :: Integer) \u003c (x :: Integer) :: Bool) || ((y :: Integer) == (x :: Integer) :: Bool) :: Bool) then (((y :: Integer) : (l' :: [Integer]) :: [Integer], r' :: [Integer]) :: ([Integer], [Integer])) else ((l' :: [Integer], (y :: Integer) : (r' :: [Integer]) :: [Integer]) :: ([Integer], [Integer])) :: ([Integer], [Integer])) :: (([Integer], [Integer]) -\u003e ([Integer], [Integer]))) (((((split :: (Integer -\u003e ([Integer] -\u003e ([Integer] -\u003e ([Integer] -\u003e ([Integer], [Integer])))))) (x :: Integer) :: ([Integer] -\u003e ([Integer] -\u003e ([Integer] -\u003e ([Integer], [Integer]))))) (ys :: [Integer]) :: ([Integer] -\u003e ([Integer] -\u003e ([Integer], [Integer])))) (l :: [Integer]) :: ([Integer] -\u003e ([Integer], [Integer]))) (r :: [Integer]) :: ([Integer], [Integer])) :: ([Integer], [Integer])) :: ([Integer], [Integer])) :: ([Integer] -\u003e ([Integer], [Integer]))) :: ([Integer] -\u003e ([Integer] -\u003e ([Integer], [Integer])))) :: ([Integer] -\u003e ([Integer] -\u003e ([Integer] -\u003e ([Integer], [Integer]))))) in ((split :: (Integer -\u003e ([Integer] -\u003e ([Integer] -\u003e ([Integer] -\u003e ([Integer], [Integer])))))) (~F0 :: Integer) :: ([Integer] -\u003e ([Integer] -\u003e ([Integer] -\u003e ([Integer], [Integer]))))) :: ([Integer] -\u003e ([Integer] -\u003e ([Integer] -\u003e ([Integer], [Integer]))))) :: (Integer -\u003e ([Integer] -\u003e ([Integer] -\u003e ([Integer] -\u003e ([Integer], [Integer])))))\nquicksort ~\u003e\u003e function (~F1 :: [Integer]) -\u003e (let rec (quicksort :: ([Integer] -\u003e [Integer])) (x :: [Integer]) = (case (x :: [Integer]) of [] -\u003e ([] :: [Integer]) | ((y :: Integer) : (ys :: [Integer])) -\u003e ((function ((l :: [Integer], r :: [Integer]) :: ([Integer], [Integer])) -\u003e (((quicksort :: ([Integer] -\u003e [Integer])) (l :: [Integer]) :: [Integer]) ++ ((y :: Integer) : ((quicksort :: ([Integer] -\u003e [Integer])) (r :: [Integer]) :: [Integer]) :: [Integer]) :: [Integer]) :: (([Integer], [Integer]) -\u003e [Integer])) (((((split :: (Integer -\u003e ([Integer] -\u003e ([Integer] -\u003e ([Integer] -\u003e ([Integer], [Integer])))))) (y :: Integer) :: ([Integer] -\u003e ([Integer] -\u003e ([Integer] -\u003e ([Integer], [Integer]))))) (ys :: [Integer]) :: ([Integer] -\u003e ([Integer] -\u003e ([Integer], [Integer])))) ([] :: [Integer]) :: ([Integer] -\u003e ([Integer], [Integer]))) ([] :: [Integer]) :: ([Integer], [Integer])) :: [Integer]) :: [Integer]) in ((quicksort :: ([Integer] -\u003e [Integer])) (~F1 :: [Integer]) :: [Integer]) :: [Integer]) :: ([Integer] -\u003e [Integer])\nrandom_list ~\u003e\u003e function (~F2 :: Integer) -\u003e (let rec (random_list :: (Integer -\u003e (Integer -\u003e [Integer]))) (x :: Integer) = (function (l :: Integer) -\u003e (if ((x :: Integer) == (0 :: Integer) :: Bool) then ([] :: [Integer]) else (((random :: (Integer -\u003e Integer)) (l :: Integer) :: Integer) : (((random_list :: (Integer -\u003e (Integer -\u003e [Integer]))) ((x :: Integer) + ((-1 :: Integer) * (1 :: Integer) :: Integer) :: Integer) :: (Integer -\u003e [Integer])) (l :: Integer) :: [Integer]) :: [Integer]) :: [Integer]) :: (Integer -\u003e [Integer])) in ((random_list :: (Integer -\u003e (Integer -\u003e [Integer]))) (~F2 :: Integer) :: (Integer -\u003e [Integer])) :: (Integer -\u003e [Integer])) :: (Integer -\u003e (Integer -\u003e [Integer]))\nmain ~\u003e\u003e (quicksort :: ([Integer] -\u003e [Integer])) (((random_list :: (Integer -\u003e (Integer -\u003e [Integer]))) (100 :: Integer) :: (Integer -\u003e [Integer])) (500 :: Integer) :: [Integer]) :: [Integer]\n```\n\nRunning `./cfl -eval` or `./cfl -jit`, or running `./cfl program.cfl` and then `./program` will output something like\n```\n[0, 1, 3, 8, 14, 15, 16, 17, 25, 32, 37, 38, 40, 46, 61, 61, 64, 77, 80, 106, 108, 110, 111, 113, 121, 127, 134, 134, 137, 144, 149, 151, 158, 160, 165, 177, 179, 180, 188, 192, 196, 200, 201, 202, 212, 216, 218, 220, 223, 230, 236, 239, 239, 244, 251, 253, 265, 269, 281, 294, 301, 304, 308, 315, 323, 332, 334, 356, 359, 372, 373, 374, 375, 375, 383, 385, 387, 392, 393, 397, 398, 399, 402, 412, 420, 425, 431, 433, 438, 440, 441, 445, 452, 454, 459, 474, 482, 488, 489, 495]\n```\n\n## Expressions\n\n### Basic types\n\nThe basic types of cfl are bools (`true` or `false`), integers (`0, 1, -1, ...`), and\ncharacters (`'q'`).\n\n### Boolean Operations\n\ncfl allows conjunction (`\u0026\u0026`), disjunction (`||`), and negation (`!`) expressions.\n\n### Integer Operations\n\nThe operations of addition (`+`), subtraction (`-`), multiplication (`*`), division\n(`/`), and modulus (`%`) evaluate to integer values. On the other hand, the comparison\noperators of equality (`==`), inequality (`!=`), less-than (`\u003c`), less-than-or-equal\n(`\u003c=`), greater-than (`\u003e`), and greater-than-or-equal (`\u003e=`) all evaluate to boolean\nvalues.\n\n### Functional Operations\n\ncfl allows the creation of anonymous functions via `function x -\u003e e` where `e` is some\nexpression, and `x` is the argument to the function. We can create multiple argument\nanonymous functions via `function x -\u003e function y -\u003e e` where `x` is\nthe first argument and `y` is the second, etc.\n\nTo apply a function `f` simply use `f e` where `e` is the expression for the first\nargument, or `f e1 e2` for the first argument `e1` and second argument `e2`. Similary\none can use `f $ x` to apply the entire right side of the `$` to `f`.\n\nFinally, one can compose two functions `f . g`.\n```\ng a = if a then 5 else 4;\nf b = b == 5;\nmain = f . g $ true\n```\n\n### If Expressions\n\nUse `if e1 then e2 else e3`.\n\n### Let Expressions\n\ncfl allows let expressions to define constants and functions (possibly recursive) via\n```\nlet x = 4 in x + 54\n```\nand\n```\nlet f x y = if x = 0 then 0 else y + f (x - 1) y in f 3 4\n```\n\n### Tuple Expressions\n\nTuples of arbitrary size can be created via `(true, false, [0], 1, [false])`.\n\nAnything but a function name can be matched to a tuple in `let` statements, for instance\n```\nlet (x, y) = (1, 2) in x + y\nlet f (x, y) = x + y in f 0 1\n```\nare both valid.\n\n### List Expressions\n\nYou can create empty lists `[]` or lists with values `[1, 2, 3, 4]`. You can push\nvalues onto a list via\n```\n5 : [4, 5, 6]\n```\nYou can also concatenate lists\n```\n[1, 2] ++ [3, 4]\n```\nFinally, we can match on lists via a case expression via\n```\ncase e1 of [] -\u003e e2 | (x : xs) -\u003e e3\n```\n\n### String Expressions\n\nStrings are implemented as lists of characters, therefore characters can be pushed onto\nstrings and two strings can be concatenated. To create a string one can simply write the\nquotation enclosed string, i.e. `\"hello world!\"`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fburz%2Fcfl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fburz%2Fcfl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fburz%2Fcfl/lists"}