{"id":51371865,"url":"https://github.com/hce/mata-ll","last_synced_at":"2026-07-03T07:33:52.973Z","repository":{"id":363652742,"uuid":"1264209597","full_name":"hce/mata-ll","owner":"hce","description":"Subset of Haskell for the Lua VM","archived":false,"fork":false,"pushed_at":"2026-07-02T11:35:47.000Z","size":1724,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-02T13:24:20.097Z","etag":null,"topics":["haskell-language","lua"],"latest_commit_sha":null,"homepage":"","language":"Rust","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/hce.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-09T17:03:54.000Z","updated_at":"2026-07-02T11:35:50.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/hce/mata-ll","commit_stats":null,"previous_names":["hce/mll","hce/mata-ll"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/hce/mata-ll","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hce%2Fmata-ll","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hce%2Fmata-ll/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hce%2Fmata-ll/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hce%2Fmata-ll/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hce","download_url":"https://codeload.github.com/hce/mata-ll/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hce%2Fmata-ll/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35077510,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-03T02:00:05.635Z","response_time":110,"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":["haskell-language","lua"],"created_at":"2026-07-03T07:33:51.921Z","updated_at":"2026-07-03T07:33:52.964Z","avatar_url":"https://github.com/hce.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"Modest Attempt at Typesystem Augmenting the Lua Language (mata-ll)\n==================================================================\n\nmata-ll is a subset of haskell that is compiled directly into a single\nLua file with no external dependencies.\n\nIf you make a mistake, the compiler is already there to\nstop you before any harm can spread to the runtime.\n\nCalling from Lua into mata-ll:\n\n| `callfib.lua` | `fib.mll` |\n|---------------|-----------|\n| \u003cpre\u003elocal fib = require \"fib\"\u003cbr\u003e\u003cbr\u003elocal fibs = fib.fibonacci(8)\u003cbr\u003efor i, n in ipairs(fibs) do\u003cbr\u003e    print(i, n)\u003cbr\u003eend\u003c/pre\u003e | \u003cpre\u003efib :: [Integer]\u003cbr\u003efib = 1:1:zipWith (+) fib (tail fib)\u003cbr\u003e\u003cbr\u003eexport fibonacci :: Integer -\u003e [Integer]\u003cbr\u003efibonacci = flip take fib\u003c/pre\u003e |\n\nCalling Lua library functions from mata-ll:\n\n```haskell\nrr :: LuaIO \"math.random\" Number\nrr2 :: Integer -\u003e Integer -\u003e LuaIO \"math.random\" Integer\n\nmain :: IO ()\nmain = do\n    randNum \u003c- rr\n    putStrLn $ \"A number between 0.0 and 1.0: \" \u003c\u003e show randNum\n    randNum2 \u003c- rr2 23 42\n    putStrLn $ \"An integer between 23 and 42: \" \u003c\u003e show randNum2\n```\n\nPassing Lua callbacks to mata-ll:\n\n| `callwritefibs.lua` | `writefibs.mll` |\n|---------------------|-----------------|\n| \u003cpre\u003elocal wf = require \"writefibs\"\u003cbr\u003elocal writer = function(fibString)\u003cbr\u003e    print(\"From mata-ll:\", fibString)\u003cbr\u003eend\u003cbr\u003ewf.writeFibs(writer, 12)\u003c/pre\u003e | \u003cpre\u003eexport writeFibs :: (String -\u003e LuaIO s ())\u003cbr\u003e                 -\u003e Integer -\u003e LuaIO s ()\u003cbr\u003ewriteFibs writer = loop 1 1\u003cbr\u003e  where\u003cbr\u003e    loop _ _ 0 = return ()\u003cbr\u003e    loop cur next count = do\u003cbr\u003e      writer (show cur)\u003cbr\u003e      loop next (cur+next) (count-1)\u003c/pre\u003e |\n\nLua functions like `string.format` that accept a variable number of\narguments cannot be given a single type signature in mata-ll. Instead,\ndeclare multiple monomorphic FFI bindings for the arities you need:\n\n```haskell\nfmt1 :: String -\u003e String -\u003e LuaPure \"string.format\" String\nfmt2 :: String -\u003e String -\u003e String -\u003e LuaPure \"string.format\" String\n```\n\nFor dynamic formatting with a variable number of values or mixed types,\nprefer mata-ll native constructs (`\u003c\u003e` and `show`) over `string.format`.\nNote that list functions like `intercalate` do not apply to `String`,\nwhich is opaque rather than `[Char]`; to join a list of strings, fold\nthem with `\u003c\u003e`.\n\n## Project goals\n\nMake available a useful subset of modern haskell to Lua. It is not\nintended to be a replacement for haskell, but rather as a way to write\nhaskell code where you would otherwise write Lua code.\n\nPrimary focus is on writing embedded code in a safer way than is\npossible with Lua without breaking boundaries to Lua.\n\nSpecifically:\n\n* Add the expressiveness, fun and safety of haskell to Lua\n* Target Lua 5.4 and LuaJIT; compile to Lua source for safe loading via mlua\n* Use non-strict evaluation with cheapness analysis (thunk only what's worth thunking)\n* Require no separate runtime; use zero-cost abstractions\n* If zero-cost abstractions don't fully work, use library functions\n* Incorporate new type system research where possible and useful\n* Once a stable version is reached, stay backwards compatible\n* Have an easy interface to plain Lua\n* Be portable and small; the compiler core -- the main part of this\n  project -- shall not incorporate 3rd party rust libraries. Convenience\n  wrappers around it (the `mll` CLI, the wasm playground) may use a few.\n* Use rust's versioning for dependency resolving, not haskell's\n\n## What's the difference between a runtime and library functions?\n\nA runtime implements core functionality, while a library provides\nauxiliary functionality, still relying on the underlying architecture\nfor core functionality.\n\nFor example, you cannot implement green threads with a library on Lua,\nbecause Lua doesn't have green threads. You can, however, implement\nmonads with a library on Lua, because Lua does have 1st class\nfunctions and closures (the core building blocks of monads), while it\ndoes not have monads.\n\n## Why rust, not C\n\nWhile C may seem to be more portable, that is slowly changing: rust is\nadding many targets, and for those, keeping C out is making the build\nprocess more robust.\n\nSince I think the combination of rust and Lua is a good one, one of\nthe primary goals of this project is to make the Lua part a bit \nmore statically typed.\n\nI miss writing haskell code but have mostly decided to do production\nwork in rust. A lot of \"business logic\" is hard to *write* efficiently\nin rust, though, because of rust's focus on memory efficiency. Lua\nfills that gap, but haskell could also fill it. However, a full blown\nhaskell stack has disadvantages:\n\nHuge ecosystem that often experiences \"dependency hell\";\nlarge dependencies for building, huge binaries generated;\nhard to get it to interoperate with rust.\n\nBesides, haskell and its ecosystem offer a full tooling suite, while\nLua is primarily focused on embedding. Using normal haskell would\nincrease complexity for any project embedding it, which is often not\nfeasible.\n\nBy writing the compiler in rust but targeting the Lua IR, I am hoping\nto make it easier to write code that does not require the raw\nperformance that rust offers in a haskell-like language.\n\nIn addition, type safety allows to catch bugs during compile time,\nwhich makes development with the help of an LLM much easier.\n\n## Why rust, not haskell?\n\nBecause the project's purpose is to make haskell available where it\notherwise wouldn't be. Making ghc or another haskell compiler a\nrequirement would defeat that purpose.\n\n## Language properties:\n\nFile extension should be .mll.\n\nEach .mll file is a module, just like in haskell.\n\nWhen compiling an .mll file, included .mll files will be merged into\nthe resulting output .lua file.\n\nWhile the language targets the Lua VM and no additional\nruntime is required, there is no need to stay closely compatible otherwise.\nInteraction between mll and other Lua functions and modules\nhappens through well defined interfaces only.\n\nFor example, within mll scope, a Lua dictionary can and should be\nreused to implement the haskell data construct.\n\nFor interacting with non-mll Lua, an FFI interface is provided.\nThis interface is used both to call into Lua as well as to export\nfunctions to Lua.\n\n## Evaluation strategy\n\nMATA-LL uses non-strict evaluation, like Haskell. Function arguments\nand let bindings are not evaluated until their values are needed.\nThis enables infinite data structures, avoids unnecessary computation,\nand makes the language behave as Haskell programmers expect.\n\nTo avoid the overhead of thunking cheap expressions (and the classic\nspace leak in accumulator patterns), the compiler performs cheapness\nanalysis: expressions that are cheaper to compute than to thunk\n(arithmetic, variable references, literals, constructor applications)\nare evaluated eagerly. Only genuinely expensive expressions (function\ncalls, case expressions) are wrapped in memoizing thunks.\n\nFor the rare cases where explicit control is needed, `seq :: a -\u003e b -\u003e b`\nforces evaluation of its first argument before returning the second.\n\n\n## Acknowledgements\n\nThis project was developed collaboratively by a human and an AI.\nThe design, direction and taste are Hans-Christian's; much of the\nimplementation was written by Claude (Anthropic). It came together over\nabout two weeks of close back-and-forth -- neither of us could have\nbuilt it alone.\n\n## Contributing\n\nBy submitting a pull request, you agree to license your contribution\nunder the MIT License, the same license that covers this project.\n\n## Dependencies\n\nSo far, no dependencies (MLL libraries) are supported. I don't think\nthat's a primary scope for now. But once support is added, they should\nbe resolved in the rust way. Conflicting transitive dependencies must\nnot let a build fail; rather, version numbers should be part of the\ninternal symbols, so that an arbitrary number of conflicting versions\ncan coexist in parallel.\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhce%2Fmata-ll","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhce%2Fmata-ll","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhce%2Fmata-ll/lists"}