Skip to content

fix(binary_tree): read trees passed back in as flat arrays - #977

Merged
martin-henz merged 1 commit into
masterfrom
fix/binary-tree-flattened-list
Sep 27, 2026
Merged

martin-henz merged 1 commit into
masterfrom
fix/binary-tree-flattened-list

Conversation

@martin-henz

Copy link
Copy Markdown
Member

Problem

After #976, building a tree from another tree fails:

from binary_tree import make_tree
make_tree(5, make_tree(4, None, None), None)
make_tree expects binary tree for left (expected binary tree, got ARRAY)

The same happens in Source: make_tree(5, make_tree(4, null, null), null).

A tree is the list [entry, left, right], and make_tree builds it as a PAIR chain. When a program passes that tree back into the module, py-slang (pythonToModule) and js-slang (sourceToModule) both flatten a proper list into a single 3-element ARRAY. is_tree and the accessors walked every tree with pair_head/pair_tail. On an ARRAY those read elements 0 and 1, so the "tail" of [4, None, None] was None and the tree was rejected.

This bug predates #976. It was hidden because make_tree used to fail earlier, on its entry argument.

Fix

A new helper, readTreeNode, reads a tree node into its three elements. It reads an ARRAY by index and walks a PAIR chain, and requires exactly three elements either way. is_tree, entry, left_branch and right_branch all use it.

Tests

The old "round-tripped as ARRAY" test built nested 2-element arrays, which neither evaluator produces, so it passed while the real case failed. It is replaced by tests using the flat shape:

  • is_tree accepts flat trees, including a flat tree nested inside another
  • is_tree rejects arrays that don't have 3 elements, and flat trees with non-tree branches
  • make_tree accepts a flat tree as a branch (the reported case)
  • entry/left_branch/right_branch read a flat tree by position

The three positive tests fail on master and pass with this change. binary_tree has 23/23 passing, and tsc and lint are clean.

Related

plotly's add_fields_to_data (behind new_plot) also walks a list with pair operations, and reads a flat ARRAY as a single pair. It likely has the same bug. Not addressed here.

🤖 Generated with Claude Code

make_tree(5, make_tree(4, None, None), None) failed with
"make_tree expects binary tree for left (expected binary tree, got ARRAY)".

A tree is the list [entry, left, right]. make_tree builds it as a PAIR
chain, but when a program passes it back in, py-slang and js-slang both
flatten a proper list into one 3-element ARRAY. is_tree and the
accessors walked every tree with pair_head/pair_tail, which on an ARRAY
read elements 0 and 1 as head and tail, so the flattened tree was
rejected.

Trees are now read by readTreeNode, which reads an ARRAY by index and a
PAIR chain by walking it, and requires exactly three elements. The old
ARRAY test built nested 2-element arrays, which neither evaluator
produces; it is replaced by tests using the real flat shape.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@martin-henz
martin-henz merged commit 2b83b53 into master Sep 27, 2026
12 checks passed
@martin-henz
martin-henz deleted the fix/binary-tree-flattened-list branch September 27, 2026 07:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant