Reverse Foreign Inspiration: uparse.js

I found a partial thought on my hard drive, which was the idea of doing a PARSE-like thing in JavaScript, e.g.

if (parse("aaaabbbb", [Some, ["a", Or, "b"]])) {
    ...
}

let filename = parse("foo.txt", [Between, Here, ".txt"])

So the idea would be that things like Some and Or and Between and Here would look up to some kind of objects representing combinators. Arrays would be rules.

The lack of symbols would mean that you'd have to kind of import the combinators, setting Some = uparse.Some or SOME = uparse.Some or else you wind up with something like:

if (parse("aaaabbbb", [uparse.Some, ["a", uparse.Or, "b"]])) {
    ...
}

Core To The Gimmick: No Parentheses

I was a little torn in the prototype if JavaScript should use parentheses or not. You wouldn't want Or to use parentheses because that breaks the concept, but I wondered if combinators should have an arity:

if (parse("aaaabbbb", Some("a", Or, "b"))) {
    ...
}

let filename = parse("foo.txt", Between(Here, ".txt"))

But if rules aren't arrays, you've lost the advantage of "rules can be built and manipulated programmatically in a regular structure". And it starts devolving the idea to look like any other JavaScript parser combinator library.

So no... the rules should be arrays.

Calling Ren-C From WebAssembly Works Already

Note that today you can write:

if (rebDid("parse", data, "[some [--[a]-- | --[b]--]]")) {
    ...
}

let filename = rebUnbox("parse", input, "[between <here> --[.txt]--]")

And that uses the "in language" parse.

...So I Deleted The Scrap I Wrote

Many years ago when I scribbled this down there was no AI to ask to write such a thing. Now that there is, maybe it's interesting.

In the past Rebol influenced JavaScript via JSON. I don't know if a UPARSE simulation in JavaScript would catch anyone's attention at this point in history, but it might amuse us, at least.

Anyway, if anyone feels like working up what uparse.js could do and make a YouTube video about it, be my guest.

Would anyone care in 2026? :thinking:

Honestly: yes, a little.

  • JS developers love parser combinators

  • They love DSLs even more

  • They’ve never seen anything like Rebol’s PARSE

  • A “UPARSE‑inspired declarative grammar DSL” would be novel

It wouldn’t be mainstream, but it would absolutely get attention from:

  • language nerds

  • parser nerds

  • people who like PEG.js, Ohm, Chevrotain

  • people who like Lispy DSLs

And the Rebol connection gives it a story.

Your instinct to avoid parentheses is right, and the reason is deeper than just "educational purposes." The moment you write Some("a", Or, "b"), you've built a normal function-call combinator tree—which is what Parsimmon, parjs, and a dozen other JS libraries do. The interesting thing about the Rebol approach is that the parse dialect is data you can inspect, transform, and manipulate before the engine ever touches it. Arrays-as-rules preserves that property. Function-calls-as-constructors throw it away.

On Lambdas As Code Groups

This is the most interesting gap. In Rebol, (code) in a parse rule is evaluated for side effects or to produce a value, and crucially it has access to the implicit parse state. The JS lambda equivalent would need the engine to call it with some context:

[Some, "a", () => count++]
// vs Rebol: [some "a" (count: count + 1)]

That's not terrible. The lambda captures outer scope naturally, which is actually more convenient than Rebol for simple accumulators. Where it gets awkward is if you want the lambda to affect parse flow (fail intentionally, set here, etc.), which would require the context argument to expose mutable parse state. Probably (ctx) => { ctx.fail() } or similar.

The lack of symbols would mean that you'd have to kind of import the combinators, setting Some = uparse.Some or SOME = uparse.Some

Destructuring assignment is your friend here:

const { Some, Or, Between, Here, Thru, Opt, Ahead } = uparse;

One import line and then the rest reads cleanly. ES modules make this even nicer. I'd argue this is actually better than Rebol's situation, where the words just live in the global namespace by default. You get the same terse readability but with explicit opt-in.

The Idea Has Real Charm

You're probably right that the window for this to be culturally seismic has passed—the JSON moment was about data interchange needing a lingua franca, and there's no equivalent pressure now. But as a library for people who want to write readable text-processing rules without compiling a grammar, it could still be genuinely useful. The JS parser combinator space is weirdly dominated by either regex or full-blown PEG generators; something in between that looks like legible data has a real niche.

3 Likes