tricu

An interpreted language for exploring Tree Calculus
Log | Files | Refs | README | LICENSE

commit e35b1b1a16b71422e03f71aadfd524f99fdac32b
parent b4426ef0ccab4bb22add7c35ce5b2547994e28a4
Author: James Eversole <james@eversole.co>
Date:   Tue, 13 Oct 2026 20:12:40 -0500

Remove fixture-only patterns dependency from IO compiler closure

Unpublished source candidate. Nix fast gate, current-source IO dependency controls, and native server integration pass. Compiler pair, fixture relocation/publication and demo-site refresh follow at acceptance.

Diffstat:
Mbootstrap/compiler-source-map.v1 | 3+--
Mdocs/validation.md | 14++++++++++++++
Mflake.nix | 2+-
Mlib/io.tri | 4----
Atest/io_dependencies.py | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtest/unit.py | 10++++++++++
6 files changed, 78 insertions(+), 7 deletions(-)

diff --git a/bootstrap/compiler-source-map.v1 b/bootstrap/compiler-source-map.v1 @@ -2,7 +2,7 @@ arboricx.source-map.v1 native source_map source.map lib/source/map.tri prelude,io,source_object,source_module,source_resolve,source_build native source_unit source.unit lib/source/unit.tri prelude,parser,source_order,source_compile,source_program,source_resolve,source_ast,source_stable native prelude prelude lib/prelude.tri base,bytes,conversions -native io io lib/io.tri base,patterns +native io io lib/io.tri base native source_object source.object lib/source/object.tri prelude,io,native_math native source_module source.module lib/source/module.tri prelude,io,source_object,source_unit,source_resolve,source_lexer,parser native source_resolve source.resolve lib/source/resolve.tri prelude,parser,source_parser,source_ast,source_lexer,source_core,source_equations,source_pattern @@ -15,7 +15,6 @@ native source_ast source.ast lib/source/ast.tri prelude,source_lexer native base base lib/base.tri native_math native bytes bytes lib/bytes.tri base native conversions conversions lib/conversions.tri base,native_math -native patterns patterns lib/patterns.tri base native source_lexer source.lexer lib/source/lexer.tri prelude,parser,lexer,native_math native source_parser source.parser lib/source/parser.tri prelude,parser,source_lexer,source_ast,source_equations native source_core source.core lib/source/core.tri prelude diff --git a/docs/validation.md b/docs/validation.md @@ -41,6 +41,20 @@ The compiled-source smoke example is in It checks the native compiler-to-inspector path separately from independent wire fixtures; inspection itself never loads a compiler or executes an exported tree. +### Current-source IO dependencies + +```sh +nix build .# +PYTHONDONTWRITEBYTECODE=1 python3 test/io_dependencies.py result/bin/tricu +``` + +This opt-in probe compiles current `io`, `base`, and `native_math` sources with +only those modules present in a temporary workspace. It checks IO constructor +and conditional results and rejects an explicit import of the absent `patterns` +module. It does not rebuild or publish compiler/support fixtures. The fast host +policy tests separately check that the working compiler map is an exact closure +and that IO depends only on `base`. + ### Batch development loop Agree on a substantial related module group, its intended interface/behavior diff --git a/flake.nix b/flake.nix @@ -71,7 +71,7 @@ mkdir workspace ${pkgs.lib.concatMapStringsSep "\n" (name: "cp ${./lib}/${name}.tri workspace/${name}.tri") [ - "base" "prelude" "bytes" "conversions" "patterns" "io" + "base" "prelude" "bytes" "conversions" "io" "parser" "http" "socket" ]} cp ${./lib/math/native.tri} workspace/native_math.tri diff --git a/lib/io.tri b/lib/io.tri @@ -1,10 +1,6 @@ !import base * -!import patterns * !export * --- Temporary build dependency: patterns remains in the compiler fixture cohort. --- IO bodies do not use it; remove this edge when that cohort is split. - -- IO constructors for host-interpreted interaction trees. -- Free-monad style: Bind is the single sequencing mechanism. diff --git a/test/io_dependencies.py b/test/io_dependencies.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +"""Opt-in current-source IO dependency regression with the packaged compiler. + +No patterns source, ambient workspace, recovery frontend, or fixture publication. +Usage: python3 test/io_dependencies.py result/bin/tricu +""" +import argparse +from pathlib import Path +import shutil +import subprocess +import tempfile + +ROOT = Path(__file__).resolve().parent.parent + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('tricu', type=Path) + args = parser.parse_args() + host = str(args.tricu.resolve()) + with tempfile.TemporaryDirectory(prefix='tricu-io-dependencies-') as temporary: + workspace = Path(temporary) + for name, relative in [('base', 'lib/base.tri'), ('io', 'lib/io.tri'), + ('native_math', 'lib/math/native.tri')]: + shutil.copyfile(ROOT / relative, workspace / (name + '.tri')) + source = workspace / 'main.tri' + # Exercise actual IO definitions in a workspace lacking patterns. + source.write_text('''!import base * +!import io as IO +!export main +main = if (and? (equal? (IO.pure 7) (pair 0 7)) + (and? (equal? (IO.when true (IO.pure 9)) (IO.pure 9)) + (and? (equal? (IO.unless true (IO.pure 9)) (IO.pure t)) + (equal? (IO.putStr "hello") (pair 10 "hello"))))) 42 0 +''') + command = [host, 'eval', str(source), '--store', str(workspace / 'store'), + '--format', 'number', '+RTS', '-N1', '-M2048m', '-RTS'] + reply = subprocess.run(command, cwd=workspace, capture_output=True, + text=True, timeout=180) + assert reply.returncode == 0, (reply.stdout, reply.stderr) + assert reply.stdout.strip() == '42', (reply.stdout, reply.stderr) + # A used missing dependency must still fail: this is not a relaxed + # resolver or an ambient-source fallback. + source.write_text('!import patterns *\n!export main\nmain = otherwise t\n') + reply = subprocess.run(command, cwd=workspace, capture_output=True, + text=True, timeout=180) + assert reply.returncode != 0, (reply.stdout, reply.stderr) + print('Current IO compiles without patterns; constructor/conditional and missing-dependency controls pass.') + + +if __name__ == '__main__': + main() diff --git a/test/unit.py b/test/unit.py @@ -610,6 +610,16 @@ class SupportPublicationControls(unittest.TestCase): self.assertEqual(list(Path(directory).iterdir()), [marker]) +class CompilerDependencyTests(unittest.TestCase): + def test_current_map_is_exact_compiler_closure_without_patterns(self): + from bootstrap_generations import source_map + _, entries, required = source_map( + ROOT / 'bootstrap/compiler-source-map.v1', ROOT, 'source_map') + self.assertEqual(entries['io'][2], ['base']) + self.assertNotIn('patterns', entries) + self.assertEqual(set(entries), required) + + class FixtureSourceTests(unittest.TestCase): def setUp(self): from fixture_sources import digest