BLANK!: The World's Weirdest "Comma Mechanic"

We now have the ability to have source-level "expression barriers"... that show up as commas:

>> all [1 + 2, 3 + 4]
== 7

>> all [1 +, 2 3 + 4]
** Script Error: + is missing its value2 argument

>> all [(1 +) 2 3 + 4]  ; error parity
** Script Error: + is missing its value2 argument

Not a "COMMA!" Type... It's Less Than Meets The Eye

The first implementation of this was indeed called "COMMA!" and it behaved like you might expect:

old>> first [,]
== ,

old>> type of first [,]
== \~{comma!}~\  ; antiform

old>> mold first [,]
== ","

But over time, observations about this started to reveal that maybe COMMA! wasn't "just another value". For instance, you couldn't decorate them with sigils, because standalone Sigils were things:

>> obj: make object! [a: '@, b: '$, c: ~, d: '',]
== &[object! [
    a: @
    b: $
    c: ~
    d: ''
]

The realization came to be that the COMMA! wasn't the data type... rather, commas were artifacts of rendering in lists to show you where the real type was... an invisible type called BLANK!.

Further, BLANK! is the base type of the other things you see above--like the lone Sigils (@ or $ or ^)... or the most slight of all quasiforms (~) or a standalone quote count (' or '' or ''' etc.)

So this strange datatype has no molding of its own, but is only suggested by the rendering around it.

Having its antiform be VOID! led to the satisfying statement: "VOID! is the antiform of BLANK!" vs. the much more head-scratching "VOID! is the antiform of COMMA!" :confused:

Expanded Application To UPARSE

I also added the feature to UPARSE and made a patch of the feature into PARSE3 (it is difficult with how parse3 is written to do a "good" job of this):

>> parse "aaabbb" [some "a" some "b"]  ; you can still do this
== "aaabbb"

>> parse "aaabbb" [[some "a"] [some "b"]]  ; could have always done this
== "aaabbb"

>> parse "aaabbb" [some "a", some "b"]  ; this is new!
== "aaabbb"

>> parse "aaabbb" [some, "a" some "b"]  ; catching misunderstandings!
** Script Error: expression barrier hit while fulfilling argument

Beyond the expression barrier feature--which I have always believed to be important--having commas available in dialects is powerful.

Note that I left in support for 1,1 being a synonym for 1.0 based on the idea of space significance. This means you'll have less ability to copy/paste data from other contexts directly, like (1,2,3) ... but it's not clear how much gain there is from allowing that when so many other things won't work (especially in plan -4, where foo(a, b c) isn't loadable either).

At least for the moment, this breaks the idea of supporting commas in URL!s directly. While it might be possible to say that http://a,b is legal but http://a, is not, how such things are scanned needs to be redesigned so there's not so much sporadic code all over the place. I'm open to the idea...just not assuming it as a foregone conclusion.

I Actually Like It

Many years ago when expression barriers were first being cooked up, I had been mostly swayed by the "commas and periods are too hard to tell apart" idea...to say that the only purpose they should have in the language would be as synonyms.

If this idea is taken to extremes, we would also say that the number 1 and lowercase L and the uppercase i and the vertical bar all have to be the same, due to I1l|. being too hard to differentiate. (Though fonts and syntax highlighting choices can go a long way in that.)

Today my thinking is that you don't necessarily control this kind of thing from the language level. You give people choices, and they write their code as it feels good to them. If they've got a certain mix of data and don't like comma with it, they should use another arrangement. Put things in groups, or on newlines, or whatever.

I'll point out you have the option to put an entire expression in a group, or just the last thing and keep the comma. It's up to you. So taking the maybe-ugly combo of blank-tailed TUPLE! and comma, you could go with your taste:

1 + a., 2 + 3
1 + (a.), 2 + 3
(1 + a.) 2 + 3
(1 + a.) (2 + 3)
[
    1 + a.
    2 + 3
]

It's something people can ignore entirely if they want. Don't use it if you don't like it!

2 Likes

Wow, I'm in love with commas in parse expressions. :heartpulse:

1 Like

I had a similar thoughts way back:

In most areas, the comma has been a reserved character in REBOL - set aside for some mysterious potential future use. My suggestion for how to utilise the comma is based on usage in other languages - some similar in appearance to REBOL (like CSS), some not (Ruby, JavaScript): Introduce a comma! datatype. It'd be an any-word! value and could be most useful in dialect creation:

1, word, here => [integer! comma! word! comma! word!]

In Ruby, commas are used to separate values in Arrays and pairs in Hashes, but are also used to bind both types where the bounding braces are omitted enabling Ruby 'dialects'

read :url => 'some url', :method => 'get'

In REBOL dialects, the implied block could be a similarly employed technique to aid readability.

pattern red, 0.0.255, green 1x2, 5, spaced

In CSS, commas are used to bind and separate:

font: bold italic 1.2em/1.4 'Georgia','Times New Roman',serif;
background: rgba(255,0,0,0.4) url('top image') repeat-x center top, url('bottom image') repeat-x center bottom;

Such freewheeling, inconsistent use of commas can still be intuitive, but not with any hard rules about what their syntactic role is, rather as a value in their own right with their own semantic presence.

pair 1.5 3, 7 pi, 1.7 infinity

I had originally wanted to copy the 'implied block' model of CSS and Ruby, but am now more or less on the same page as your proposal here.

1 Like

This may be a stretch, but I wonder if there's an argument here for copying a MarkDown convention for an alternative way to express URLs: allowing <> as delimiters. It would only apply to URLs that contain :// so as to distinguish from tags with namespaces.

1 Like

2 posts were split to a new topic: What Does COMMA! Evaluate To (If It Evaluates?)

So it was interesting (though not entirely surprising) to find that Carl had proposed commas as an evaluation terminator in 2007:

http://www.rebol.net/r3blogs/0086.html - Explicit EvaluationTerminator

He said "I've been thinking about this for more than 8 years, and I've never reached a positive conclusion. (Lol)"

It's a similar concept (though less similar once COMMA! was reimagined as BLANK!). But there's a lot of issues to sort out besides the syntax once you get into it, that he would have found if he tried it.

But Interesting Comments On The Blog!

Edoc
15-Apr-2007 8:38:53
It doesn't seem like a big benefit, unless it opens up possibilities to some breakthrough feature (e.g., rebol-dialect --> rebcode --> scheme --> compiled C).

13 years later... :slight_smile:

Oldes speaks up in support of the commas, while most people don't want them, making another rare case of us agreeing on something.

Gregg is against the idea.

pekr Suggests colon...

   new-face: make any [
       all [parent : object? new : new] 
       all [parent :  word? new  : get-style new] 
       vid-face
   ] any [all [parent : block? new : new] [parent: 'panel]] 

It doesn't look that bad there, but he's cherry-picked an example where the stuff he's separating has no SET-WORD!s or GET-WORD!s.

More interestingly though, he says:

Looks quite elegant, similar to | (which would be imo best, if it would not implicate parser's OR).

I remember when I tried to use | and I would swear he was one of the people who was against it. I don't think | had anyone who even said the idea had any merit. Maybe I'm misremembering.

2 Likes