Skip to content

JS WAM: distinct string term tag - #4204

Open
s243a wants to merge 3 commits into
grok/wamjs-op3from
grok/wamjs-string-tag
Open

JS WAM: distinct string term tag#4204
s243a wants to merge 3 commits into
grok/wamjs-op3from
grok/wamjs-string-tag

Conversation

@s243a

@s243a s243a commented Aug 30, 2026

Copy link
Copy Markdown
Owner

G-W3 residual: the JS WAM now has a distinct string tag (V.String) instead of interning SWI strings as atoms.

Branched from grok/wamjs-op3 and extended it (net additions). No INTEGRATION_PATCH.md.

What landed

  • Term model: V.String(s) alongside atom/int/float/var/struct. deref, unify (string unifies only with an equal string, never an atom of the same text), copy_term, ==/\==, and compare/3 / sort handle the tag.
  • Standard order matches SWI 9.0.4 (the oracle on this tree): Var < Number < String < Atom < Compound. "foo" @< foo / compare(foo, "foo") is >. The older “Atom < String” manual line is not this SWI version.
  • atom/1 is false for strings; string/1 is true only for the tag.
  • String-producing builtins now box V.String:
    • atom_string/2
    • string_concat/3 (atom_concat still produces atoms)
    • string_chars/2 construct (decompose is still a list of one-char atoms)
    • string_to_atom/2
    • number_string/2
    • split_string/4 (list of strings)
  • write/1 prints the text without quotes (SWI write). format ~q quotes with ".
  • Pratt reader tokenizes "..." as the string tag.

Compiled constants stay atoms. The shared WAM tokeniser stores every constant as a Prolog string token, so wrapping put_constant in V.String would rewrite atoms/ints and break the 48-query suite. Construct strings via builtins or the Pratt "..." reader.

Tests

probe_string_tag/0 in tests/test_wam_javascript_builtins.pl:

  • atom_string(a, S), string(S), \+ atom(S)
  • split_string('a,b,c', ',', '', Parts) is a list of strings
  • string_concat(x, y, Z) yields a string
  • sort([foo, SFoo, 1, bar], L)[1, SFoo, bar, foo]

Local acceptance:

  1. tests/test_wam_javascript_builtins.pl green (incl. new probe)
  2. tests/test_wam_javascript_lowered.pl and tests/test_wam_javascript_fact_sources.pl green
  3. Official CONFORMANCE_TARGETS=javascript harness exits 0 (adapter still unpatched; local 48-query stand-in in the builtins file stays 48/48)
  4. SWI vs Node dumps match for string/1, atom_string, split_string, string_concat, and standard-order sort

Residuals

  • writeq/1 is not registered as a standalone builtin (quoted rendering is via format ~q)
  • Compiled "foo" literals collapse to atom foo (shared WAM constant tokens; cannot fix without editing wam_target.pl)
  • Fact-source JSON/TSV cells still intern as atoms
  • string_length/2 not added
  • format('~q', [List]) does not quote nested strings (list walk uses write, not writeq)
  • Cyclic terms are N/A for the string tag itself
Open in Web Open in Cursor 

cursoragent and others added 3 commits August 30, 2026 20:12
Introduce V.String and thread it through unify, ==, copy_term, write,
compare/sort (Atom < String < Compound). String-producing builtins
(atom_string, string_concat, string_chars, string_to_atom, number_string,
split_string) now yield strings; compiled Prolog string constants emit
as V.String.

Co-authored-by: johns243a <johns243a@gmail.com>
The shared WAM tokeniser stores every constant as text, so treating
string(C) as V.String rewrote atoms and broke unify. Strings come from
builtins and the Pratt \"...\" reader. Standard order matches SWI 9.0.4
(String @< Atom).

Co-authored-by: johns243a <johns243a@gmail.com>
String sorts before Atom on this SWI (compare(foo,"foo") = >).

Co-authored-by: johns243a <johns243a@gmail.com>
@s243a
s243a marked this pull request as ready for review August 30, 2026 20:17
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.

2 participants