Skip to content

fix(amend): evaluate first arg; in-place amends return the symbol#257

Merged
singaraiona merged 2 commits into
masterfrom
fix/amend-eval-first-symbol-return
Jun 13, 2026
Merged

fix(amend): evaluate first arg; in-place amends return the symbol#257
singaraiona merged 2 commits into
masterfrom
fix/amend-eval-first-symbol-return

Conversation

@singaraiona

Copy link
Copy Markdown
Collaborator

Problem

insert/upsert decided in-place vs functional by inspecting the raw parse node for a literal 'sym (the ATTR_QUOTED flag), so only a literal first arg drove in-place mode. A symbol arriving any other way raised error: type:

(set t (table [a] (list [])))
(insert 't (list 1))      ;; ok — literal 'sym
(set name 't)
(insert name (list 2))    ;; error: type   ← symbol via a variable

update and alter already did the right thing (evaluate the first arg, resolve a symbol to its named global).

Fix

Unify all amends on one rule: evaluate the first argument; a symbol value names a global to amend in place, a table/vec value is amended functionally. In-place amends now return the symbol rather than the amended clone (matching v1).

  • query.cinsert/upsert mirror update's eval-first dispatch; dropped the ATTR_QUOTED raw-node special case. In-place returns the symbol across insert/upsert/update. (The internal upsertinsert recursion via the already-evaluated table path is untouched.)
  • tblop.calter in-place returns the symbol.

This works through variables, (quote t), and lambda parameters, since everything now routes through ray_env_get/ray_env_set like the literal 'sym path always did.

Tests

  • New regression test/rfl/table/insert_inplace_symbol.rfl (variable/quote/lambda forms, functional-vs-in-place, symbol return value across insert/upsert/update/alter).
  • Updated existing tests that relied on the old value-return behavior (update.rfl, query_coverage.rfl, linkop/coverage.rfl, test_lang.c), including the (set x (alter 'x ...)) idiom which now uses the in-place mutation directly.

Full suite passes under the sanitizer build (3441 passed, 0 failed, 3 pre-existing skips).

🤖 Generated with Claude Code

singaraiona and others added 2 commits June 13, 2026 18:41
insert/upsert decided in-place vs functional by inspecting the raw parse
node for a literal 'sym (ATTR_QUOTED), so only a literal first arg drove
in-place mode. A symbol arriving any other way — through a variable, via
(quote t), or as a lambda parameter — fell through to the vec/list path
and raised `type`.

Unify all amends on one rule (already followed by update/alter): evaluate
the first argument; a symbol value names a global to amend in place, a
table/vec value is amended functionally. In-place amends now return the
symbol rather than the amended clone, matching v1.

- query.c: insert/upsert mirror update's eval-first dispatch; drop the
  ATTR_QUOTED raw-node special case. In-place returns the symbol across
  insert/upsert/update.
- tblop.c: alter in-place returns the symbol.
- tests: new insert_inplace_symbol.rfl regression (variable/quote/lambda
  forms, symbol return); update existing tests that relied on the old
  value return, including the (set x (alter 'x ...)) idiom.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@singaraiona singaraiona merged commit a0b7870 into master Jun 13, 2026
4 checks passed
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