Skip to content

Add splice where-function for multi-position sentinel rewriting #708

@yegor256

Description

@yegor256

The where-function dispatch in src/Functions.hs:34-47 exposes concat, sed, join, size, tau, random-tau, random-string, number, string, sum, dataize, scope, and contextualize, but it has no primitive that replaces every occurrence of a structured sub-formation inside a captured binding group within a single firing. Multi-emit fusion in objectionary/hone-maven-plugin#570 — specifically the 401c-fuse-cps-auto.phr rule in that repo — needs exactly that primitive in order to splice an auto body in front of every Φ.hone.emit marker in a cps body in one shot (for flatMap and verbatim mapMulti).

The naive workaround does not work. A non-consuming variant of the rule that keeps the source auto formation in result so phino's fixed-point loop fires once per emit marker still matches after each rewrite (the same emit marker is still in the body, the auto formation is still adjacent), so phino re-splices forever and never reaches a fixed point. The existing join function concatenates two binding groups but cannot find-and-replace inside one; sed operates on string scalars only; neither covers a structured-sub-formation match within a binding group. Without a multi-position primitive — or a "this position was already rewritten" sentinel on the marker side — the rule is inexpressible.

The smallest fix is to add a new dispatch entry next to _join at src/Functions.hs:46 (buildTerm' "splice" = _splice) and an implementation that takes three arguments — an input binding group, the sentinel formation expression that identifies positions to rewrite, and a replacement binding group — and returns a new binding group with the replacement spliced in at every position where a binding's value structurally matches the sentinel. A proposed YAML signature for rule files is {meta: 𝐵-out, function: splice, args: [𝐵-in, 𝜏-sentinel-phi, 𝐵-replacement]}. The function's contract — "splice the replacement in at every match position in one firing" — is part of the definition; the name does not encode multiplicity (the same way sed does not need to say "sed-globally"). It forms a natural pair with join: join concatenates two binding groups, splice weaves a replacement into a binding group at every sentinel position. No existing function needs to change.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions