diff options
author | polwex <polwex@sortug.com> | 2025-10-06 22:06:53 +0700 |
---|---|---|
committer | polwex <polwex@sortug.com> | 2025-10-06 22:06:53 +0700 |
commit | 64b132efc5ad870677ac974334b30fdbc4afafd3 (patch) | |
tree | 6f3d07fd9ff08d0cfc854d0396fa03c2e3d2622b /ocaml/NOCK_FIXES_IDEAS.md | |
parent | 6ce2c5919f36776fe8aea711b94bbd2d64c8207a (diff) |
kinda getting there
Diffstat (limited to 'ocaml/NOCK_FIXES_IDEAS.md')
-rw-r--r-- | ocaml/NOCK_FIXES_IDEAS.md | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/ocaml/NOCK_FIXES_IDEAS.md b/ocaml/NOCK_FIXES_IDEAS.md new file mode 100644 index 0000000..1811c21 --- /dev/null +++ b/ocaml/NOCK_FIXES_IDEAS.md @@ -0,0 +1,55 @@ + +C: call #1 is opcode 8 (extend)OCaml: call #1 is opcode 0 (slot), call #2 is opcode 0 (slot), call #3 is opcode 7 (compose) + + This means for the same input formula [2 [0 3] [0 2]], C is directly executing opcode 8, while OCaml is executing the slot lookups [0 3] and [0 2] as separate Nock calls, then getting opcode 7. + + The problem is likely that OCaml is treating slot lookups as full recursive Nock evaluations, when they should be internal operations. Let me check the OCaml Nock 2 implementation: + + | 2 -> + (* Nock 2: *[subject formula new_subject] - evaluate with new subject *) + (* C evaluates tail first, then head - must match this order! *) + if not (is_cell gal) then raise Exit; + let c_gal = tail gal in + let b_gal = head gal in + let nex = nock_on bus c_gal in (* Tail first like C *) + let seb = nock_on bus b_gal in (* Head second like C *) + nock_on seb nex + + The issue is that when c_gal = [0 2] and b_gal = [0 3], we're calling nock_on recursively, which logs and increments the call counter. But maybe C handles slot lookups differently—perhaps as an internal + operation without logging? + + Let me check what C does when it encounters [0 axis] - does it call u3n_nock_on recursively, or does it handle it inline? + + Should I investigate the C _n_nock_on or _n_burn implementation to see how it handles Nock 0 (slot) operations? + + + -- + + + + C logs: + >>> ENTER call #0 depth=0 opcode=2 bus=cell + >>> ENTER call #1 depth=1 opcode=8 bus=cell ← Goes directly to opcode 8! + + OCaml logs: + >>> ENTER call #0 depth=0 opcode=2(eval) bus=cell + >>> ENTER call #1 depth=1 opcode=0(slot) bus=cell ← Evaluates [0 3] + <<< EXIT call #1 depth=1 returns=cell + >>> ENTER call #2 depth=1 opcode=0(slot) bus=cell ← Evaluates [0 2] + <<< EXIT call #2 depth=1 returns=cell + >>> ENTER call #3 depth=1 opcode=7(compose) bus=cell ← Result is opcode 7 + + The problem is clear: C doesn't call u3n_nock_on recursively for simple operations like [0 axis]. Instead, C compiles the Nock formula to bytecode first, and the bytecode handles slot lookups inline without + recursive nock calls. + + This is why C shows opcode 8 directly - the bytecode compiler has already evaluated [0 3] and [0 2] internally and determined that the next operation is opcode 8. + + OCaml, on the other hand, is a pure interpreter - every Nock formula, even simple ones like [0 3], goes through nock_on recursively. + + This is not a bug in OCaml - it's the correct interpreter behavior! C's bytecode is an optimization. To make OCaml match C's log output, we'd need to either: + + 1. Add bytecode compilation to OCaml (major work) + 2. Inline simple operations like slot lookup in Nock 2 (quick fix but changes the interpreter structure) + 3. Accept that the logs will differ at this level but verify the final results match + + Would you like me to inline slot lookups in Nock 2 to reduce the logging noise, or should we focus on verifying that despite the different execution paths, both C and OCaml produce the same final results? |