* * * * *

                    Some comments on delimiter-first code

I was reading “Delimiter-first code [1]” (via Lobsters [2]) and I was struck
by his first example of comma-first formatting:

-----[ SQL ]-----
-- leading commas
SELECT employee_name
    , company_name
    , salary
    , state_code
    , city
FROM `employees`
-----[ END OF LINE ]-----

That doesn't look half bad, I thought. It could make for smaller diffs in
some cases. For instance, I have this:

-----[ C ]-----
fprintf(
        stdout,
        "Status: %d\r\n"
        "X-Error: %s\r\n"
        "Content-type: text/html\r\n"
        "\r\n",
        level,
        errmsg
      );
-----[ END OF LINE ]-----

Rework it to use comma-first formatting:

-----[ C ]-----
fprintf(
           stdout
        , "Status: %d\r\n"
          "X-Error: %s\r\n"
          "Content-type: text/html\r\n"
          "\r\n"
        , level
        , errmsg
      );
-----[ END OF LINE ]-----

I still have to work within the confines of C, but here it's easier to see
that the string literal is one long literal and not four additional
parameters, so that's good. It's a bit strange looking, but I could get used
to it (I got used to “char const” over “const char” because const applies to
the object to its right, except if starts the declaration; it makes parsing
“char const *const p” easier for me—this declares p to be a constant pointer
to constant data). And if I need to add to it:

-----[ C ]-----
fprintf(
           stdout
        , "Status: %d\r\n"
          "X-Error: %s\r\n"
          "Content-type: text/html\r\n"
          "X-Foobar: %s\r\n"
          "\r\n"
        , level
        , errmsg
        , foobar
      );
-----[ END OF LINE ]-----

the diff is easier to follow—this:

-----[ dif ]-----
5a6
>            "X-Foobar: %s\r\n"
8a10
>          , foobar
-----[ END OF LINE ]-----

instead of:

-----[ diff ]-----
5a6
>          "X-Foobar: %s\r\n"
8c9,10
<          errmsg
---
>          errmsg,
>          foobar
-----[ END OF LINE ]-----

But then I came across this bit of code I wrote:

-----[ C ]-----
XEvent se =
{
 .xselection =
 {
   .type       = SelectionNotify,
   .serial     = NextRequest(event->xselectionrequest.display),
   .send_event = True,
   .display    = event->xselectionrequest.display,
   .requestor  = event->xselectionrequest.requestor,
   .selection  = event->xselectionrequest.selection,
   .target     = event->xselectionrequest.target,
   .property   = event->xselectionrequest.property,
   .time       = event->xselectionrequest.time,
 }
};
-----[ END OF LINE ]-----

And … um …

-----[ C ]-----
XEvent se =
{
 .xselection =
 {
     .type       = SelectionNotify
   , .serial     = NextRequest(event->xselectionrequest.display)
   , .send_event = True
   , .display    = event->xselectionrequest.display
   , .requestor  = event->xselectionrequest.requestor
   , .selection  = event->xselectionrequest.selection
   , .target     = event->xselectionrequest.target
   , .property   = event->xselectionrequest.property
   , .time       = event->xselectionrequest.time
 }
};
-----[ END OF LINE ]-----

Yeah …

C99 has designated initializers and also allows trailing commas when
initializing structures, so the need for comma-first formatting doesn't
really apply here; comma-first formatting only really applies to function
calls. Perhaps languages should allow trailing commas in all contexts? It's
something to think about.

The rest of the article is really about marking items in a list with some
delimiter, usually a comma that comes after an item (except for the last
item). There's one example he brings up: “1 , 2 , 3” vs. “・1 ・2 ・3” and here,
I would say maybe “1 2 3” is best? Using spaces instead of a comma could
still work in a lot of contexts in C:

-----[ C ]-----
/* none of this is valid C code */
rc = cgi_error(blog req HTTP_BADREQ "bad request");
fprintf(
       stdout
       "Status: %s\r\nContent-type: text/html\r\n\r\n"
       status
);
generic_cb("main" stdout callback_init(&cbd blog req));
-----[ END OF LINE ]-----

It only breaks down when we go back to my first example above:

-----[ C ]-----
/* still not valid C code */
fprintf(
        stdout
        "Status: %d\r\n"
        "X-Error: %s\r\n"
        "Content-type: text/html\r\n"
        "\r\n"
        level
        errmsg
      );
-----[ END OF LINE ]-----

Consecutive string literals are collected together into a single string
literal, so such a construct as above could lead to some confusion. But this
is just me riffing on using space as a delimiter.

The rest of the article does lay out a decent argument for leading delimiters
for a lot of contexts, but removing closing brackets I think is too far. It
works for Python because of syntactic white space, but it won't work for
nearly any other language. It also fails for languages that support variadic
functions [3], so it's probably best to keep both opening and closing
brackets (or parenthesis or whatever). It also seems the arguments are more
for vertical than horizontal formatting.

The article ends with:

> Don’t be too surprised if this proposal evokes “hey this looks wrong, just
> plain wrong” reaction. After all, ideas we enjoy these days: enumeration
> from zero, using registers in names, structural programming, mandatory
> formatting, and even python’s approach to defining code blocks with
> indentation — every single one of them were met with a storm of criticism.
>

I'll keep that in mind, but even so, not everyone buys into mandatory
formatting or significant white space.

[1] https://arogozhnikov.github.io/2022/11/29/delimiter-comes-first.html
[2] https://lobste.rs/s/9q8rx2/delimiter_first_code
[3] https://en.wikipedia.org/wiki/Variadic_function

Email author at [email protected]