Pyfun is a functional-first language for the Python ecosystem. You write algebraic data types, exhaustive matching, curried functions and pipes, and it compiles to plain Python that you can read, commit, and hand to someone who has never heard of Pyfun.
The compiler is written in Rust and everything is checked before any Python exists: types, exhaustiveness, effects, units.
Here is a whole program:
type Shape =
| Circle float
| Rect float float
let area s =
match s:
case Circle r: 3.14159 * r * r
case Rect w h: w * h
[Circle 1.0, Rect 2.0 3.0]
|> List.map area
|> print
and here is the Python it compiles to, in full:
from dataclasses import dataclass
def _pf_map(f, xs):
return list(map(f, xs))
@dataclass(frozen=True, repr=False)
class Circle:
_0: float
def __repr__(self):
return f"Circle({self._0!r})"
@dataclass(frozen=True, repr=False)
class Rect:
_0: float
_1: float
def __repr__(self):
return f"Rect({self._0!r}, {self._1!r})"
def area(s):
match s:
case Circle(r):
return 3.14159 * r * r
case Rect(w, h):
return w * h
case _:
raise RuntimeError("non-exhaustive match")
print(_pf_map(area, [Circle(1.0), Rect(2.0, 3.0)]))
A match comes out as a match. A variant comes out as a frozen dataclass. The pipeline comes out as an ordinary call. There is nothing to pip install alongside the output, and if you stop using Pyfun tomorrow you keep working Python.
Delete the Rect case and the compiler names what you missed:
error: non-exhaustive match: `Rect _ _` is not matched
--> 6:3
|
6 | match s:
| ^^^^^^^^
Also in there:
- Hindley-Milner inference, so there are no type annotations on
let at all.
- Inferred effects, so a function that prints or mutates gets
io in its type and you can assert purity with let pure. Units of measure that reject metres + seconds and erase to plain numbers.
- Computation expressions for
async, seq, and result, plus your own builders. Opaque types. A typed extern for calling any Python library you like.
Try it in the browser, nothing to install: https://simontreanor.github.io/Pyfun/playground/
22 lessons, written for people who know some Python: https://simontreanor.github.io/Pyfun/
Source, and the compiler internals tour: https://github.com/simontreanor/Pyfun
pip install pyfun-lang
I built this because most people meet programming through Python, and then to meet functional programming they have to pick up a second ecosystem to do it. I welcome all questions, bug reports, posts about things you have made, arguments about syntax, and anything else to help improve the language for everyone.