Generic Quoting Makes Headway on MAKE OBJECT!


Rebol2/R3-Alpha/Red have a notation for molding out objects:

Red>> obj: make object! [a: 10]
== make object! [
    a: 10

Let’s ignore for the moment the fact that it’s giving a sequence of what looks to be two words and a block to denote a single OBJECT!. What it’s trying to do is give you a syntax that looks like what it would take to create the object if typed from source. (Perhaps it would more appropriately be SOURCE OBJ vs. MOLD OBJ)

But there are some pretty big problems. What if you said:

Red>> obj: make object! [g: quote (1 + 2) n: 0 unset 'n w: quote 'word]
== make object! [
    g: (1 + 2)
    n: unset
    w: 'word

The resulting MOLDing MAKE OBJECT! doesn’t get close to what it’s trying to capture.

  • In the original object G is a “PAREN!” with (1 + 2). Running that MAKE OBJECT! would give you G of INTEGER 3.
  • We’ll assume it meant #[unset] instead of the word UNSET (which here, would unset word). If it had said what it meant, the make object! would have failed, as it’s not legal to assign unsets via set-word.
  • W would come out as a WORD! here, instead of the LIT-WORD! in the original object.

Generalized escaping to the rescue

Ren-C doesn’t have a full solution to the problem of round-trip representations as text. But now, when it comes to this, it’s at least a powerful step closer:

>> obj: make object! [g: lit (1 + 2) n: 0 unset 'n w: lit 'word]
== make object! [
    g: '(1 + 2)
    n: '
    w: ''word

Here we see these loopholes getting closed. The make is actually able to produce a structurally identical object (like I said, let’s avoid talking about binding, that’s its own conversation). Note the unusual-but-very-important aspect that a single apostrophe evaluates to null.

It’s not necessary to put the apostrophe on all items, only those that evaluate…so the system should probably only add them if needed:

>> obj: make object! [i: 10 t: "hello" p: ''a/b/c]
== make object! [
    i: 10
    t: "hello"
    p: ''a/b/c

INTEGER! and TEXT! can be left as-is, so perhaps worth it to do so. Here we see a LIT-PATH!, escaped in the original representation for its assignment, escaped again for its re-representation.

This generalized-escaping-based mechanism replaces a previous attempt to deal with the issue, and gives strong evidence that the effort was time well spent. :face_with_monocle:

(P.S. It had been a topic of debate for a while, as to whether you should have to escape Rebol [Type: 'module] or if that was just noise. For overall consistency with the round-tripping of these kinds of structures, I think the apostrophe needs to be mandatory on evaluative types…it seems like there’s now a coherent story on this.)

Seeing all ACTION!s as variadic FRAME!-makers