2018-06-25 A simple hack with the comma operator and console.log

As we all know, console.log is the best debugging tool there is. I know, I know, it’s primitive, it’s slow (you have to insert it and run the program again, though that can be sped up) and it’s uncool to use it. Never mind.

There is one place, however, where it’s not easy to put a console.log (or console.dir, or similar stuff): arrow functions. Assume we have this code:

[1, 2, 3, 4, 5].map(x => x**2)

Assume that I want to insert a console.log(x) before returning the square of x in the arrow function above. Well, I have to first convert it to a “normal” function, and then put my stuff there:

[1, 2, 3, 4, 5].map(function(x) {
    return x**2;

Or do I?

Remember that JavaScript’s syntax is based on C, and we have the comma operator. Also, console.log is not a statement, but a function, so console.log(...) is an expression. Hence, we can do this:

[1, 2, 3, 4, 5].map(x => (console.log(x), x**2))

Notice that the parentheses around the compound expression console.log(x), x**2 are mandatory, since otherwise the x**2 is apparently interpreted as a second argument to Array.map. Unfortunately, the docs are rather, say, concise on this (lame pun intended). JavScript syntax could be better, I suppose. Still, I find this technique pretty useful.

Interestingly, it has a distinct functional feel to me. While Lisp is not (contrary to the common wisdom) a functional language, it has one important thing that makes functional programming so pleasant: in Lisp, there are no statements, and the program is a series of expressions. (That makes hacks like the ternary expression completely redundant – there is no “conditional statement” in Lisp at all.) The very existence of statements is IMHO one of the most annoying features of JavaScript and many other languages. Happily, console.log is a function (and the comma operator is essentially a progn), making this trick possible.

CategoryEnglish, CategoryBlog, CategoryJavaScript