Skip to content

Generation stages

Learning path · Step 2 of 4. This page explains the process; you will run it in the tutorial after Installation.

After How YIDL works, keep three moments separate: preparing a generator, generating a particular class, and using that class. The same prepared generator can receive different input rows for later generations.

1. Prepare the generator library

Author a .yidl concept describing input row shapes, reusable Python code pieces and rules for assembling them. compile_yidl_files reads those definitions; emit_concept_runtime_source emits a Python library. The tutorial calls that library runtime.py and executes it into a fresh Python namespace.

This library supplies ClassRow and FieldRow input types, new_builder() to collect their values, and build_Module to run its declared assembly. It is reusable generator machinery. It is not yet the Point application class.

2. Generate the particular class

The Python driver creates rows describing Point and its fields. A builder is the mutable container in which it adds them. freeze() turns that data into a read-only fact container, so later matching and code assembly can use a stable set of inputs. Data-producing operations, when a consumer needs them, run before this freeze.

build_Module(facts) selects contributions, binds field names such as x, and inserts the code pieces in their declared order. The result is an Astichi composable, the intermediate code object defined in the introduction. to_executable_ast() materializes it into a Python syntax tree. The driver saves readable source as model.py, then uses Python's compile(tree, ..., "exec") and exec to create the actual Point class in a namespace.

The tutorial's explicit source-template route can parse code while preparing resources, including lazy template compilation during generation. The final compile above compiles a Python tree; it does not reparse a handwritten method string. These stages are not a promise that all generation is parser-free.

3. Use the generated class

Ordinary Python code calls Point(3, 4). Its generated constructor assigns 3 to self.x and 4 to self.y. Further instance creation uses that existing class; it does not rerun the generator. Generation inputs specify names and behavior; constructor arguments supply this instance's values.

Next: Installation. You now have the stage overview needed for the tutorial. The remaining section is a troubleshooting reference; return to it when you need to locate a failure.

Locate an error by stage

Stage Input → output Typical failure
Parse/resolve Source map → compiled concepts Grammar, missing import/export, duplicate inherited name
Emit library Data definition and assembly metadata → Python runtime source Unsupported evaluator/source expression
Fill/produce facts Concrete records → mutable builder Wrong storage keyword/type, identity or cardinality conflict
Freeze/snapshot Builder → resolved data Operation/provider diagnostics before freeze
Match Input combinations → selected resource/contribution Missing property, ambiguous visible name, no match
Build/bind Selected instances → wired composable Duplicate instance, unresolved identifier, absent target
Materialize Composable → Python AST Mandatory hole, unsupported target context, backend failure
Execute AST and namespace → class → instances Missing capture, user callback exception, wrong behavior

For example, Assignment failing to target stores is a generation failure. Inspect its exception chain, selected input row, binding and destination. It is not a failure of Point(3, 4)'s later field assignment. The debugging guide supplies the inspection route.

MatcherGeneratedValue.to_generator() lazily compiles and caches an unbound code template. It does not cache a completed Point class or Point.x's runtime value. Protected generated decorator/helper paths are intended to avoid fresh ad hoc source parsing; that implementation rule differs from the explicit compiler/build boundary above. See caching and performance for those lifetimes and the limits of native-backend claims.

Continue the learning path with Installation.