The Language World's Weirdest COMMA! Mechanic

All right, I went and wrote it:

Though sounding a bit like a broken record at this point, please add tests as you can think of them.

%comma.test.reb

Due to having to juggle about a million design decisions at once that have actual deep difficult ramifications, I kind of have to draw the line after I feel I've gotten past any obvious disproofs of an idea...so the tests only go so far in the initial commit. Unfortunately that's about as far as they tend to stay until bugs are found.

>> 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

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 comma 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 COMMA! 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.

One thought I had was that the COMMA! might represent a pause instead of a barrier when it came to enfix. This could make it a precedence manipulator:

>> add 1 2 * 3
== 7

>> add 1 2, * 3
== 9  ; as if you'd written `(add 1 2) * 3`

The current thought is it acts more like you've written (add 1 2) (* 3).

We probably want such an operator, but I don't think comma is it. The barrier behavior seems more reasonable and uniform, and lets you throw commas into lists of generated expressions and know that you're keeping them separate. (well, modulo hard quoting)

2 Likes

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 COMMA! 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 the same syntax concept. 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.

He might have said a COMMA! just evaluates to UNSET!. Well that's not great if you're trying to use it in something like an ANY or ALL, because either they error on the unset (which makes it clearly bad) or unsets are truthy and that could be disruptive (think NONE-OF [a, b, c]).

So COMMA! cannot evaluate to a "normal" product. He'd have to invent VOID, and trying to do that without antiforms is going to have all kinds of issues.

I imagine he'd have probably tried to implement transparency by having the evaluator skip them like they're not there. That raises it's own question. For instance: where should your step be after a DO/NEXT of [x: 1 + 2, y: 3 + 4]?

  • If the evaluator consumes the comma, then you would be at [y: 3 + 4] and never know it was there. Should the user of the DO/NEXT not be able to react to commas due to them being explicitly ignored and consumed at the end of expressions?

  • Or should a step leave you at [, y: 3 + 4]? If it does that, then what if you're looking for SET-WORD!s and miss it, because the next evaluator step takes you to the end at []?

It's my belief that COMMA! needs to have its own evaluator step, and its own evaluation product. And I believe that product must not be storable in SET-WORD!, e.g. x:, must error. Also I think commas are useful for an expression out of parts, like append code [a + b,]. You might have a lot of expressions like that you're appending together but then the terminal comma needs to vanish (like a NIHIL) so you still get the overall product. But it can't be NIHIL, because... okay, going too deep here.

Anyway my point is just: Having the syntax would have only been the beginning...and there would have been no isotopic theory to help.

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.

1 Like