Does any other language other than JavaScript have a difference between brace start locations (same line and next line)?
JavascriptLanguage AgnosticProgramming LanguagesLanguage DesignJavascript Problem Overview
Today, while I was randomly reading the JavaScript patterns O'Reilly book, I found one interesting thing (page 27 for reference).
In Javascript, in some cases, there is a difference if the brace start location is different.
function test_function1() {
return
{
name: 'rajat'
};
}
var obj = test_function1();
alert(obj); //Shows "undefined"
While
function test_function2() {
return {
name: 'rajat'
};
}
var obj = test_function2();
alert(obj); //Shows object
Does any other language out there have such behavior? If so, then I would have to change my habit for sure..:)
I am mainly concerned about PHP, C, C++, Java, and ruby.
Javascript Solutions
Solution 1 - Javascript
Any language that doesn’t rely on semicolons (but instead on newlines) to delimit statements potentially allows this. Consider Python:
>>> def foo():
... return
... { 1: 2 }
...
>>> def bar():
... return { 1: 2 }
...
>>> foo()
>>> bar()
{1: 2}
You might be able to construct a similar case in Visual Basic but off the top of my head I can’t figure out how because VB is pretty restrictive in where values may be placed. But the following should work, unless the static analyser complains about unreachable code:
Try
Throw New Exception()
Catch ex As Exception
Throw ex.GetBaseException()
End Try
' versus
Try
Throw New Exception()
Catch ex As Exception
Throw
ex.GetBaseException()
End Try
From the languages you mentioned, Ruby has the same property. PHP, C, C++ and Java do not simply because they discard newline as whitespace, and require semicolons to delimit statements.
Here’s the equivalent code from the Python example in Ruby:
>> def foo
>> return { 1 => 2 }
>> end
=> nil
>> def bar
>> return
>> { 1 => 2 }
>> end
=> nil
>> foo
=> {1=>2}
>> bar
=> nil
Solution 2 - Javascript
The JavaScript interpreter automatically adds a ;
at the end of each line if it doesn't find one (with some exceptions, not getting into them here :).
So basically the issue is not the braces' location (which here represent an object literal, not a code block as in most languages), but this little "feature" that forces your first example to return ;
=> undefined
. You can check out the behavior of return
in the ES5 spec.
For other languages that have similar behavior, check out Konrad's answer.
Solution 3 - Javascript
Most certainly. Google's go programming language exhibits a very similar behavior (albeit with different effects). As explained there:
>In fact, what happens is that the formal language uses semicolons, much as in C or Java, but they are inserted automatically at the end of every line that looks like the end of a statement. You don't need to type them yourself. > > ..snip... > >This approach makes for clean-looking, semicolon-free code. The one surprise is that it's important to put the opening brace of a construct such as an if statement on the same line as the if; if you don't, there are situations that may not compile or may give the wrong result. The language forces the brace style to some extent.
Secretly, I think Rob Pike just wanted an excuse to require the One True Brace Style.
Solution 4 - Javascript
The answer to that question is fairly easy. Any language that has "automatic semicolon insertion" might be in trouble on that line. The problem with this
return
{
name: 'rajat'
};
..is that the js engine will insert a semicolon after the return;
statement (and therefore, return undefined
). This example is a good reason to open curly brackets always on the right side and never on the left side also. Since you already correctly noticed, if there is a curly bracket in the same line, the interpretator will notice that and can't insert a semicolon.
Solution 5 - Javascript
FWIW, JSLint reports several warnings with that syntax:
$ jslint -stdin
function foo(){
return
{ x: "y" };
}
^D
(3): lint warning: unexpected end of line; it is ambiguous whether these lines are part of the same statement
return
........^
(3): lint warning: missing semicolon
{ x: "y" };
..^
(3): lint warning: unreachable code
{ x: "y" };
..^
(3): lint warning: meaningless block; curly braces have no impact
{ x: "y" };
..^
(3): lint warning: use of label
{ x: "y" };
.....^
(3): lint warning: missing semicolon
{ x: "y" };
...........^
(3): lint warning: empty statement or extra semicolon
{ x: "y" };
............^
0 error(s), 7 warning(s)
Solution 6 - Javascript
The first language where I came across this was awk (which also has its share of syntax "oddities"; optional semi colons, string concatenation using only whitespace and so on...) I think the DTrace designers, which based the D syntax loosely on awk, had enough sense to NOT copy these features, but I can't remember off the top of my head. A simple example (counting the number of ENTITY tags in a DTD, from my Mac):
$ cat printEntities.awk
# This prints all lines where the string ENTITY occurs
/ENTITY/ {
print $0
}
$ awk -f printEntities.awk < /usr/share/texinfo/texinfo.dtd | wc -l
119
If this little script instead were written with the brace on a line of its own, this is what would happen:
$ cat printAll.awk
# Because of the brace placement, the print statement will be executed
# for all lines in the input file
# Lines containing the string ENTITY will be printed twice,
# because print is the default action, if no other action is specified
/ENTITY/
{
print $0
}
$ awk -f printAll.awk < /usr/share/texinfo/texinfo.dtd | wc -l
603
$ /bin/cat < /usr/share/texinfo/texinfo.dtd | wc -l
484
$