Skip to the content.

TAPL Concepts

This document explains the ideas behind TAPL and the design decisions that make it different from conventional approaches.

Core Idea 1: The Type-Checker Is Not Fixed

Core Idea 2: The Parser Is Not Fixed

Compilation Pipeline

For each .tapl source file, the compiler produces two Python files as described above:

  1. The evaluation layer (e.g., hello_world.py): executable runtime code.
  2. The type-checking layer (e.g., hello_world1.py): type-checker code. If it executes without error, the evaluation layer is guaranteed to be type-safe.

The pipeline:

Source (a.tapl)
    |
    v
[Chunker] -- Splits source into indentation-based chunks
    |
    v
[Language Directive] -- First chunk: "language {language-name}"
    |
    v
[Language Module] -- Loaded dynamically: tapl_language.{language-name}.get_language()
    |
    v
[Parser] -- Grammar rules produce a syntax tree
    |
    v
[LayerSeparator] -- Splits the syntax tree into two layers
    |
    v
[Backend (Python AST)] -- Each layer is converted to a Python AST
    |
    v
Output: a.py (layer 0), a1.py (layer 1)

Note: TAPL numbers layers from 0. Layer 0 is evaluation, layer 1 is type-checking. Since layer 0 is the primary output, the 0 is omitted by convention — so a.tapl produces a.py and a1.py.

Summary

TAPL is not a fixed language but a framework. It provides a compiler whose core is minimal and generic. The only fixed requirements are: (1) a language directive, (2) a language module that provides a grammar and predefined headers, and (3) syntax nodes that know how to split themselves across layers. Everything else — syntax, type rules, built-in types — is defined by the user. See the deep dive for details on these mechanisms.