Two substantial slices of gene/phen trait implementation just landed on submain. This shifts the needle significantly—contract checking and the capability for phen methods to actually get called at runtime are in the door. Previously, we only had the basic declarations and coherence working but now methods can type-check, Self can resolve per receiver, and calls execute. The submain branch now sits 15 commits ahead of main, holding the matrix at 321/0.
Contract Checking and Self Resolution (Slice 2)
Let’s zero in on commit fcd3193, which makes waves with 594 insertions across 23 files. The big takeaway is Pass 0 contract conformance. The collect_gene_phen_registry() function now actively validates every phen against its gene. Consider everything from arity to positional parameter types (post-Self substitution), return types, and even checks for both missing and extra methods. If there’s a mismatch, it doesn’t just shout—each one is a precise diagnostic identifying gene, method, position, and expected-vs-actual types. It’s pinpoint troubleshooting.
The decision to resolve Self at the concrete level before analysis was deliberate. Self in phen signatures and bodies changes to the actual receiver type within the AST thanks to substitute_self_type(). This function even navigates through intricate structures like Array, Handle, and Result wrappers. There was an alternative: treating Self as a floating type parameter. But honestly, it doesn’t cut it because types_compatible would unify any type param with anything. Sticking to the design docs, our path—Self is concrete, not a floating parametric.
How about ownership? It’s strict. There’s no room for unauthorized methods beyond the gene’s contract. And we’re talking multiple enforcement points: from Pass 0 checks to the phen_methods field on Analyzer triggered during per-file analysis, down to cross-gene-method name collisions caught by Pass 0. Every path specified is locked down, as envisioned by the design docs.
PhenDef’s semantic representation beefed up. SemanticStmt::PhenDef now contains Vec and Vec> instead of just plain method names. Methods undergo scrutiny in temporary scopes just like their impl-block cousins. Testing isn’t left out. We’ve packed ten new negative test fixtures plus a positive one to exercise every rejection path—think contract arity mismatches, missing and mismatched methods, and more. The positive test? t_gene_phen_contract_ok checks two phens of a single gene with Self in all type positions, acting as a ‘leak’ canary.
Phen Method Calls at Runtime (Slice 3)
Switch to commit cbb095e. This is the one where phen methods get street-legal, callable status. The insight here: phen methods log into semantic_impls keyed on (type_name, method_name) with receiver bindings—the same data architecture impl-block methods leverage. Therefore, call_semantic_method dispatches phen calls without any tweaks, reaffirming the design doc where phen methods function as full-fledged implementations identical to an impl block’s.
Surprisingly, forward-reference support hitchhiked into the build. The pre-registration pass in run_with_interpreter_setup() slots in phen methods right alongside impl methods, seamlessly supporting forward-call breakouts. Picture it—textual call sites preceding phen declarations still dispatch accurately.
Six new test fixtures? You bet. We cover the gamut from basic construct-call-use-return pathways to multi-type dispatch and forward references. We didn’t overlook parity for phen versus impl methods in mutation scenarios, or Self typed params and returns in execution.
Design Decisions Confirmed
These slices pivot around the established design doc rather than veering off in new directions:
-
Selfbeing concrete, not parametric, echoes decision 3. Thet_gene_phen_self_leak_rejectfixture underscores this—annotating an Enemy literal asSelfin a Player phen remains a type error. - Dispatch mechanics tightly reuse the impl-block pathways, not distinguished at runtime, needs no parallel path.
- Tightly enforced method ownership—as per decision 5—across all facets, rigorously tested.
Slice 2 carries a ‘rebuild’ hint in its commit note, indicating previous rewrites now shelved in favor of the cleaner final version.
What’s Next?
Half of our six slices are ready and on submain. We’re locked in with declarations, coherence, contract checking, Self resolution, core ownership rules, and interpreter dispatch. On deck are IR lowering for gene/phen constructs (vital for JIT backend handling), operator overloading, and the rollout of generics v3 type bounds, all part of the 0.3.4 roadmap.
Sure, submain is running 15 commits ahead of main, and the merge holds off while the 0.3.4 sprint drums on. Eventually, though, we need to consider the inherent risks of a ballooning batch size. Plus, issue #3 (explicit return paired with trailing expressions) remains open and is currently untouched with attention shifted toward the gene/phen sprint.
Follow the Cx language project:
- Website: cx-lang.com
- GitHub: github.com/COMMENTERTHE9/Cx_lang
- Dev.to: dev.to/commenterthe9
- Bluesky: thecomment.bsky.social
- Twitter/X: @commenterthe9
Originally published at https://cx-lang.com/blog/2026-07-21
답글 남기기