0
$\begingroup$

In most C-like languages, a call such as printf("%d", x) is followed by two parentheses; and I see that a statement such as return(x); would be ugly compared with return x;, but why is the inconsistency?

$\endgroup$
7
  • 1
    $\begingroup$ People write return statements with parenthesis as in return(0); all the time. (FYI, I prefer the simple and direct return 0;). Using parens when not necessary may come by habit from function calling, as well as maybe from other statements like if(x) and while(x), etc.., which require the parens in C & C-like languages. Some people back in the day transitioned from Pascal where these statements do not use parens, so I think when transitioning to C used both necessary and unnecessary parens. $\endgroup$ Commented Jul 11 at 18:03
  • 1
    $\begingroup$ Fun fact, there are a small number of places in C# where an expression is forbidden to be parenthesized. Due to small bugs in early versions of C#, if the entire returned expression was parenthesized, the compiler logically removed the parentheses. Those all became places where the rules about expressions that could not be parenthesized could be violated, oops. $\endgroup$ Commented Jul 14 at 22:53
  • 2
    $\begingroup$ Interestingly, VB6 takes this a step further: Subroutines do not use parentheses whereas function calls do use parentheses. $\endgroup$ Commented Jul 15 at 20:30
  • 2
    $\begingroup$ @Rāṣidu'l-Qamar, in VB6, a Function returns a value whereas a subroutine (keyword Sub) doesn't (although both can use ByRef parameters as out parameters). To be honest, the syntactical distinction always felt inconvenient and unnecessary to me (or vestigial of some predecessor concept in Basic that I'm not aware of). Iirc, this was ironed out in VB.NET - both kinds of call use parentheses for the argument list. $\endgroup$ Commented Jul 16 at 8:01
  • 1
    $\begingroup$ @Brian: Though that gets the gist of it across, the actual rules are bizarrely overcomplicated. See my 2003 article on the subject if you want the whole ridiculous story: ericlippert.com/2003/09/15/… $\endgroup$ Commented Jul 20 at 18:24

2 Answers 2

12
$\begingroup$

Parentheses are used to group arguments to a function. In the syntax that's common to most conventional programming languages, you need them so you can tell where the function arguments end if the function is part of a larger expression, e.g. sqrt(x) + 1.

return is not a function, it's a statement. In most languages, it can't be a subexpression. So there's no need to indicate where the parameter(s) end, they end at the end of the statement.

There are other ways to solve this problem. In Lisp, all statements are expressions, so everything is in parentheses. In APL, everything after the function name is arguments, you do grouping by putting the entire call inside parentheses. And in ML, functions only take one argument, so there's no need to indicate the end of arguments.

But putting function arguments in parentheses has a long history, it has been used at least since Fortran was created in the 50's.

$\endgroup$
3
  • 1
    $\begingroup$ In languages like ml, function calls just have the argument after the function: func arg, with no other punctuation needed. You only need to have parentheses to override the "normal" binding of infix operators -- such as when you use parens to combine multiple values into a single tuple, and then pass the tuple as the argument to the function: func ( val1, val2, val3 ). This looks like a function call with multiple arguments, but it is actually comma operators building a tuple. $\endgroup$ Commented Jul 9 at 20:34
  • 1
    $\begingroup$ Thanks, added that to my list of exceptions. $\endgroup$ Commented Jul 9 at 20:41
  • 9
    $\begingroup$ Long history indeed: FOR(mula)TRAN(slating system) took it from mathematics -- using parentheses for function arguments dates to Euler in 1740. $\endgroup$ Commented Jul 10 at 14:23
3
$\begingroup$

Just enriching @Barmar's answer here, in mathematics there is a long tradition of representing functions as f(x), said to date back at least to Euler in the 18th century - so it well precedes the era of programming languages.

The use of the comma , as an item separator has a less clear origin that I'm aware of, but seems to date at least as far back as the early 20th century in mathematics, such as in Ernst Zermelo's writings on set theory - and there is obvious correspondence with how three or more items are listed in plain English, too.

So in a language like C which has adopted a "function" concept with multiple arguments possible, then I don't think the choice of syntax needs much justification as it corresponds closely to contemporary mathematical notation and there doesn't seem to be a compelling alternative that was foregone.

As for why return x; doesn't use brackets, I think you'd have to note two things.

Firstly, only one result can be returned from the function in C, and therefore there cannot be the possibility of assembling an ad-hoc list of results - this eliminates the role of the brackets in grouping multiple items or disambiguating the use of the comma.

Secondly, C analyses the circumfix ( ) operator as being the call operator, and return is not a call in the conventional sense, but a reversion from an already extant call.

Other than perhaps making the syntax for return look vaguely functional-call-related, or perhaps finding an analogy in how an argument is passed to another context, there's not much reason why it should require brackets - any more so than the goto statement should require brackets around the target line label.

$\endgroup$
1
  • $\begingroup$ Good observation about return being the reversion of an extant call. Extrapolating from that, if anything, the most logical operator for a return call would be return )x(;. And that just looks ugly. $\endgroup$ Commented Sep 18 at 8:24

You must log in to answer this question.