FPL

Dit is de homepage van de repo. Hiervanaf kan je gaan verkennen.

Goal

FPL should maximize the capacity it affords its operators to achieve their goals per unit of complexity and effort.

Those goals: solving problems by making fast, efficient, safe and ergonomic software.

What FPL is

A two-level language (2LTT [1]): a fixed meta level over an object level whose theory is pluggable. The default object theory is call-by-push-value (CBPV [2]). Terms are abstract binding trees (ABT [3]); the text is homoiconic and concatenative.

Get started

These entry points are planned, not yet published.

Try it

nix run github:fpl-org/fpl   # try FPL without cloning

In a container

podman run -it ghcr.io/fpl-org/fpl

Hack on it

git clone https://github.com/fpl-org/fpl && cd fpl
direnv allow       # once; without direnv, run `nix develop` each time you enter
nix flake check    # run every gate

Where things are

FPL
├── .agents/      # how agents work here (commits, branches, quality)
├── 01-bootstrap/    # our first implementation: a Python walker using Lark
│   ├── 01.01-boundary/
│   │   ├── 01.01.01-source.md
│   │   ├── 01.01.02-fon.md
│   │   ├── 01.01.03-pipe.md
│   │   └── 01.01.04-render.md
│   ├── 01.02-pass/
│   │   ├── 01.02.01-lex.md
│   │   ├── 01.02.02-parse.md
│   │   ├── 01.02.03-resolve.md
│   │   ├── 01.02.04-expand.md
│   │   ├── 01.02.05-desugar.md
│   │   ├── 01.02.06-elaborate.md
│   │   ├── 01.02.07-lower.md
│   │   ├── 01.02.08-normalize.md
│   │   ├── 01.02.09-optimize.md
│   │   ├── 01.02.10-evaluate.md
│   │   └── 01.02.11-codegen.md
│   ├── 01.03-repr/
│   │   ├── 01.03.01-source.md
│   │   ├── 01.03.02-tokens.md
│   │   ├── 01.03.03-syntax.md
│   │   ├── 01.03.04-resolved.md
│   │   ├── 01.03.05-expanded.md
│   │   ├── 01.03.06-elaborated.md
│   │   └── 01.03.07-core.md
│   ├── 01.04-compose/
│   │   ├── 01.04.01-pass.md
│   │   ├── 01.04.02-run.md
│   │   ├── 01.04.03-inspect.md
│   │   └── 01.04.04-build.md
│   ├── 01.05-labs/
│   │   └── 01.05.01-pipeline.md
│   └── 01.06-nagini/
│       └── 01.06.01-advance.md
├── 02-docs/         # design, spec and roadmap
│   ├── 02.01-design.md
│   ├── 02.02-spec.md
│   ├── 02.03-roadmap.md
│   └── 02.05-notes/
│       ├── 02.05.01-issue-task-patch.md
│       ├── 02.05.02-sober.md
│       ├── 02.05.03-mediating-project.md
│       ├── 02.05.04-obsidian-okf-cob-bridge.md
│       └── 02.05.05-repl-phrase-costs.md
├── 03-fpl/          # FPL's own tree
│   └── 03.01-features/ # the executable spec: what FPL must do (spec.md + examples)
├── .harness/quality/      # the bar every change must clear
├── .harness/scripts/      # gates and helpers (land, boundary, commit-lint)
├── .harness/tools/        # side tools; tokview shows how a tokenizer cuts FPL source
├── worktrees/    # yours to create: put your worktrees here to hack around
├── AGENTS.md     # start here if you are an agent (or want to work like one)
├── Makefile      # `make check` runs the one gate
└── flake.nix     # the dev shell: every entry point

References

  1. Annenkov, Capriotti, Kraus, Sattler, Two-level type theory and applications (MSCS, 2023), open copy; Kovács, Staged compilation with two-level type theory (ICFP 2022), open copy.
  2. Levy, Call-by-Push-Value (Springer, 2003), open copy (PhD thesis).
  3. Harper, Practical Foundations for Programming Languages (2nd ed., Cambridge, 2016), ch. 1, open copy (abbreviated edition).

Try it in the browser

Edit a block and press play. Runs in Pyodide with this site’s fpl-walker wheel.

For a full editor, shareable #c= links, and graded katas, open the Playground or Katas.

frames = "
".join(
    [
        ";;; ── frames ──",
        "1 | 1 2 3 +    ; 2 3 4",
        "1 2 3 +    ; [1‿2‿3 +]",
        "2 | 3 +    ; 5",
        "1 | 1 2 3 [-] swap-args    ; 1 2 3 - 1",
    ]
)
fpl.run.default.src(frames)
fpl.run.default.src("""
double : n -- n
    dup +

2 double
""")
fpl.run.default.src("""
4 double
""")