Skip to main content
Ben Nadel at cf.Objective() 2013 (Bloomington, MN) with: Nathan Deneau
Ben Nadel at cf.Objective() 2013 (Bloomington, MN) with: Nathan Deneau

Double-Parentheses ()() Requires Too Much Cognitive Load For My Brain

By on

I have no idea if this affects anyone else other than myself; but, when I see back-to-back sets of parentheses in the code, my brain just comes to a complete stop. Unlike so much other code, which I can picture with a simple, linear mental model, I feel like double-parentheses require me to branch off and hold parallel values in my head while simultaneously trying to understand control-flow. It may sound trivial, but it brings my machinery to a catastrophic stand-still.

To be clear, when I talk about double-parentheses, I am referring to code that immediately invokes the return value of another function. Code that looks like this:

  • require**(** "thing" )( options )
  • connect**(** thisthing )( thatthing )

And, it gets even worse if one of the function arguments is, itself, a function call. Code that looks like this:

  • withStuff**(** getthing**() )(** stuff )

At this point, my brain starts throwing parsing errors. I literally (with no exaggeration) have to skip over this block of code and just hope that I have a vague understanding of what it does as I continue to process the rest of the file in my head.

They say that in computer science there are only two hard things:

  • Naming
  • Cache Invalidation
  • Off-by-One Errors

I think part of why I struggle so much with the double-parenthesis is that I am forced to create a temporary name to hold the conceptual understanding of what the first parenthesis produces. Meaning, when I see code that looks like this:

connect**(** thisthing )( thatthing )

... my brain is actually trying to create an expression that looks more like this:

( var SOME_INTERMEDIARY_CONCEPT = connect( thisthing ) ).call( null, thatthing )

And that's where I stumble. With the name. With creating a name that portrays intent, usage, and functionality. With creating a name that makes sense and is informative. With creating a name that any other developer would understand if they had to read and maintain my mental syntax tree. With doing one of the hardest things in computer science - on-the-fly - while simultaneously trying to understand what the rest of the file is doing.

It's just something my brain doesn't do well. And, it's not like I don't have practice - this kind of code is prevalent in the JavaScript / Node.js community. I see it all the time. And, every time, I struggle. Of course, its prevalence is clear evidence that most people have no problem at all with this kind of code. Sometimes, I like to imagine that everyone else is crazy. But, in this context, I have to believe that I'm the crazy one.

Reader Comments


Glad that I am not the only person who has this problem and is not ashamed to admit it.

When I bump into curried functions I start to imagine all of the scopes and how they are maintaining state. Then I find myself with a notepad and a pen questioning my sanity. It's easier to say 'this bit of code seems fine' and move on. Ha!



Glad I'm in good company :) It could be my personal mental block; or, my personal experience bias; but, I feel like intermediary variables just make the code easier to read and reason about. It seems like nice thing to do for the "next" developer.