<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: COMMENTERTHE9</title>
    <description>The latest articles on DEV Community by COMMENTERTHE9 (@commenterthe9).</description>
    <link>https://dev.to/commenterthe9</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3823333%2F1af4f546-b6c0-4597-9d66-05fe6c618387.png</url>
      <title>DEV Community: COMMENTERTHE9</title>
      <link>https://dev.to/commenterthe9</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/commenterthe9"/>
    <language>en</language>
    <item>
      <title>Cx Dev Log — 2026-08-03</title>
      <dc:creator>COMMENTERTHE9</dc:creator>
      <pubDate>Wed, 12 Aug 2026 00:23:11 +0000</pubDate>
      <link>https://dev.to/commenterthe9/cx-dev-log-2026-08-03-k6c</link>
      <guid>https://dev.to/commenterthe9/cx-dev-log-2026-08-03-k6c</guid>
      <description>&lt;p&gt;Eliminating Overhead for Non-recursive Code in Cx: The Cycle-Only Call-Depth Guard&lt;/p&gt;

&lt;p&gt;Two host callbacks in every compiled call might sound minor, but they clocked in at about 11 ns per call in debug mode and around 14.5 ns debug-side. That's how our previous uniform call-depth guard in Cx worked—until today. It was effective but indiscriminate. Functions that couldn’t possibly recurse still took the performance hit. &lt;/p&gt;

&lt;p&gt;Today’s change makes that a thing of the past: non-recursive code won't face any overhead for stack-depth protection now.&lt;/p&gt;

&lt;h2&gt;
  
  
  How cycle-only guarding works
&lt;/h2&gt;

&lt;p&gt;So here's what's changed: a function that can't call itself through the call graph won't need a depth counter. Our solution starts by building a static call graph from the IR. This step is crucially done post-lowering to avoid a class of bugs tracked as C1-C4. Using Tarjan's strongly connected components algorithm, we've isolated functions that exist in call cycles. These are the only functions the guard touches.&lt;/p&gt;

&lt;p&gt;We've added about 130 lines of code to &lt;code&gt;host_boundary.rs&lt;/code&gt;. The core entry point—&lt;code&gt;functions_that_can_recurse()&lt;/code&gt;—trims the call graph to module-internal edges only. Here's the catch: host intrinsics like &lt;code&gt;cx_*&lt;/code&gt; end chains rather than completing cycles, so they're left out. A function gets the guard if it's part of an SCC larger than one or if it loops back to itself.&lt;/p&gt;

&lt;p&gt;An insightful touch: Tarjan's algorithm here runs iteratively, not recursively, ensuring our compiler doesn't eat its own stack while guarding against stack overflows in user code.&lt;/p&gt;

&lt;p&gt;Soundness? It’s all about the call graph’s completeness. The absence of indirect calls in Cx secures this. With &lt;code&gt;IrInst::Call.callee&lt;/code&gt; being a &lt;code&gt;String&lt;/code&gt;, the backend doesn't emit &lt;code&gt;call_indirect&lt;/code&gt;, and there's no function or callable type in the language—ensuring every possible call edge is accounted for.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance results
&lt;/h2&gt;

&lt;p&gt;Ran the numbers. Measured a few times, took the minimums: &lt;/p&gt;

&lt;p&gt;Recursive calls like &lt;code&gt;fib(30)&lt;/code&gt; (which stay guarded) showed negligible changes—141 ms to 139 ms in debug and 104 ms to 112 ms in release. Noise. The guard remains for recursives, so no surprise there.&lt;/p&gt;

&lt;p&gt;Non-recursive code is where it shines: 6 million calls shifted from 200 ms to 110 ms in debug and from 128 ms to 106 ms in release. The cycle-only guard puts us on par with unguarded calls—103 ms release, 110 ms debug. Non-recursive performance? Back to business as usual.&lt;/p&gt;

&lt;p&gt;For guarded functions, a call wears about 3.7 ns. The debug overhead that originally sparked this optim (11 ns/call) was nearly four times what ships.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inline counter deferred on evidence
&lt;/h2&gt;

&lt;p&gt;Yesterday, swapping the two host callbacks for a &lt;code&gt;declare_data&lt;/code&gt; load/add/store sequence was flagged as a follow-up optimization. Not anymore. Cycle-only cuts the guard cost from non-recursive routines, which covers most code. For recursive code, at about 3.7 ns/call in release, it doesn’t merit more fiddling. &lt;/p&gt;

&lt;p&gt;Consistently, we measure first, decide second, and document the reasoning afterward.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test coverage
&lt;/h2&gt;

&lt;p&gt;Our latest fixture, &lt;code&gt;t_mutual_recursion_guard&lt;/code&gt;, digs into scenarios beyond self-loops alone—A to B and B to A kind of calls need complete SCC analysis. We've got new tests on self-loops, length-2 and length-3 cycles, non-recursive calls dodging guards, and host intrinsics not being treated as graph edges. Boundary checks hold steady at 255/256 across recursion shapes and backends.&lt;/p&gt;

&lt;p&gt;The corpus climbed to 414 from 413 fixtures. Parity ticks up from 373/40/0 to 374/40/0. JIT tests climb to 426 from 425. Clippy stays perfect at 110/110.&lt;/p&gt;

&lt;h2&gt;
  
  
  State of the repo
&lt;/h2&gt;

&lt;p&gt;Submain sees an advance of 26 commits over main, up from 24. The merge is one step closer, yet not done. The gap's there, and growing.&lt;/p&gt;

&lt;p&gt;Merge that to the front, and two 0.3.3 milestones await: array-return lowering and expression receivers. They're on the horizon.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Follow the Cx language project:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Website: &lt;a href="https://cx-lang.com" rel="noopener noreferrer"&gt;cx-lang.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/COMMENTERTHE9/Cx_lang" rel="noopener noreferrer"&gt;github.com/COMMENTERTHE9/Cx_lang&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Dev.to: &lt;a href="https://dev.to/commenterthe9"&gt;dev.to/commenterthe9&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Bluesky: &lt;a href="https://bsky.app/profile/thecomment.bsky.social" rel="noopener noreferrer"&gt;thecomment.bsky.social&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Twitter/X: &lt;a href="https://x.com/commenterthe9" rel="noopener noreferrer"&gt;@commenterthe9&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://cx-lang.com/blog/2026-08-03" rel="noopener noreferrer"&gt;https://cx-lang.com/blog/2026-08-03&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cx</category>
      <category>programming</category>
    </item>
    <item>
      <title>Cx Dev Log — 2026-08-08</title>
      <dc:creator>COMMENTERTHE9</dc:creator>
      <pubDate>Sun, 09 Aug 2026 02:43:25 +0000</pubDate>
      <link>https://dev.to/commenterthe9/cx-dev-log-2026-08-08-f0o</link>
      <guid>https://dev.to/commenterthe9/cx-dev-log-2026-08-08-f0o</guid>
      <description>&lt;p&gt;Nothing landed today. The last real development commit was on August 2, and the repo has been quiet since then. Clean working tree, no staged changes, no branches moving. The test matrix on main holds at 380 pass, 0 fail, just like all week.&lt;/p&gt;

&lt;p&gt;This is day six of the pause. Worth documenting because the state of the codebase itself is interesting right now, even if nothing is actively changing.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's sitting on submain
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;submain&lt;/code&gt; branch is 26 commits ahead of main. That gap represents the bulk of what will become 0.3.3 when it merges. The core pieces:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generic-function monomorphization&lt;/strong&gt; is the headline feature. Commit &lt;code&gt;959a980&lt;/code&gt; introduced a worklist-driven instantiation system with a composition cap, living in a new &lt;code&gt;monomorphize.rs&lt;/code&gt; module. Each concrete type combination gets its own instantiation. This is the piece that makes generic functions actually compile down to specialized code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generic-struct lowering&lt;/strong&gt; (&lt;code&gt;5dcd548&lt;/code&gt;) follows from the same work: one memory layout per instantiation, so &lt;code&gt;Vec&amp;lt;i32&amp;gt;&lt;/code&gt; and &lt;code&gt;Vec&lt;/code&gt; get distinct layouts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gene-bound soundness fix&lt;/strong&gt; (&lt;code&gt;e105e56&lt;/code&gt;) closed a hole where field access through type-parameter bounds was allowed. A gene (Cx's trait-like construct) promises methods, not fields. Accessing a field through a gene bound was unsound because different concrete types behind that bound could have different field layouts. Now it's rejected at analysis time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Call-depth guards&lt;/strong&gt; shipped in two forms. The interpreter version (&lt;code&gt;878ba7c&lt;/code&gt;) turns recursion crashes into clean diagnostics. The JIT version (&lt;code&gt;664850d&lt;/code&gt;) does the same for compiled code. Then &lt;code&gt;ab62a6d&lt;/code&gt; (the last real commit, August 2) optimized both: it runs Tarjan's SCC algorithm on the static call graph at compile time and only instruments functions that participate in call cycles. Non-recursive code pays zero overhead for the guard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Const lowering&lt;/strong&gt; (&lt;code&gt;6c37339&lt;/code&gt;) and &lt;strong&gt;exit lowering&lt;/strong&gt; (&lt;code&gt;3d7a2cd&lt;/code&gt;) closed known-issues #12 and #11 respectively. Two long-standing gaps in the lowering pipeline, now handled.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enforcement-layer fixes&lt;/strong&gt; (&lt;code&gt;2de51aa&lt;/code&gt;, &lt;code&gt;fa95c12&lt;/code&gt;) tightened the analysis pass: const immutability is now enforced, and field/variant/loop-counter facts are checked at analysis time rather than relying on runtime behavior.&lt;/p&gt;

&lt;p&gt;Each of these features has paired documentation commits and README accuracy passes, so the merge to main should be straightforward. No conflicts are visible.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pause
&lt;/h2&gt;

&lt;p&gt;Six consecutive days with no development activity is unusual for this project. Nothing in the codebase itself suggests a technical blocker. The submain work is complete, tested, and documented. The merge to main has been the predicted next step since August 2, and it hasn't happened. The most likely explanation is that the pause is external to the codebase.&lt;/p&gt;

&lt;p&gt;Thirteen daily-log PRs (July 27 through today) have also accumulated without being merged. These are documentation-only and could be batch-merged whenever things pick back up.&lt;/p&gt;

&lt;h2&gt;
  
  
  When activity resumes
&lt;/h2&gt;

&lt;p&gt;The merge of submain to main is the clear first move. It brings 26 additive commits into the mainline and effectively constitutes 0.3.3 or the majority of it. After that, two 0.3.3 scope items remain: array-return lowering and expression receivers. Neither has been started yet.&lt;/p&gt;

&lt;p&gt;The matrix should stay green through the merge since submain's test additions are all additive. The interesting question is whether array-return lowering or expression receivers will introduce new complexity in the lowering pipeline, but that's a problem for a future log.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Follow the Cx language project:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Website: &lt;a href="https://cx-lang.com" rel="noopener noreferrer"&gt;cx-lang.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/COMMENTERTHE9/Cx_lang" rel="noopener noreferrer"&gt;github.com/COMMENTERTHE9/Cx_lang&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Dev.to: &lt;a href="https://dev.to/commenterthe9"&gt;dev.to/commenterthe9&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Bluesky: &lt;a href="https://bsky.app/profile/thecomment.bsky.social" rel="noopener noreferrer"&gt;thecomment.bsky.social&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Twitter/X: &lt;a href="https://x.com/commenterthe9" rel="noopener noreferrer"&gt;@commenterthe9&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://cx-lang.com/blog/2026-08-08" rel="noopener noreferrer"&gt;https://cx-lang.com/blog/2026-08-08&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cx</category>
      <category>programming</category>
    </item>
    <item>
      <title>Cx Dev Log — 2026-07-26</title>
      <dc:creator>COMMENTERTHE9</dc:creator>
      <pubDate>Sun, 02 Aug 2026 17:54:52 +0000</pubDate>
      <link>https://dev.to/commenterthe9/cx-dev-log-2026-07-26-45h</link>
      <guid>https://dev.to/commenterthe9/cx-dev-log-2026-07-26-45h</guid>
      <description>&lt;p&gt;No commits landed today. The test matrix sits at 380 pass, 0 fail on main, same as yesterday. v0.3.2 is stable and nothing moved. This is a status-check log rather than a progress report.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where things stand
&lt;/h2&gt;

&lt;p&gt;The 0.3.2 release shipped with gene/phen support and has been clean since it landed. The seven documentation site commits from July 24 are still branch-local on &lt;code&gt;site&lt;/code&gt;, unmerged. The eight example file rewrites (hello.cx, fibonacci.cx, fizzbuzz.cx, arrays_and_loops.cx, error_handling.cx, generics.cx, structs_and_methods.cx, tbool_uncertainty.cx) have been parked on the &lt;code&gt;daily-log-2026-07-04&lt;/code&gt; branch since late June. Those are tutorial-style expansions: block comments explaining language features, reorganized code for better demonstration, more diverse examples. About 280 insertions and 78 deletions across the eight files.&lt;/p&gt;

&lt;p&gt;Neither of these queued items moved today.&lt;/p&gt;

&lt;h2&gt;
  
  
  0.3.3 scope
&lt;/h2&gt;

&lt;p&gt;The next milestone is scoped but not started. Three items define it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Array-return lowering.&lt;/strong&gt; Same ABI-shape work pattern as the struct-return fix from 0.3.2. The approach is established; this extends it to array types.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generic-function lowering.&lt;/strong&gt; Bringing &lt;code&gt;T: GeneName&lt;/code&gt; bounded generics into the Cranelift JIT path. This is the piece that turns generics from a type-system feature into something that actually compiles and runs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Expression receivers.&lt;/strong&gt; Unlocking chained method-style calls and operator expressions on user types beyond the current single-expression restriction.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these have started. They carry forward as the primary engineering targets once active development resumes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pending cleanup
&lt;/h2&gt;

&lt;p&gt;Two items that could land independently of 0.3.3:&lt;/p&gt;

&lt;p&gt;The site branch has seven verified commits from a documentation sprint on July 24. Whether these merge to main or deploy independently is still undecided, but the content is ready.&lt;/p&gt;

&lt;p&gt;The example file rewrites have been sitting for roughly a month. They are a self-contained set of changes and could ship as a small cleanup PR without blocking or depending on anything else.&lt;/p&gt;

&lt;p&gt;The roadmap's "Last updated" date was corrected from 2026-07-04 to 2026-07-26 today. The content itself had already been reconciled by the 0.3.2 merge (PR #352), but the date line had not been bumped. No substantive roadmap changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;The same three predictions from yesterday carry forward unchanged: 0.3.3 implementation work, site branch merge or deployment, and a README feature audit to update sections that still describe pre-gene/phen capabilities. None were addressed today.&lt;/p&gt;

&lt;p&gt;When work resumes, array-return lowering is probably the lowest-friction starting point since the struct-return pattern from 0.3.2 provides a direct template.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Follow the Cx language project:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Website: &lt;a href="https://cx-lang.com" rel="noopener noreferrer"&gt;cx-lang.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/COMMENTERTHE9/Cx_lang" rel="noopener noreferrer"&gt;github.com/COMMENTERTHE9/Cx_lang&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Dev.to: &lt;a href="https://dev.to/commenterthe9"&gt;dev.to/commenterthe9&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Bluesky: &lt;a href="https://bsky.app/profile/thecomment.bsky.social" rel="noopener noreferrer"&gt;thecomment.bsky.social&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Twitter/X: &lt;a href="https://x.com/commenterthe9" rel="noopener noreferrer"&gt;@commenterthe9&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://cx-lang.com/blog/2026-07-26" rel="noopener noreferrer"&gt;https://cx-lang.com/blog/2026-07-26&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cx</category>
      <category>programming</category>
    </item>
    <item>
      <title>Cx Dev Log — 2026-07-29</title>
      <dc:creator>COMMENTERTHE9</dc:creator>
      <pubDate>Thu, 30 Jul 2026 00:12:29 +0000</pubDate>
      <link>https://dev.to/commenterthe9/cx-dev-log-2026-07-29-449f</link>
      <guid>https://dev.to/commenterthe9/cx-dev-log-2026-07-29-449f</guid>
      <description>&lt;p&gt;Submain sits 12 commits ahead of main, ready for a merge that's been "most likely next" in every daily log for days. If you want to catch a project in a moment of tension, there's no better time. No commits added recently, but in the quiet lies the pushback of a pending decision.&lt;/p&gt;

&lt;h2&gt;
  
  
  Current State
&lt;/h2&gt;

&lt;p&gt;Main holds strong at 380 passes and zero fails—a pristine test matrix. On its tail, submain checks in at 345 passes, zero fails, but with 51 skips across 396 test fixtures. Despite the skips, nothing's broken. As far as v0.3.2 goes, we're stable post-release after adding gene/phen support, operator overloading, and fixing the struct-return ABI. Not a single regression logged.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Submain Situation
&lt;/h2&gt;

&lt;p&gt;Let's talk about submain’s restless state, dangling those 12 commits. The work includes some key technical progress like exit and const lowering, a crucial parser guard fix, and a README accuracy pass. Moreover, there's a comprehensive audit pushing the C1-C4 enforcement layer to completion. We've got no visible merge conflicts. All that's missing is a green light for integration—tests are passing, the diff is clean, and yet, the commits remain stranded. Not a blocker in sight, just an unturned page in this project’s log.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open Issues
&lt;/h2&gt;

&lt;p&gt;Issues are stacking—#15 through #17—with tags since 07-27. These deal with constant-index out-of-bounds and division mishaps, runtime-checked string interpolation, and some diagnostic bugs. No hands have touched them so far. #16 might hold the path of least resistance, promising a cleaner follow-up by relocating validation to the analysis phase. Getting through these would clear some anxieties lying under the surface.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;The log keeps reiterating the same next steps, and they remain clear:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Merge submain into main.&lt;/strong&gt; It's straightforward: zero conflicts, twelve commits, all tests clear.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tackle Issues #15-#17.&lt;/strong&gt; With #16 being most self-contained, it might deserve a start. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scope for 0.3.3.&lt;/strong&gt; Eyeing array-return lowering, generic-function lowering, and expression receivers for the future.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All this while holding strong in a stable post-release calm. The merge of submain and the 0.3.3 scoping represent the next milestones. Making space for untangling those issues could set the stage for forward strides.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Follow the Cx language project:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Website: &lt;a href="https://cx-lang.com" rel="noopener noreferrer"&gt;cx-lang.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/COMMENTERTHE9/Cx_lang" rel="noopener noreferrer"&gt;github.com/COMMENTERTHE9/Cx_lang&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Dev.to: &lt;a href="https://dev.to/commenterthe9"&gt;dev.to/commenterthe9&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Bluesky: &lt;a href="https://bsky.app/profile/thecomment.bsky.social" rel="noopener noreferrer"&gt;thecomment.bsky.social&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Twitter/X: &lt;a href="https://x.com/commenterthe9" rel="noopener noreferrer"&gt;@commenterthe9&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://cx-lang.com/blog/2026-07-29" rel="noopener noreferrer"&gt;https://cx-lang.com/blog/2026-07-29&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cx</category>
      <category>programming</category>
    </item>
    <item>
      <title>Cx Dev Log — 2026-07-28</title>
      <dc:creator>COMMENTERTHE9</dc:creator>
      <pubDate>Wed, 29 Jul 2026 00:13:31 +0000</pubDate>
      <link>https://dev.to/commenterthe9/cx-dev-log-2026-07-28-1469</link>
      <guid>https://dev.to/commenterthe9/cx-dev-log-2026-07-28-1469</guid>
      <description>&lt;p&gt;The parity harness has a blind spot. When a test expects failure, any non-zero exit satisfies it, and the JIT's exit-127 trap counts as a clean SKIP. That means a whole class of bugs can hide in plain sight: cases where semantic analysis knows something is wrong, rejects it on the write side, but silently accepts it on the read side. The interpreter runs the wrong program. The JIT refuses it for unrelated reasons. The harness sees green.&lt;/p&gt;

&lt;p&gt;Today's work was a systematic audit of that pattern across &lt;code&gt;submain&lt;/code&gt;, producing two commits that close four of these holes and a locked design principle that codifies the fix as a rule.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four holes
&lt;/h2&gt;

&lt;p&gt;All four follow the same shape. Semantic analysis validates a fact when a value is constructed or assigned, but not when it is accessed or used. The result is that the interpreter invents behavior for programs the language should reject.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C1 (struct fields):&lt;/strong&gt; &lt;code&gt;resolve_field_access()&lt;/code&gt; had three copies of the same field lookup, each ending in &lt;code&gt;.unwrap_or(Unknown)&lt;/code&gt;. Writing &lt;code&gt;a.zzz = 5&lt;/code&gt; on a struct that only declares &lt;code&gt;x&lt;/code&gt; made the interpreter invent the field at runtime, exit cleanly, and print 5. The JIT refused it and counted a SKIP. Invisible to parity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C2 (loop-counter writes):&lt;/strong&gt; Immutability for loop counters was enforced by a flat scan of the loop body's top-level statements. One level of nesting defeated it. &lt;code&gt;for i in 0..3 { if i &amp;gt;= 0 { i = 99 } print(i) }&lt;/code&gt; produced &lt;code&gt;99 99 99&lt;/code&gt; on the interpreter and &lt;code&gt;99&lt;/code&gt; on the JIT. This was a live PARITY_FAIL with no fixture covering it. The fix introduces a &lt;code&gt;readonly_bindings: HashSet&lt;/code&gt; checked at the same two assignment choke points as &lt;code&gt;reject_const_assignment&lt;/code&gt;, keyed by binding ID so shadowing works correctly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C3 (enum variants):&lt;/strong&gt; &lt;code&gt;resolve_enum_variant()&lt;/code&gt; now provides a single resolver for value position, &lt;code&gt;when&lt;/code&gt; patterns, enum-variant arms, and &lt;code&gt;as v&lt;/code&gt; arms. Before this, &lt;code&gt;c: L = L::Blue&lt;/code&gt; on an enum declaring only &lt;code&gt;Red, Green&lt;/code&gt; ran to completion as a phantom variant.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C4 (index/dot on non-container):&lt;/strong&gt; The lvalue paths for "index target must be array" and dot access on a receiver with no fields already rejected bad programs. Only the rvalue paths fell through.&lt;/p&gt;

&lt;p&gt;The predicates are conservative. &lt;code&gt;Unknown&lt;/code&gt;, &lt;code&gt;TypeParam&lt;/code&gt;, &lt;code&gt;Container&lt;/code&gt;, and &lt;code&gt;Handle&lt;/code&gt; receivers pass through without rejection, so the new checks only fire when analysis actually knows the answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the harness missed these
&lt;/h2&gt;

&lt;p&gt;The structural issue is that &lt;code&gt;TestExpectation::Fail&lt;/code&gt; is satisfied by any non-zero exit code. When the JIT hits an unlowered or invalid construct, it traps with exit 127, which the harness scores as a clean SKIP. The interpreter, being more permissive at runtime, runs the program anyway and exits 0. Since the test only checks whether both backends agree on pass/fail, a case where the interpreter wrongly succeeds and the JIT wrongly refuses can register as "both handled it" rather than "both got it wrong in different ways."&lt;/p&gt;

&lt;p&gt;This is the same structural mistake that produced the f64 comparison bug, the enum equality bug, the width-check gaps, the ordering allowlist issue, and the const-immutability hole fixed last session. Six prior bugs, one pattern.&lt;/p&gt;

&lt;h2&gt;
  
  
  The locked design principle
&lt;/h2&gt;

&lt;p&gt;The second commit (&lt;code&gt;0ee7766&lt;/code&gt;) adds &lt;code&gt;docs/frontend/enforcement_layers.md&lt;/code&gt;, a 135-line document that locks the rule: if a fact is known to semantic analysis, semantic analysis rejects it. Any surviving backend check is defense-in-depth only.&lt;/p&gt;

&lt;p&gt;This is the project's second locked design principle, after the method-ownership principle in &lt;code&gt;gene_phen_design.md&lt;/code&gt;. Locked means it is not revisited per-instance. The document records the choke-point structure, explains why these bugs are invisible to the parity harness, and provides the keep-or-remove decision framework for redundant backend checks.&lt;/p&gt;

&lt;h2&gt;
  
  
  C2 bypass disposition
&lt;/h2&gt;

&lt;p&gt;The audit found that the interpreter has by-name write paths (&lt;code&gt;read()&lt;/code&gt;, &lt;code&gt;input()&lt;/code&gt;, multi-alias method write-back) that bypass &lt;code&gt;Stmt::Assign&lt;/code&gt; and could theoretically write to a loop counter. These are currently unreachable because the counter is typed &lt;code&gt;t64&lt;/code&gt; and the bypass paths carry &lt;code&gt;str&lt;/code&gt; or struct payloads, which means a type mismatch in a different layer stops them. The commit records this as a latent hole that becomes reachable if loop counters ever gain non-&lt;code&gt;t64&lt;/code&gt; types, with an explicit instruction that whoever makes that change must add the runtime guard in the same commit.&lt;/p&gt;

&lt;h2&gt;
  
  
  New known issues
&lt;/h2&gt;

&lt;p&gt;Three issues were filed, not fixed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;#15:&lt;/strong&gt; Constant-index out-of-bounds and literal-zero division are decidable at analysis time but currently left to runtime, where the two backends reject them differently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;#16:&lt;/strong&gt; String interpolation validation is runtime-checked, not compile-checked. The README claimed otherwise and was corrected.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;#17:&lt;/strong&gt; Diagnostics bugs: hardcoded position 0 in some error spans, and &lt;code&gt;%&lt;/code&gt; operations reporting &lt;code&gt;/&lt;/code&gt; in their error messages.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these block release, but #16 is called out in the known-issues doc as the cleanest follow-up target.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is next
&lt;/h2&gt;

&lt;p&gt;Submain is now 12 commits ahead of main with no merge conflicts visible. The merge has been predicted in every recent log and has not happened yet. Verification on submain stands at 396 fixtures, 345 PASS / 51 SKIP / 0 PARITY_FAIL. Main holds at 380/0.&lt;/p&gt;

&lt;p&gt;The 0.3.3 targets (expression receivers, array-return lowering, generic-function lowering) remain unstarted. The most likely near-term work is the submain merge followed by triage on the newly filed known issues.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Follow the Cx language project:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Website: &lt;a href="https://cx-lang.com" rel="noopener noreferrer"&gt;cx-lang.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/COMMENTERTHE9/Cx_lang" rel="noopener noreferrer"&gt;github.com/COMMENTERTHE9/Cx_lang&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Dev.to: &lt;a href="https://dev.to/commenterthe9"&gt;dev.to/commenterthe9&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Bluesky: &lt;a href="https://bsky.app/profile/thecomment.bsky.social" rel="noopener noreferrer"&gt;thecomment.bsky.social&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Twitter/X: &lt;a href="https://x.com/commenterthe9" rel="noopener noreferrer"&gt;@commenterthe9&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://cx-lang.com/blog/2026-07-28" rel="noopener noreferrer"&gt;https://cx-lang.com/blog/2026-07-28&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cx</category>
      <category>programming</category>
    </item>
    <item>
      <title>Cx Dev Log — 2026-07-24</title>
      <dc:creator>COMMENTERTHE9</dc:creator>
      <pubDate>Sat, 25 Jul 2026 00:13:28 +0000</pubDate>
      <link>https://dev.to/commenterthe9/cx-dev-log-2026-07-24-3j42</link>
      <guid>https://dev.to/commenterthe9/cx-dev-log-2026-07-24-3j42</guid>
      <description>&lt;p&gt;v0.3.2 is out. The gene/phen sprint that started six slices ago is done, merged to main via PR #352, and tagged. Submain and main sit at the same commit for the first time since this work began. The verification matrix went from 321 to 380 fixtures, all passing.&lt;/p&gt;

&lt;p&gt;The headline feature is operator overloading through an embedded prelude, which is the final architectural piece of the trait system. But the release is really the sum of all six slices: gene declarations, phen implementations, generic bounds, method dispatch, struct-return ABI fixes, and now operator contracts.&lt;/p&gt;

&lt;h2&gt;
  
  
  The embedded prelude
&lt;/h2&gt;

&lt;p&gt;The capstone commit (&lt;code&gt;e38024e&lt;/code&gt;, 526 insertions across 24 files) introduced &lt;code&gt;src/prelude.cx&lt;/code&gt;, a 52-line Cx source file that defines eight operator gene contracts: &lt;code&gt;Add&lt;/code&gt;, &lt;code&gt;Sub&lt;/code&gt;, &lt;code&gt;Mul&lt;/code&gt;, &lt;code&gt;Div&lt;/code&gt;, &lt;code&gt;Mod&lt;/code&gt;, &lt;code&gt;Neg&lt;/code&gt;, &lt;code&gt;Eq&lt;/code&gt;, and &lt;code&gt;Ord&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This file is compiled into &lt;code&gt;cx.exe&lt;/code&gt; via &lt;code&gt;include_str!&lt;/code&gt; and injected as the first source unit of every program, before the root file and all imports. It goes through the ordinary lexer-parser-semantic pipeline. There is no filesystem probing, no fallback path, no special syntax. The embedded text is the only runtime path.&lt;/p&gt;

&lt;p&gt;This was a deliberate architectural decision (decision 6 from the gene/phen design doc). The prelude is the permanent home for operator contracts, not a stopgap while something else gets built. There is no hardcoded operator-overloading syntax and no parallel system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Operator-gene dispatch
&lt;/h2&gt;

&lt;p&gt;The new &lt;code&gt;try_operator_gene_dispatch()&lt;/code&gt; method in &lt;code&gt;semantic.rs&lt;/code&gt; (~240 insertions) handles all binary operators (&lt;code&gt;+&lt;/code&gt;, &lt;code&gt;-&lt;/code&gt;, &lt;code&gt;*&lt;/code&gt;, &lt;code&gt;/&lt;/code&gt;, &lt;code&gt;%&lt;/code&gt;, &lt;code&gt;==&lt;/code&gt;, &lt;code&gt;!=&lt;/code&gt;, &lt;code&gt;&amp;lt;&lt;/code&gt;, &lt;code&gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;=&lt;/code&gt;, &lt;code&gt;&amp;gt;=&lt;/code&gt;) and unary &lt;code&gt;-&lt;/code&gt;. When the left operand is a user struct that has a phen for the corresponding gene, the operator gets rewritten to the same &lt;code&gt;MethodCall&lt;/code&gt; node that a hand-written &lt;code&gt;a.add(b)&lt;/code&gt; call would produce. This reuses the dispatch machinery from slices 3 and 5 with no new mechanism added.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;!=&lt;/code&gt; is derived as the logical NOT of &lt;code&gt;eq()&lt;/code&gt;, matching the Eq gene contract. Types that don't have a matching phen fall through to the existing built-in numeric paths unchanged.&lt;/p&gt;

&lt;p&gt;There is one interim restriction: operator dispatch requires a named variable as the left operand. Expression receivers like &lt;code&gt;(v1 + v2) + v3&lt;/code&gt; produce a clean error rather than silently misbehaving. This is a known gap, not a design position. It lifts when method receivers become expressions, which is scoped for 0.3.3.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prelude injection and collision detection
&lt;/h2&gt;

&lt;p&gt;The resolver now injects the prelude as module ID 0, before all other source units. Gene duplicate detection gained source-location tracking, so if a user redeclares a prelude gene, they get an error that names &lt;code&gt;&amp;lt;prelude&amp;gt;:LINE&lt;/code&gt; using the same collision machinery every other declaration kind already uses.&lt;/p&gt;

&lt;p&gt;Eight new test fixtures cover the operator dispatch and prelude injection: arithmetic dispatch on user structs, unary neg and equality via genes, all four ordering operators, the expression-receiver restriction error, rejection when a struct lacks an &lt;code&gt;Add&lt;/code&gt; phen, prelude behavior with multi-file imports, and collision between user-defined and prelude genes. Four existing duplicate-detection fixtures were updated for the new source-location diagnostics.&lt;/p&gt;

&lt;h2&gt;
  
  
  The merge and the release
&lt;/h2&gt;

&lt;p&gt;The full merge through PR #352 brought the entire gene/phen sprint into main: 133 files changed, 3301 insertions, 120 deletions. That covers all six slices of gene/phen implementation, the struct-return ABI fix, scope-variable hardening, and audit fixtures.&lt;/p&gt;

&lt;p&gt;The roadmap was reconciled in a separate commit (&lt;code&gt;71b5af4&lt;/code&gt;). The version sequence now reflects what actually shipped: 0.3.1 included pattern matching, and 0.3.2 contains gene/phen, operator overloading, generic bounds, the struct-return fix, and audit hardening. README status was updated to 0.3.2 with current verification figures: 245 unit tests, 420 with JIT, 380 fixtures, 319 JIT PASS / 61 SKIP / 0 PARITY_FAIL.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bootstrap intrinsics
&lt;/h2&gt;

&lt;p&gt;One detail worth noting: the built-in numeric paths in semantic analysis (addition, subtraction, comparison for primitives) now explicitly conform to the prelude gene contracts and are marked as bootstrap intrinsics. They are designed for removal. The known gap is that primitives do not yet satisfy &lt;code&gt;T: Add&lt;/code&gt;-style generic bounds, since bound checks consult the phen registry and intrinsics are not registry entries. That will matter when generic functions lower through the JIT.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is next
&lt;/h2&gt;

&lt;p&gt;0.3.3 is scoped with three items:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Expression receivers&lt;/strong&gt; for method and operator dispatch. This is the most visible gap in the freshly shipped system, and it unlocks chained operator expressions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Array-return lowering&lt;/strong&gt;, the same dangling-frame ABI shape as the struct-return bug that was fixed in this sprint. The slot convention needs array-layout awareness.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generic-function lowering&lt;/strong&gt; through the JIT. Generic functions with type bounds are semantically complete but not yet lowered.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There is also a pending README content audit. The feature sections still describe 0.2.0-era capability and need a documentation pass covering gene/phen, Handle, pattern matching, and operator overloading.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Follow the Cx language project:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Website: &lt;a href="https://cx-lang.com" rel="noopener noreferrer"&gt;cx-lang.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/COMMENTERTHE9/Cx_lang" rel="noopener noreferrer"&gt;github.com/COMMENTERTHE9/Cx_lang&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Dev.to: &lt;a href="https://dev.to/commenterthe9"&gt;dev.to/commenterthe9&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Bluesky: &lt;a href="https://bsky.app/profile/thecomment.bsky.social" rel="noopener noreferrer"&gt;thecomment.bsky.social&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Twitter/X: &lt;a href="https://x.com/commenterthe9" rel="noopener noreferrer"&gt;@commenterthe9&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://cx-lang.com/blog/2026-07-24" rel="noopener noreferrer"&gt;https://cx-lang.com/blog/2026-07-24&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cx</category>
      <category>programming</category>
    </item>
    <item>
      <title>Cx Dev Log — 2026-07-21</title>
      <dc:creator>COMMENTERTHE9</dc:creator>
      <pubDate>Wed, 22 Jul 2026 00:12:06 +0000</pubDate>
      <link>https://dev.to/commenterthe9/cx-dev-log-2026-07-21-16oj</link>
      <guid>https://dev.to/commenterthe9/cx-dev-log-2026-07-21-16oj</guid>
      <description>&lt;p&gt;Two substantial slices of gene/phen trait implementation just landed on &lt;code&gt;submain&lt;/code&gt;. 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, &lt;code&gt;Self&lt;/code&gt; can resolve per receiver, and calls execute. The &lt;code&gt;submain&lt;/code&gt; branch now sits 15 commits ahead of &lt;code&gt;main&lt;/code&gt;, holding the matrix at 321/0.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contract Checking and &lt;code&gt;Self&lt;/code&gt; Resolution (Slice 2)
&lt;/h2&gt;

&lt;p&gt;Let's zero in on commit &lt;code&gt;fcd3193&lt;/code&gt;, which makes waves with 594 insertions across 23 files. The big takeaway is Pass 0 contract conformance. The &lt;code&gt;collect_gene_phen_registry()&lt;/code&gt; function now actively validates every phen against its gene. Consider everything from arity to positional parameter types (post-&lt;code&gt;Self&lt;/code&gt; 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.&lt;/p&gt;

&lt;p&gt;The decision to resolve &lt;code&gt;Self&lt;/code&gt; at the concrete level before analysis was deliberate. &lt;code&gt;Self&lt;/code&gt; in phen signatures and bodies changes to the actual receiver type within the AST thanks to &lt;code&gt;substitute_self_type()&lt;/code&gt;. This function even navigates through intricate structures like &lt;code&gt;Array&lt;/code&gt;, &lt;code&gt;Handle&lt;/code&gt;, and &lt;code&gt;Result&lt;/code&gt; wrappers. There was an alternative: treating &lt;code&gt;Self&lt;/code&gt; as a floating type parameter. But honestly, it doesn't cut it because &lt;code&gt;types_compatible&lt;/code&gt; would unify any type param with anything. Sticking to the design docs, our path—&lt;code&gt;Self&lt;/code&gt; is concrete, not a floating parametric. &lt;/p&gt;

&lt;p&gt;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 &lt;code&gt;phen_methods&lt;/code&gt; field on &lt;code&gt;Analyzer&lt;/code&gt; 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.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;PhenDef&lt;/code&gt;’s semantic representation beefed up. &lt;code&gt;SemanticStmt::PhenDef&lt;/code&gt; now contains &lt;code&gt;Vec&lt;/code&gt; and &lt;code&gt;Vec&amp;gt;&lt;/code&gt; 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? &lt;code&gt;t_gene_phen_contract_ok&lt;/code&gt; checks two phens of a single gene with &lt;code&gt;Self&lt;/code&gt; in all type positions, acting as a 'leak' canary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Phen Method Calls at Runtime (Slice 3)
&lt;/h2&gt;

&lt;p&gt;Switch to commit &lt;code&gt;cbb095e&lt;/code&gt;. This is the one where phen methods get street-legal, callable status. The insight here: phen methods log into &lt;code&gt;semantic_impls&lt;/code&gt; keyed on &lt;code&gt;(type_name, method_name)&lt;/code&gt; with receiver bindings—the same data architecture impl-block methods leverage. Therefore, &lt;code&gt;call_semantic_method&lt;/code&gt; dispatches phen calls without any tweaks, reaffirming the design doc where phen methods function as full-fledged implementations identical to an impl block's.&lt;/p&gt;

&lt;p&gt;Surprisingly, forward-reference support hitchhiked into the build. The pre-registration pass in &lt;code&gt;run_with_interpreter_setup()&lt;/code&gt; slots in phen methods right alongside impl methods, seamlessly supporting forward-call breakouts. Picture it—textual call sites preceding phen declarations still dispatch accurately.&lt;/p&gt;

&lt;p&gt;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 &lt;code&gt;Self&lt;/code&gt; typed params and returns in execution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design Decisions Confirmed
&lt;/h2&gt;

&lt;p&gt;These slices pivot around the established design doc rather than veering off in new directions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Self&lt;/code&gt; being concrete, not parametric, echoes decision 3. The &lt;code&gt;t_gene_phen_self_leak_reject&lt;/code&gt; fixture underscores this—annotating an Enemy literal as &lt;code&gt;Self&lt;/code&gt; in a Player phen remains a type error.&lt;/li&gt;
&lt;li&gt;Dispatch mechanics tightly reuse the impl-block pathways, not distinguished at runtime, needs no parallel path.&lt;/li&gt;
&lt;li&gt;Tightly enforced method ownership—as per decision 5—across all facets, rigorously tested.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Slice 2 carries a 'rebuild' hint in its commit note, indicating previous rewrites now shelved in favor of the cleaner final version.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;Half of our six slices are ready and on submain. We're locked in with declarations, coherence, contract checking, &lt;code&gt;Self&lt;/code&gt; 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.&lt;/p&gt;

&lt;p&gt;Sure, &lt;code&gt;submain&lt;/code&gt; is running 15 commits ahead of &lt;code&gt;main&lt;/code&gt;, 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.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Follow the Cx language project:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Website: &lt;a href="https://cx-lang.com" rel="noopener noreferrer"&gt;cx-lang.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/COMMENTERTHE9/Cx_lang" rel="noopener noreferrer"&gt;github.com/COMMENTERTHE9/Cx_lang&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Dev.to: &lt;a href="https://dev.to/commenterthe9"&gt;dev.to/commenterthe9&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Bluesky: &lt;a href="https://bsky.app/profile/thecomment.bsky.social" rel="noopener noreferrer"&gt;thecomment.bsky.social&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Twitter/X: &lt;a href="https://x.com/commenterthe9" rel="noopener noreferrer"&gt;@commenterthe9&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://cx-lang.com/blog/2026-07-21" rel="noopener noreferrer"&gt;https://cx-lang.com/blog/2026-07-21&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cx</category>
      <category>programming</category>
    </item>
    <item>
      <title>Cx Dev Log — 2026-07-18</title>
      <dc:creator>COMMENTERTHE9</dc:creator>
      <pubDate>Sun, 19 Jul 2026 00:11:59 +0000</pubDate>
      <link>https://dev.to/commenterthe9/cx-dev-log-2026-07-18-1fj3</link>
      <guid>https://dev.to/commenterthe9/cx-dev-log-2026-07-18-1fj3</guid>
      <description>&lt;p&gt;Cx Dev Log — 2026-07-18: A Moment of Pause Before the Next Push&lt;/p&gt;

&lt;p&gt;The Cx codebase has taken a breather. It's been quiet for five days, a rarity in the fast-paced world of solo-developed languages. Main is stable at commit &lt;code&gt;3430e4e&lt;/code&gt;, marked by the last 0.3.1 release tag from July 9. Submain's clocked at &lt;code&gt;3b7b7f8&lt;/code&gt; with the freshly finalized gene/phen design as of July 14. Even the automated matrix stands firm: 321 tests passing, zero failing. But quiet isn't inactivity—it's anticipation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the Project Sits
&lt;/h2&gt;

&lt;p&gt;The significant chunk of work that wrapped on July 14 was hefty: the gene/phen design's v1.1 spec. It doesn't just wrap dispatch strategies; we're talking about cleaner Ord mappings, robust Self resolutions, and handling phen lookups with cross-module coherence. Those are down in a 13-commit series on submain, the product of a thorough hammering out of all six outstanding design questions. But it wasn't just theoretical.&lt;/p&gt;

&lt;p&gt;These commits include necessary parser and semantic adjustments, say, coming out of our recent audit. Scoping issues are in check, width-range enforcement leveled up, and we've put any unnecessary comparison errors on Bool/Enum to bed. There's a crucial runtime patch too—no more enum &lt;code&gt;==&lt;/code&gt;/&lt;code&gt;!=&lt;/code&gt; crashes blowing up the interpreter. We've also streamlined CI through direct &lt;code&gt;run_matrix.sh&lt;/code&gt; runs.&lt;/p&gt;

&lt;p&gt;These advances sit 13 steps ahead of main without a single technical barricade to rushing them into action. This delay in merging? It's purely deliberate, not dictated by troublesome conflicts or failing tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Queued Once Work Resumes
&lt;/h2&gt;

&lt;p&gt;So, what's cooking when the fingers start flying across keyboards again? Here's what's lined up:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Merge submain to main.&lt;/strong&gt; We've got 13 commits begging for integration. Expect this to be painless, almost ceremonial, since main's been untouched.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;0.3.4: Gene/Phen Implementation.&lt;/strong&gt; The design spec isn’t a riddle wrapped in an enigma—it's a clear blueprint. It's got everything: pass ordering, canonical key formats, robust collision detection, diagnostic frameworks, and essential test fixtures. The specs make the engineering path obvious and actionable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Known Issue #3.&lt;/strong&gt; It’s another loose end: explicit return with trailing expressions, tangled in the same territory where #2 was resolved. It's still up for grabs.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  On Pauses
&lt;/h2&gt;

&lt;p&gt;A five-day hiatus post-design isn’t unusual, especially for a language crafted solo. Ensuring the architecture's rock-solid—dispatch mechanics, coherence rules, semantics—takes its toll. Patterns being matched in 0.3.2 landed but haven’t seen a tagged release. We’ve got routine release housekeeping next to the real implementation grind.&lt;/p&gt;

&lt;p&gt;Call it the calm before the storm. The project isn't at sea without a sail—the framework's in place, and the green-lit test matrix primes us for action. It's just about recharging before the next coding sprint.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Follow the Cx language project:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Website: &lt;a href="https://cx-lang.com" rel="noopener noreferrer"&gt;cx-lang.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/COMMENTERTHE9/Cx_lang" rel="noopener noreferrer"&gt;github.com/COMMENTERTHE9/Cx_lang&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Dev.to: &lt;a href="https://dev.to/commenterthe9"&gt;dev.to/commenterthe9&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Bluesky: &lt;a href="https://bsky.app/profile/thecomment.bsky.social" rel="noopener noreferrer"&gt;thecomment.bsky.social&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Twitter/X: &lt;a href="https://x.com/commenterthe9" rel="noopener noreferrer"&gt;@commenterthe9&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://cx-lang.com/blog/2026-07-18" rel="noopener noreferrer"&gt;https://cx-lang.com/blog/2026-07-18&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cx</category>
      <category>programming</category>
    </item>
    <item>
      <title>Cx Dev Log — 2026-07-11</title>
      <dc:creator>COMMENTERTHE9</dc:creator>
      <pubDate>Sun, 12 Jul 2026 02:42:51 +0000</pubDate>
      <link>https://dev.to/commenterthe9/cx-dev-log-2026-07-11-1jn7</link>
      <guid>https://dev.to/commenterthe9/cx-dev-log-2026-07-11-1jn7</guid>
      <description>&lt;p&gt;A parser with no changes to its lowering layer fixed a JIT failure. Sounds improbable? That's what we tackled recently in Cx development. Throughout our session, four issues were closed in two subsystems, focusing on correctness and stability, on the submain branch. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Trailing-Builtin Parser Fix
&lt;/h2&gt;

&lt;p&gt;Consider a &lt;code&gt;print(x)&lt;/code&gt; as the final line of a function without a trailing semicolon. Previously, this line would be promoted to a &lt;code&gt;ret_expr&lt;/code&gt; by our parser's &lt;code&gt;func_body&lt;/code&gt; combinator — resulting in semantic artifacts that disrupted the lowering system. This oversight led to an unsettling "unresolved semantic artifact reached lowering" error.&lt;/p&gt;

&lt;p&gt;The solution was a simple yet effective new predicate, &lt;code&gt;is_statement_level_builtin_call()&lt;/code&gt;, in &lt;code&gt;src/frontend/parser.rs&lt;/code&gt;. It specifically recognizes trailing calls like &lt;code&gt;print&lt;/code&gt;, &lt;code&gt;println&lt;/code&gt;, &lt;code&gt;printn&lt;/code&gt;, &lt;code&gt;assert&lt;/code&gt;, and &lt;code&gt;assert_eq&lt;/code&gt;, and ensures they're treated as standard statements rather than being prematurely promoted. This fix bypasses unnecessary promotions and channels the calls through the existing &lt;code&gt;lower_stmt&lt;/code&gt; dispatcher. Interestingly, this was purely a parser misclassification error, not a failure of the lowering layer.&lt;/p&gt;

&lt;p&gt;Here's what changed: 5 JIT-SKIP fixtures are now back in action: &lt;code&gt;t29_forward_decl&lt;/code&gt;, &lt;code&gt;t31_strref_forward_combined&lt;/code&gt;, &lt;code&gt;t67_macro_outer_test&lt;/code&gt;, &lt;code&gt;t68_macro_outer_deprecated&lt;/code&gt;, and &lt;code&gt;t_array_elem_arg_in_range&lt;/code&gt;. Initially, the prediction was 8, but two fixtures were disqualified earlier in macro processing, and &lt;code&gt;t50_nested_func_no_leak&lt;/code&gt; remains on hold. JIT parity advanced from 261/60/0 to 267/55/0.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scope Boundaries for Control-Flow Bodies
&lt;/h2&gt;

&lt;p&gt;Variables declared within &lt;code&gt;if&lt;/code&gt;, &lt;code&gt;else&lt;/code&gt;, &lt;code&gt;else-if&lt;/code&gt;, &lt;code&gt;while&lt;/code&gt;, &lt;code&gt;loop&lt;/code&gt;, and &lt;code&gt;while-in&lt;/code&gt; bodies were unintentionally bleeding out into the surrounding scope. This problem boiled down to missing &lt;code&gt;push_scope()&lt;/code&gt; and &lt;code&gt;pop_scope()&lt;/code&gt; calls in &lt;code&gt;src/frontend/semantic.rs&lt;/code&gt;. By adding these, we ensured proper scope boundaries.&lt;/p&gt;

&lt;p&gt;Four new test fixtures (&lt;code&gt;t179_if_scope&lt;/code&gt;, &lt;code&gt;t180_while_scope&lt;/code&gt;, &lt;code&gt;t181_loop_scope&lt;/code&gt;, &lt;code&gt;t182_whilein_scope&lt;/code&gt;) now check that names declared within those bodies aren't accessible outside of them. Previously, incorrect programs could silently pass by misusing variables beyond their intended scope.&lt;/p&gt;

&lt;h2&gt;
  
  
  Width-Range Enforcement at Missed Sites
&lt;/h2&gt;

&lt;p&gt;In &lt;code&gt;check_semantic_num_fits()&lt;/code&gt;, our system ensures numeric values are within target type ranges. However, three assignment contexts were slipping through without these checks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Variable reassignment (e.g., &lt;code&gt;x = 300&lt;/code&gt; where &lt;code&gt;x: u8&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Array-index assignment (e.g., &lt;code&gt;arr[0] = 300&lt;/code&gt; where &lt;code&gt;arr: [u8; 4]&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Method-call arguments (e.g., &lt;code&gt;obj.method(300)&lt;/code&gt; expecting a &lt;code&gt;u8&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We addressed each of these scenarios. Six new test fixtures now verify both in-range and out-of-range values across these contexts. It's all about defensive correctness — repairs that should've been in the type system from the start.&lt;/p&gt;

&lt;h2&gt;
  
  
  Direction
&lt;/h2&gt;

&lt;p&gt;We've consciously shifted focus from the challenging tasks ahead (like known-issues #5 I128 ABI sizing and #4 per-enum tag-to-name tables) toward more tractable correctness fixes. The semantic audit findings and parser adjustments made were straightforward but necessary. This involved four commits, 11 new test fixtures, and the closure of two known issues and two audit findings.&lt;/p&gt;

&lt;p&gt;Currently, everything remains on the submain, with main topping at v0.3.1.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;Submain leads the main by four commits, all with clean fixture runs, setting the stage for a potential merge to main and possibly v0.3.2 in the future. Known-issue #3 (explicit return + trailing expression) becomes the natural follow-up, sitting right within the modified parser framework. Major items, like the I128 ABI and enum tag-to-name tables, will stay on the backburner for now, while we concentrate on feasible victories.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Follow the Cx language project:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Website: &lt;a href="https://cx-lang.com" rel="noopener noreferrer"&gt;cx-lang.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/COMMENTERTHE9/Cx_lang" rel="noopener noreferrer"&gt;github.com/COMMENTERTHE9/Cx_lang&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Dev.to: &lt;a href="https://dev.to/commenterthe9"&gt;dev.to/commenterthe9&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Bluesky: &lt;a href="https://bsky.app/profile/thecomment.bsky.social" rel="noopener noreferrer"&gt;thecomment.bsky.social&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Twitter/X: &lt;a href="https://x.com/commenterthe9" rel="noopener noreferrer"&gt;@commenterthe9&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://cx-lang.com/blog/2026-07-11" rel="noopener noreferrer"&gt;https://cx-lang.com/blog/2026-07-11&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cx</category>
      <category>programming</category>
    </item>
    <item>
      <title>Cx Dev Log — 2026-07-10</title>
      <dc:creator>COMMENTERTHE9</dc:creator>
      <pubDate>Sat, 11 Jul 2026 01:14:03 +0000</pubDate>
      <link>https://dev.to/commenterthe9/cx-dev-log-2026-07-10-2ch3</link>
      <guid>https://dev.to/commenterthe9/cx-dev-log-2026-07-10-2ch3</guid>
      <description>&lt;p&gt;The v0.3.1 release is finally here, capping off a series of daily logs predicting its arrival. The integration on July 9 brought us more than what was initially scoped, folding in Handle core, pattern matching enhancements, an f64 comparison fix, and a new known-issues tracker. It's been a significant addition, pushing our test matrix from 292 to 321.&lt;/p&gt;

&lt;h2&gt;
  
  
  What shipped
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Handle core (D2.5a/b/c).&lt;/strong&gt; We've introduced the &lt;code&gt;Handle&lt;/code&gt; construct, adding read/val and drop functionality for scalar payloads. This uses a packed i64 representation—slot and generation fields, anchored by a host-side registry. Empirical tests confirm no aliasing on double-drop and generational safety. Nine new test fixtures ensure coverage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pattern matching first slices.&lt;/strong&gt; Originally destined for 0.3.2, enhancements like &lt;code&gt;as v&lt;/code&gt; named bindings and guard clauses in &lt;code&gt;when&lt;/code&gt; enum arms have arrived early. Guard clauses repurpose existing mechanics, avoiding new control-flow constructs. The additions were well-received, with twenty new fixtures targeting positive behavior and leak rejection.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interpreter f64 comparison fix.&lt;/strong&gt; This fix addressed missing &lt;code&gt;Value::Float&lt;/code&gt; match arms for comparison operators like &lt;code&gt;&amp;lt;&lt;/code&gt;, &lt;code&gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;=&lt;/code&gt;, &lt;code&gt;&amp;gt;=&lt;/code&gt; in &lt;code&gt;src/runtime/ops.rs&lt;/code&gt;. Interestingly, the JIT got it right from the start, reversing an often-seen pattern where the interpreter leads. Five new fixtures ensure correctness.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Known-issues tracker.&lt;/strong&gt; We've established a tracker in &lt;code&gt;docs/known_issues.md&lt;/code&gt;, cataloging ongoing divergences between the interpreter and JIT. The f64 issue is resolved, but others like bare builtin in trailing positions and print issues remain.&lt;/p&gt;

&lt;h2&gt;
  
  
  The I128 host-boundary finding
&lt;/h2&gt;

&lt;p&gt;The standout technical takeaway? A failed fix on our JIT system. Trying to pass a raw &lt;code&gt;i128&lt;/code&gt; by value proved unsuccessful—it segfaulted. This boundary scenario, untested before, requires a pass-by-pointer strategy instead. This insight, although not immediately operational, is crucial for any wide scalar work moving forward.&lt;/p&gt;

&lt;p&gt;Attempting to resolve the &lt;code&gt;print(enum)&lt;/code&gt; issue revealed another layer of complexity. It involves setting up tag-to-name tables rather than simple dispatch-arm fixes. This pivot in approach, while unplanned, is necessary for the print parity objective.&lt;/p&gt;

&lt;h2&gt;
  
  
  State of the project
&lt;/h2&gt;

&lt;p&gt;Following the merge, both submain and main branches are aligned, leaving our working tree clean. 321 tests now pass without failure—a testimony to the release's impact, bolstered by 29 new fixtures.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is next
&lt;/h2&gt;

&lt;p&gt;Addressing the I128 host-boundary ABI snag is next up, with a sizing pass pinned as our most pressing task. The subsequent task involves implementing the tag-to-name string tables for full JIT print parity. Issues around expression handling (#2 and #3) remain unsized and open, awaiting attention.&lt;/p&gt;

&lt;p&gt;For the feature roadmap, the gene and phen design pass is queued for release 0.3.2. However, the timeline is uncertain as multiple pull requests linger, awaiting review.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Follow the Cx language project:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Website: &lt;a href="https://cx-lang.com" rel="noopener noreferrer"&gt;cx-lang.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/COMMENTERTHE9/Cx_lang" rel="noopener noreferrer"&gt;github.com/COMMENTERTHE9/Cx_lang&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Dev.to: &lt;a href="https://dev.to/commenterthe9"&gt;dev.to/commenterthe9&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Bluesky: &lt;a href="https://bsky.app/profile/thecomment.bsky.social" rel="noopener noreferrer"&gt;thecomment.bsky.social&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Twitter/X: &lt;a href="https://x.com/commenterthe9" rel="noopener noreferrer"&gt;@commenterthe9&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://cx-lang.com/blog/2026-07-10" rel="noopener noreferrer"&gt;https://cx-lang.com/blog/2026-07-10&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cx</category>
      <category>programming</category>
    </item>
    <item>
      <title>Cx Dev Log — 2026-07-09</title>
      <dc:creator>COMMENTERTHE9</dc:creator>
      <pubDate>Fri, 10 Jul 2026 00:21:18 +0000</pubDate>
      <link>https://dev.to/commenterthe9/cx-dev-log-2026-07-09-51n8</link>
      <guid>https://dev.to/commenterthe9/cx-dev-log-2026-07-09-51n8</guid>
      <description>&lt;p&gt;No developer commits landed on any branch today. That marks five days in a row. Despite this lull, the matrix remains at 292/0, keeping the working tree clean and submain nine commits ahead of main. These aren't trivial changes waiting in the wings—they're foundational adjustments covering critical components like Handle core, pattern matching, and float comparison fixes.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's waiting on submain
&lt;/h2&gt;

&lt;p&gt;Let's dive into what's been brewing on submain since the last merge. There are three feature scopes waiting to be seen:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scalar Handle core (D2.5a/b/c)&lt;/strong&gt; made some significant strides by introducing construct, read, and drop with proven generational safety via Cranelift. This isn’t just a bunch of lines in code—it's a packed-i64 representation complete with slot and generation fields, a host-side registry, and an out-parameter validity checking pattern. Six test fixtures back up these additions, supporting functionality and correctness.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pattern matching first slices&lt;/strong&gt; took an ambitious step by incorporating &lt;code&gt;as v&lt;/code&gt; named binding on enum arms and guard clauses on &lt;code&gt;when&lt;/code&gt; arms. This might not sound flashy, but it's a crucial move towards making pattern matching useful for real control flow—not merely for type discrimination anymore.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interpreter float comparison fix&lt;/strong&gt; addressed four missing &lt;code&gt;Value::Float&lt;/code&gt; match arms for relational operators. It’s a straightforward correction, but an essential one, especially for anyone relying on numerical evaluations in the interpreter path. Without it, mathematical consistency would be the first to go out the window.&lt;/p&gt;

&lt;p&gt;Alongside these language updates, submain also carries a roadmap reconciliation to fix stale version sequences—ranging from 0.3.1 through to 1.0+—alongside a new known-issues tracker found at &lt;code&gt;docs/known_issues.md&lt;/code&gt;. This catalogues five interpreter/JIT divergences. Yet, all of this remains invisible to those on main.&lt;/p&gt;

&lt;h2&gt;
  
  
  The integration gap
&lt;/h2&gt;

&lt;p&gt;Merging submain to main has been the forecasted step every day since July 4th. But it hasn't happened. Missing the mark five times on the same forecast is concern-worthy.&lt;/p&gt;

&lt;p&gt;From an outsider’s perspective, the repository state appears healthy: passing tests, a clean working tree, and finished code on submain. There's no technical debt or failing tests barricading this merge. The real barrier might be review cadence, a confidence threshold, or something unrelated to the repo entirely.&lt;/p&gt;

&lt;p&gt;Adding to the backlog, five daily log pull requests (#328 through #332) remain unmerged. Essential roadmap updates, particularly the major restructuring from the July 5th log, haven't reached main. The main-branch roadmap lags behind in its May 18th state, almost two months stale compared to submain’s last update on July 4th. The gap closes once submain merges or any daily log PR lands, but without action, neither clears.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;Carrying predictions forward feels less certain as each day passes:&lt;/p&gt;

&lt;p&gt;The submain merge remains the most impactful step we could take. Nine commits, three feature scopes, roadmap reconciliation, and a known-issues tracker—all poised to deliver significant updates once merged. Known issue #5 (I128 printing) is primed and waiting—needing just one match arm plus one host callback for completion. Plus, at least one daily log PR could independently help update the main roadmap without relying on the full submain integration.&lt;/p&gt;

&lt;p&gt;The repeated inactivity isn't inherently alarming. Software development seldom moves in a straight line, and holding patterns are par for the course. However, the gap between submain's accomplishments and main's current state widens with each passing day. Merging grows more complex as the branches diverge further.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Follow the Cx language project:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Website: &lt;a href="https://cx-lang.com" rel="noopener noreferrer"&gt;cx-lang.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/COMMENTERTHE9/Cx_lang" rel="noopener noreferrer"&gt;github.com/COMMENTERTHE9/Cx_lang&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Dev.to: &lt;a href="https://dev.to/commenterthe9"&gt;dev.to/commenterthe9&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Bluesky: &lt;a href="https://bsky.app/profile/thecomment.bsky.social" rel="noopener noreferrer"&gt;thecomment.bsky.social&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Twitter/X: &lt;a href="https://x.com/commenterthe9" rel="noopener noreferrer"&gt;@commenterthe9&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://cx-lang.com/blog/2026-07-09" rel="noopener noreferrer"&gt;https://cx-lang.com/blog/2026-07-09&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cx</category>
      <category>programming</category>
    </item>
    <item>
      <title>Cx Dev Log — 2026-07-04</title>
      <dc:creator>COMMENTERTHE9</dc:creator>
      <pubDate>Sun, 05 Jul 2026 02:43:00 +0000</pubDate>
      <link>https://dev.to/commenterthe9/cx-dev-log-2026-07-04-2462</link>
      <guid>https://dev.to/commenterthe9/cx-dev-log-2026-07-04-2462</guid>
      <description>&lt;p&gt;Handles in Cx have taken a big step forward with two key commits now on submain. The Handle type has finally become a real machine value processed through Cranelift, marking a major milestone for Phase 8 Round 2.&lt;/p&gt;

&lt;h2&gt;
  
  
  The packed-i64 Representation
&lt;/h2&gt;

&lt;p&gt;In Cx, a Handle is straightforward: a packed single i64 represented by &lt;code&gt;slot | (gen &amp;lt;&amp;lt; 32)&lt;/code&gt;. Both &lt;code&gt;slot&lt;/code&gt; and &lt;code&gt;gen&lt;/code&gt; are unsigned u32s and we use a u64 reinterpretation to avoid any sign-extension issues. Specifically, &lt;code&gt;lower_type(SemanticType::Handle(_))&lt;/code&gt; outputs an &lt;code&gt;IrType::I64&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Handling these machine values required placing runtime state in a &lt;code&gt;HandleRegistry&amp;lt;i64&amp;gt;&lt;/code&gt; behind a &lt;code&gt;OnceLock&amp;gt;&lt;/code&gt; static in &lt;code&gt;host_boundary.rs&lt;/code&gt;. This setup is a workaround for Cranelift limitations. The constraint? &lt;code&gt;jit_builder.symbol()&lt;/code&gt; relies on raw function pointers, not state-capturing closures. Safety here comes from &lt;code&gt;run_jit_subprocess&lt;/code&gt; which isolates states by using fresh OS processes for each fixture, preventing cross-test state carryover.&lt;/p&gt;

&lt;p&gt;A helper, &lt;code&gt;widen_handle_payload_to_i64&lt;/code&gt;, converts inner expressions' lowered types to i64 but only for &lt;code&gt;{I8, I16, I32, I64, Bool}&lt;/code&gt; types. Notably excluded are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ptr&lt;/strong&gt;: We'd face the &lt;code&gt;Handle&amp;lt;str&amp;gt;&lt;/code&gt; issue, where a raw scalar or a string descriptor pointer could confuse operations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;F64&lt;/strong&gt;: This would lead to silent truncation, not suitable for types requiring round-trip fidelity. Consideration here is crucial, reflecting intentional design rather than future work placeholders.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Handle.val and the Out-parameter Approach
&lt;/h2&gt;

&lt;p&gt;Reading the value (commit D2.5b) posed more challenges than expected. Our initial "uniform-i64" hypothesis didn't hold water due to strict type equality required downstream. Instead, HandleVal's semantic design uses I128, not i64, so handling it involves widening the i64 payload via sign-extending Cast to output a legitimate &lt;code&gt;IrType::I128&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For validity checks, an out-parameter is used instead of sentinels, given that the slot+gen packed space leaves no room for reserved bit patterns without conflicts. &lt;code&gt;_cx_handle_val(handle: i64, out_valid: *mut i8) -&amp;gt; i64_&lt;/code&gt; performs the out-parameter check and defaults to &lt;code&gt;IrTerminator::Trap&lt;/code&gt; if invalid. The reuse of the Alloca/Store/Load pattern, similar to Results, adapts well, though a single-byte slot suffices here.&lt;/p&gt;

&lt;p&gt;Though the Trap path is hardwired, we can't yet test invalid handles through current Cx code; since there’s neither HandleDrop nor uninitialized reads. The real testing awaits D2.5c alongside generational reuse that will naturally generate stale handles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Handle+Array Composition Success
&lt;/h2&gt;

&lt;p&gt;A third commit by early July 3rd confirmed the correctness of Handle+array composition. An earlier syntax error audit, using &lt;code&gt;arr[i]&lt;/code&gt; instead of the correct &lt;code&gt;arr:[i]&lt;/code&gt;, had been resolved. Now, Handles in array literals process and return expected results. Notably, the &lt;code&gt;t_handle_array_no_drop&lt;/code&gt; fixture confirms this improvement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test Matrix Progress
&lt;/h2&gt;

&lt;p&gt;The matrix on submain now stands at 297/0 after rising from 292. Parity scores are 237 PASS / 60 SKIP / 0 PARITY_FAIL across this set. Recent commits introduced several new fixtures, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;t_handle_construct_cross_fn&lt;/code&gt; (from D2.5a, provisional)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;t_handle_val_positive&lt;/code&gt; (standard round-trip case)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;t_handle_val_negative&lt;/code&gt; (tests for sign-extension)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;t_handle_val_bool&lt;/code&gt; (validates discrimination)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Currently, all updates remain within submain, with main unchanged.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;Up next is the HandleDrop (D2.5c), set to handle generational reuse and empirically prove the stale-handle Trap path. An integration point approaches with submain now four commits ahead of v0.3.0 and a merge to main beckons. Still in the wings are DotAccess updates in compound forms, alongside uncommitted tutorial rewrites—280 lines ready to fit into the broader narrative.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Follow the Cx language project:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Website: &lt;a href="https://cx-lang.com" rel="noopener noreferrer"&gt;cx-lang.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/COMMENTERTHE9/Cx_lang" rel="noopener noreferrer"&gt;github.com/COMMENTERTHE9/Cx_lang&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Dev.to: &lt;a href="https://dev.to/commenterthe9"&gt;dev.to/commenterthe9&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Bluesky: &lt;a href="https://bsky.app/profile/thecomment.bsky.social" rel="noopener noreferrer"&gt;thecomment.bsky.social&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Twitter/X: &lt;a href="https://x.com/commenterthe9" rel="noopener noreferrer"&gt;@commenterthe9&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://cx-lang.com/blog/2026-07-04" rel="noopener noreferrer"&gt;https://cx-lang.com/blog/2026-07-04&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cx</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
