Skip to content

Latest commit

 

History

History
96 lines (70 loc) · 1.98 KB

README.md

File metadata and controls

96 lines (70 loc) · 1.98 KB

Pure Functional Python

PFPy aims to transpile to Python (3.12), while providing 100% type coverage. The language syntax try to be familiar to Python programmers while borrowing some syntax from OCaml. The transpiled code is fully typed.

The goal is to enable formally verifying Python code by placing restrictions on the code itself.

The available Python constructs are:

  • Functions
  • Match statements
  • If statements
  • Dataclasses
  • Python expressions

The unavailable Python costructs (not an exaustive list) are:

  • No classes
  • No exceptions
  • No methods
  • No iterators

Also all functions are:

  • Fully typed, supporting type parameters
  • Consists of a single expression

Let's se an example:

# test/result.fy
from typing import Callable, Union;
from dataclasses import dataclass;

data Result[T, E] = Union[Ok[T], Error[E]];

def bind_result[A, B, E](
  x: Result[A, E],
	f: A -> Result[B, E]
): Result[B, E] =
  match x with
  | Ok(y) => f(y)
  | Error(e) => Error(e)
  end;

print(
  bind_result(Ok(1), lambda (x: int) =>
  bind_result(Ok(2), lambda (y: int) =>
  Ok (x + y))));

This code is translated to this Python code:

from typing import Callable, Union

from dataclasses import dataclass

@dataclass
class Ok[T]:
    value0: T

@dataclass
class Error[E]:
    value0: E

type Result[T, E] = Union[Ok[T], Error[E]]

def bind_result[A, B, E](x: Result[A, E], f: Callable[[A], Result[B, E]]) -> Result[B, E]:
    match x:
        case Ok(y):
            return f(y)
        case Error(e):
            return Error(e)

print(bind_result(Ok(1), (lambda x: bind_result(Ok(2), (lambda y: Ok(x + y))))))

The most "magical" construct of PFPy is the data statement, which expands type classes for each type constructor. Also the arrow operator expands to Callable calls making function types more readable.

To translate PFPy code use the stdin, e.g.:

pfpy < test/test.fy

To build and install you'll need dune and opam

dune install

After that pfpy will be in your path