Skip to main content
Ben Nadel at cf.Objective() 2017 (Washington, D.C.) with: Mike Sprague
Ben Nadel at cf.Objective() 2017 (Washington, D.C.) with: Mike Sprague ( @spraguey )

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

By
Published in Comments (4)

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

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

15,748 Comments

@Brad,

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.

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel