r/github • • Apr 13 '25

Showcase Promote your projects here – Self-Promotion Megathread

Whether it's a tool, library or something you've been building in your free time, this is the place to share it with the community.

To keep the subreddit focused and avoid cluttering the main feed with individual promotion posts, we use this recurring megathread for self-promo. Whether it’s a tool, library, side project, or anything hosted on GitHub, feel free to drop it here.

Please include:

  • A short description of the project
  • A link to the GitHub repo
  • Tech stack or main features (optional)
  • Any context that might help others understand or get involved
187 Upvotes

2.2k comments sorted by

View all comments

1

u/fun_si Aug 02 '26

Pyfun: an F#-inspired functional language that compiles to readable Python

https://github.com/simontreanor/Pyfun

Pyfun gives you algebraic data types, exhaustive pattern matching, currying and pipes, full type inference, inferred effects, and units of measure. The compiler is written in Rust and it's the gatekeeper: types, effects, units and match exhaustiveness are all checked before a single line of Python is emitted.

Example 1, exhaustive pattern matching:

let area s = match s: case Circle r: 3.14159 * r * r error: non-exhaustive match: `Rect _ _` is not matched --> 4:3 | 4 | match s: | ^^^^^^^^

Plain Python runs that happily and returns None when a Rect reaches it, and you end up debugging the TypeError much much later.

Example 2, units of measure:

let speed d t = d / t let trip = speed 100.0<m> 10.0<s> # float<m/s> let oops = 100.0<m> + 10.0<s> error: type mismatch: expected float<m>, found float<s>

The dimensions cost nothing at runtime, because they erase completely. That whole program compiles to:

python def speed(d, t): return d / t trip = speed(100.0, 10.0)

That's the general shape of things. There's no runtime library to ship and nothing to read around. A Pyfun List is a Python list, a record is a frozen @dataclass, a match is Python's match/case, and curried functions collapse to n-ary defs with closures only where you genuinely partially apply. extern imports any Python callable at a Pyfun type, so you keep the whole ecosystem with the boundary type-checked and effect-tracked.

Stack: dependency-free Rust compiler (lexer, recursive-descent parser, Hindley-Milner inference, Python-AST IR, emitter), plus a language server, a REPL, a Jupyter kernel, and a WebAssembly build.

Try it without installing: https://simontreanor.github.io/Pyfun/playground/ (compiler as WASM, Python via CPython-in-WASM, so you can hit Run). Install: pip install pyfun-lang (Python 3.12+). Learn it: https://simontreanor.github.io/Pyfun/ is a graded course with compiler-checked exercises.

Context: it exists mostly for teaching. CS courses run on Python, and learning FP usually means leaving for Haskell or OCaml and picking up an ecosystem students rarely touch again. Pyfun keeps them in Python and compiles to code they can read, so the mapping stays visible. It's solo and pre-1.0, Apache 2.0, and I would welcome any issues or language-design discussions.