{ Rethinking Braces }... as an array type?

In Carl's "ASON" pitch, he proposes lexical braces to mean objects:

I don't think this would satisfy JavaScript programmers...nor Rebol programmers for that matter...as a replacement for MAKE OBJECT!. (Note there is no source code for ASON, so we don't know how many scenarios he has looked at or hasn't.)

The problem is that if you take braces to mean objects literally, it raises the question of when expressions would be evaluated... or if expressions are allowed at all.

You can't evaluate expressions at LOAD time because the variables and contexts are not set up. So what would you get from this?

center: {x: 10, y: 20}

points: [
     {x: center.x - 10, y: center.y - 10}
     {x: center.x + 10, y: center.y + 10}
]

print ["Point 1's X is" points.1.x]

See the problem? When could these expressions be evaluated? They couldn't be evaluated at load time (it doesn't know what CENTER is yet, the line assigning it hasn't happened). And it can't be when POINTS is assigned, because the BLOCK! is inert.

It seems you simply can't use expressions when braces are used to lexically represent an object instance.

How Does Red's "Lexical MAP!" #(...) Deal With This?

It doesn't.

red>> points: [#(x: 1 + 1 y: 2 + 2)]
== [#(
    x: 1
    +: 2
    y: 2
)]

Since it couldn't evaluate the expressions it just did something weird, as if you'd written:

 points: reduce [make map! [
     x: 1
     +: 1
     y: 2
     +: 2  ; overwrites earlier mapping of + -> 1
]]

:roll_eyes:

So if you want expressions, you need to go through the normal process of MAKE MAP!.

How Does JSON Deal With This

It doesn't.

JSON is narrowly defined to not allow expressions...because it is for exchanging data.

You are discouraged from actually using a plain JavaScript eval() to process a JSON message precisely because it can evaluate...which could lead to bugs or vulnerabilities.

That doesn't change the fact that {...} within the JavaScript language evaluate when the line containing them is run. In this usage they are called object initializers.

How Would The FENCE! Proposal Handle This?

The proposal differs from "{} as lexical object" because it says that FENCE! is just another category of array...which when evaluated gives you an OBJECT!.

Arrays would be a case where this would surprise a JavaScript programmer, because they expect an array initialization to run evaluations of the object initializers inside that array. That's because arrays get evaluated without a REDUCE step.

But this applies for any expression, not just objects:

js>> var test = [1 + 2, 30 + 40]
js>> test
<- Array [ 3, 70 ]

js>> var test = [{x: 1 + 2, y: 30 + 40}]
js>> test
<- Array [ {...} ]
   > 0: Object {x: 3, y: 70}
     length: 1

We understand that the first case in Rebol would need some sort of evaluation request like REDUCE to run the expressions. With FENCE! the way I propose it, there would have to be a similar request for evaluation.

This calls for operators that parallel JSON.deserialize(), that would enforce that there weren't expressions. But also operators that would be more COMPOSE-like...looking for all the OBJECT!s in nested arrays and generating new BLOCK!s of OBJECT!s from them.

What About Accessing FENCE! In Object-Like Ways?

There's historical precedent of being able to pick from blocks like they were objects. Fences could try that as well.

>> points: [{x: 10, y: 20}]
== [{x: 10, y: 20}]

>> type of points.1
== #[datatype! fence!]

>> points.1.y
== 20

But this leads to complex questions. What if they are expressions? (The accessor could error if it doesn't see a comma?) How would NULL be represented? (Going directly to the next SET-WORD?) FENCE! is a generic array so you can APPEND arbitrary material to it...what happens if you add another X?

I don't know how beneficial it is to go along with this illusion, but the subject matter already has a post for discussing it:

BLOCK! and OBJECT! Parity in Pathing/Picking

One nuance here is that if braces are used principally for objects, then maybe @rgchris's wish for BLOCK!s to think in terms of /SKIP counts (alternating keys and values?) could coexist with a SET-WORD!-seeking rule for FENCE!.

Summary...?

The lexical brace concept (which I have never lent my support to) would not replace MAKE OBJECT! because it cannot be used for expression evaluation. It would be creating the objects it represents at LOAD-time, not when expression contexts were known. It would thus serve a very niche purpose in making data exchange somewhat-more JavaScript compatible.

The FENCE! proposal would be able to replace MAKE OBJECT!, but would be essentially a synonym for that functionality today. You would still need to be in an evaluative context to get the OBJECT!...and until then it would remain as an unevaluated FENCE!. But at least you can use it for more than just data exchange. And on the plus side, this opens up fences for interesting dialecting purposes.

2 Likes