DEV Community

Cover image for A Compelling Case for the Comma Operator

A Compelling Case for the Comma Operator

Basti Ortiz on September 06, 2024

The comma operator is one of the lesser-known operators in C-like languages such as JavaScript and C++. Essentially, it delimits a sequence of expr...
Collapse
 
steve-oh profile image
Steve Schafer

I would say that, rather than a compelling case for the comma operator, your example is a compelling case for expression-based languages.

Collapse
 
somedood profile image
Basti Ortiz

You know, you make a very strong point. 😅

Collapse
 
goteguru profile image
Gergely Mészáros

My biggest concern would be that the form (a,b) exactly looks like a tuple used in almost every other languages (and even in mathematics). Using something what looks like a tuple but works like a hidden side-effect might cause confusion.

Collapse
 
somedood profile image
Basti Ortiz

That's a totally fair argument. I will have to agree with you on this one. If there's any reason to contest the comma operator in C-like languages, this would be it.

Collapse
 
buri profile image
Erich Buri

Here is an example where I use that operator on a regular basis - reduce!

Array with objects that have a unique id reduced to a map, indexed by id:

a.reduce((acc,item) => (acc[item.id]=item,acc),{})

It’s more efficient than:
a.reduce((acc,item)=>({…acc,[item.id]:item}),{})

Collapse
 
somedood profile image
Basti Ortiz

I do understand the appeal of one-liners, but how do you feel about this refactor?

a.reduce((acc, item) => {
    acc[item.id] = item;
    return acc;
});
Enter fullscreen mode Exit fullscreen mode

I personally prefer it this way—albeit a bit more verbose than yours. I'd love to know your thoughts on that.

Collapse
 
goteguru profile image
Gergely Mészáros

Your example is basically a map, therefore not very useful (not clean) to implement it with reduce. Just do: Object.fromEntries(a.map(x=>[x.id,x]))
However valid point, I can imagine situations where it is useful.

Collapse
 
somedood profile image
Basti Ortiz

Oh, right! That is definitely much prettier than the reduce. Thanks for calling it out. 👏

Collapse
 
docbok profile image
Mark David Robert McDonagh

This feels like a corner case using a rarely used solution, and is only going to confuse other developers, especially juniors. This would likely lead to an organisation banning comma operators in their coding standards.

Collapse
 
somedood profile image
Basti Ortiz

I could see that being the case. Though I'd like to clarify that I never advocated for its use everywhere. I was careful to note that readable code must be tasteful.

That's why my compromise is to only allow at most three inlined statements. That's what I've found to be the perfect balance between readability and bewilderment.

I think outright banning the syntax is counter-productive when the pattern can effectively and concisely communicate the intent of the code. It's like forcing crutches on us.

Instead of keeping ourselves away from these patterns, let's educate others (especially the juniors) on their proper and responsible use. Hence, I believe that banning the syntax only perpetuates the confusion around the comma operator. I find that unfortunate.

Collapse
 
martinbaun profile image
Martin Baun

The only thing I've used the comma operator for is writing a "clever" macro to track where a variable is getting used :P

Collapse
 
somedood profile image
Basti Ortiz

Some people at Twitter also had the same sentiment. The C macro ecosystem never fails to astound me. 😅

Collapse
 
martinbaun profile image
Martin Baun

Haha! Very interesting :D

Collapse
 
goteguru profile image
Gergely Mészáros

fun fact: (,) operator corresponds to flip const in Haskell. Unfortunately without partial application and lazy evaluation it has few true use cases. (Otherwise it has many).

Collapse
 
a4z profile image
Harald

In some languages, it's even possible to have some fun with the comma operator

Collapse
 
somedood profile image
Basti Ortiz

This is so cursed. I love it!

Collapse
 
pauljlucas profile image
Paul J. Lucas

If you do something like:

int n = (f(), 42);
Enter fullscreen mode Exit fullscreen mode

in either C or C++, many compilers will warn you that the value of the left-hand operand of , is discarded. To silence the warning, you need to cast it to (void).

That aside, cramming stuff into an expression and using , just makes for unclear code. Just use an if-else instead.

BTW, you missed the obvious primary use-case for , (at least in C or C++) which is inside a for:

for ( int i = 0, j = 0; i < m && j < n; ++i, ++j ) {
    // ...
}
Enter fullscreen mode Exit fullscreen mode

where the second , is the comma operator and separates the ++i and ++j.

Collapse
 
somedood profile image
Basti Ortiz • Edited

Ah yes, that's true. I did omit that use case because I found it to be less compelling than the emulation of expression-based conditionals as in other programming languages. Though I will not deny that your example is pretty neat and useful, especially for zip-like operations.

That aside, cramming stuff into an expression and using , just makes for unclear code. Just use an if-else instead.

Yes, I agree, but I have raised my arguments against this: the primary one being uninitialized variables whose initialization is far detached from the declaration. If the only safe1 viable alternative for this is the comma operator (as shown in the article), then I'm all for it!

That's why for less than three inlined statements, I find the comma operator quite useful and readable for conditional ternaries. Anything more than that, though, is dubious construction that is worth refactoring into dedicated functions or otherwise. The if-else construction would honestly be my absolutely last resort.


  1. By "safe", I mean code that is less likely for us now, us in the future, other developers now, and other developers in the future to forget to initialize the variable in all branches. 

Collapse
 
donangel profile image
Doncho Angelov

It's a good article, in the sense that it describes how to write more cryptic code.

As a C++ developer for more than 30 years, I've always prioritized reading and understanding the code over the shortness of the expression.

How quick it is to read and understand the code is way more important than the shortness of the expression. And that's valid for more than 95% (number from the top of my head) of the production code, especially bearing in mind that the compilers are excellent in the optimization of "well written, but more descriptive than short" code.

Collapse
 
somedood profile image
Basti Ortiz

I understand where you're coming from, which is why I limited my usage of it to at most three inlined statements.

Working within the context of conditional ternary expressions, let's consider the alternatives: (1) if statements with variable initialization far detached from the declaration and (2) ad hoc functions that encapsulate multiple statements.

Frankly, I will always reject (1) because of how bug-prone it is as I've argued in the article. I'm willing to accept (2), but if one must write three-line ad hoc functions just to work around the comma operator, I think that's poor practice.

And so considering all other alternatives, this is how I reached my conclusion in the article. I strongly disagree that it's "cryptic code" (especially when we cap it at three inlined statements) because the alternatives are either bug-prone as in (1) or cumbersome as in (2). The comma operator can get the job done clearly and concisely in this happy medium.

Collapse
 
awschult002 profile image
awschult002

I use the ternary all of the time. Is one of my favorites for simplifying an expression.

However, there is one scenario that comes up a lot that I haven't been able to held and that is conditionally executing a function that doesn't return a value, thus no final assignment.

I would really like to see a clean ternary expression like you show, but without the need to assign a final value.

Collapse
 
somedood profile image
Basti Ortiz

I'd like to see a code example. Why wouldn't an if statement suffice?