Mozilla states expressions are also statements. Why? - javascript

Looking at these articles from Mozilla's JavaScript guide:
Expressions
Statements
expressions are also considered assignment statements. In fact, in the second article one can read "any expression is also a statement". Being acquainted with other programming languages, I thought that expressions are always values, but they never cause side effects like statements would do. In other words, 7, 7 + 8, "string", etc., are expressions, because they don't change the state, but a = 7 is a statement, since a variable has now been defined (i.e. a state has changed).
Why would Mozilla not differentiate between the two in JS?

I believe you are taking the terms "expression" and "statement" too literally. "Expressions not changing any state" is a very tough requirement for a programming language.
A thought experiment: In 7 + 8 substitute 8 with a function call to
var globalVar = 0;
function my8() {
globalVar = globalVar + 1;
return 8;
}
Is 7 + my8() a statement or an expression? There is no obvious state change happing here, but still my8 performs a state change. Using the "no side-effects" definition it would be impossible to decide if 7 + my8() is a statement or an expression without analyzing the code of the my8 function. Of course it would be possible to simply prohibit any state change as part of a function call, but that is not the way of JavaScript.
In my experience most languages define "everything which returns a value" as an expression and a statement, everything else as just a statement.
To answer your question "Why would Mozilla not differentiate between the two in JS?":
I think they do, but not in the manner you expected. To consider "everything which returns a value" an expression seems to be the most practical approach.
Also there is no contradiction between a chunk of code being a statement and an expression at the same time. That is simply how Javascript and many other languages work. Of course it is always possible to draw a more strict line between those two.
Examples:
Assignments return values, so this is possible:
a = b = c = 1;
It can be written in the more obvious form:
a = (b = (c = 1));
Because of that an assignment is considered an expression (and also a statement).
On the other hand:
if (true) { };
does not return a value (in Javascript!) and therefore is no expression (but still a statement).

An expression is a code fragment that returns some value, Expression (Computer Science):
3; // 3
{}; // Object
func(); // whatever func returns, or undefined if not specified
You can combine expressions into one compound expression:
3 + 7; // 10
{}, []; // Array. Comma operator always returns result of right-most expression
A statement is the smallest valid code fragment that can be compiled or interpreted, Statement (Computer Science):
5; // valid js
You can also combine statements into compound statements:
check || func(); // valid js
{
4 + 9;
"block statement";
}
In the Mozilla documentation, a statement refers to any (compound) statement that is explicitly or implicitly terminated by semi-colon (;).
[,,[],[,[,,],,]]; // Array declaration whose reference is returned (and ignored)
// Multi-dimensional array with empty (undefined) elements
In some programming languages the above example doesn't compile or doesn't get interpreted. Other languages might not allow for the result of an expression not to be catched.
Javascript is very expressive, which is why every expression counts as a valid statement. Some statements are not expressions, like break, return, while, etc. They don't return any value, but they control the program execution flow.

Mozilla does differentiate between the two, or rather the Javascript syntax does.
The only slightly "special" about Javascript is the following:
"any expression is also a statement",
which means that at places where a statement is required in the syntax, an expression can be used directly (but not the other way around). E.g. the following is valid Javascript but invalid in many other similar languages:
if (true) "asfd"
or
foo = function(){
if (5) {
"some text here that won't do anything";
return true;
42; // always good to have that one here!
}
}
whereas statements cannot be used as expressions:
a = (if (true) 5) // does not work "unexpected token 'if'"
They used that "feature" for the strict mode specification without introducing a new keyword or syntax - if you add the expression "use strict" as the first statement in a function body, Javascript is executed in strict mode in supporting browsers.
While expressions evaluate to a value, usually, statements do not. Most statements alter control flow, expressions usually don't (although one could argue that an expression that results in an exception being thrown alters control flow, too).
In Javascript expressions form a subset of all statements.

Related

Testing out my understanding of expressions and statements with two examples [duplicate]

For the past few hours I have been trying to find the difference between the 3, not just the difference, I also have been trying to find out which are sort of synonymous, MDN calls all declarations "statements", so I presume that is true. However, none of the articles and SO questions I read provided me with a cheatsheet of sorts to distinguish between the 3 (or the 2, expressions vs statements).
Something I have noticed with statements is that they all somehow involve a special JavaScript keyword like break or for or var. The articles say that an expression evaluates to something, while a statement performs an action. What is a function then ? Is it a statement-expression hybrid (since it both performs an action when called, and returns a value) ? Right now, I am assuming that this is not the case since a function call does not involve a JavaScript keyword.
And then there are declarations, is every declaration also a statement ?
I am also aware of expression statements like 20 + 5 * 2 / 3;, but aren't these virtually useless ? Why would anyone pollute their code with a line like this ?
I would be more than glad if someone could ask the above questions (or at least some of them), or if someone could provide me with some sort of a cheatsheet. Why is there so little material on a topic that appears to be so simple in such a popular language ?
There are standard definitions of these terms that all languages, including JS, follow. My takes on them are the following:
An expression produces a value and can be written wherever a value is expected.
A statement on the other hand is is a standalone unit of execution. It does not return anything.
A declaration is a statement in which a value is assigned to a variable.
All declarations are statements, but not all statements are declarations.
Most statements and all declarations contain expressions.
Javadoc also gives nice, succinct definitions:
An expression is a construct made up of variables, operators, and method invocations, which are constructed according to the syntax of the language, that evaluates to a single value.
Statements are roughly equivalent to sentences in natural languages. A statement forms a complete unit of execution.
Now, your theory on keywords being necessarily involved is incorrect. Here is a statement that includes a keyword:
break;
And here is one that does not:
foo();
In the first example I execute a break, whereas in the second one I call a function. Both are statements, however only one includes any special keyword.
A function is not a statement. A function call is a statement, as demonstrated above. In the case of a function that returns something, the call can also be a declaration:
var bar = foo();
And for your final question, the reason there is so little material out there on this is because this is merely an issue of semantics. People do not linger on the exact definitions of these terms.
For further clarification, I recommend taking a look at this blog post by Axel Rauschmayer that specifically talks about the difference between statements and expressions in JS.
For the past few hours I have been trying to find the difference between the 3, not just the difference, I also have been trying to find out which are sort of synonymous, MDN calls all declarations "statements", so I presume that is true.
A declaration is any construct that "declares" a variable name into existence at compile/load time before the program executes. All declared names in their respective scopes are therefore known in advance.
Statements and expressions differ from each other in that the former does not produce a value a result, whereas the latter does. So an expression may be used anywhere a value is expected, and a statement may not be used in those places.
An expression statement is one where the statement is a single expression, or several included in an expression that requires zero or more sub-expressions. While the expression(s) produce a result, the statement does not.
Here's an expression:
x = foo() + 2
A full expression statement could be explicitly shown by adding a semicolon to the end.
x = foo() + 2;
The first example can be wrapped in a set of parens, because the parens as a grouping operator expects an expression, often provided as several expressions joined by the comma operator.
The second example can not be wrapped in parens (if you include the semicolon) because then it is a statement, and does not produce a value, which the grouping operator expects to receive and return as its own value.
Something I have noticed with statements is that they all somehow involve a special JavaScript keyword like break or for or var.
While most statements do involve a keyword, not all do. Most notably, the block statement has no keyword. Instead it uses a set of curly braces to delimit its start and end.
The articles say that an expression evaluates to something, while a statement performs an action. What is a function then ? Is it a statement-expression hybrid (since it both performs an action when called, and returns a value) ? Right now, I am assuming that this is not the case since a function call does not involve a JavaScript keyword.
There are three kinds of functions in JS. If you're talking about the ones that use the function keyword, then the may be either a declaration or an expression depending on its context.
If the function is used where an expression would be expected, then it's evaluated as an expression that returns a new function object. If not, then it is expected to be a declaration, which basically creates a variable with the function object assigned to it. As a declaration, a function name is required (for the variable name). As an expression, it's optional.
I am also aware of expression statements like 20 + 5 * 2 / 3;, but aren't these virtually useless ? Why would anyone pollute their code with a line like this ?
If the resulting value is ignored, it would be useless, given that example. But here's another expression statement.
foobar();
Now we have a side effect from the function call, which is most likely desired and useful.
Let's talk about expressions first. As you say, an expression is something that evaluates to a value. A function is a value. A function call, on the other hand, is an expression.
I don't agree with the characterization of a statement as something that "performs an action". As you say, calling a function involves running the function body, which consists of statements and declarations, so it performs actions "on the inside".
A better way to look at it is that expressions, statements, and declarations are syntactic categories. They arise from trying to describe the structure of the JavaScript grammar. See e.g. the ECMAScript 8 specification on expressions, statements, and declarations.
An expression statement like 20 + 5 * 2 / 3; is indeed useless because it has no effects, and the only point of a statement is its effects. But there are other kinds of much more useful expression statements:
a function call: foo();
assignment: x = 42; (= is an operator and can be used in expressions)
increment/decrement: i++; (similarly, ++ is an operator)
Statements other than expression statements tend to start with a special keyword to avoid syntactic ambiguity: The parser wants to be able to tell what kind of construct it is dealing with right from the start. Hence we get:
if statements: if (EXPR) STMT
while statements: while (EXPR) STMT
return statements: return; or return EXPR;
etc.
However, there are some statements that don't start with a keyword:
the empty statement: ;
a block: { ... }
Finally, declarations. In JavaScript the distinction between statements and declarations is somewhat arbitrary. The grammar distinguishes between the two, but in practice you can often treat them the same (e.g. the contents of a block statement are defined as a sequence of statement list items, and a statement list item is defined to be either a statement or a declaration). Declarations include:
function declarations: function foo() { ... } (including variants such as generators (function* foo() { ... }) and asynchronous functions (async function foo() { ... }))
let and const
class declarations
(But for some reason var foo; is classified as a statement, not a declaration.)

Why doesn't logical OR work with error throwing in JavaScript?

This is a pretty common and useful practice:
// default via value
var un = undefined
var v1 = un || 1
// default via a function call
var myval = () => 1
var v2 = un || myval()
But it doesn't work (SyntaxError) when throwing an error:
var v3 = un || throw new Error('un is not set!')
Is there a way how to achieve the same effect in a similarly elegant way?
This is IMHO a lot of boilerplate code:
if (!un) {
throw new Error('un is not set!')
}
var v3 = un
Or is there any theoretical obstruction, why this is not, and never will be, possible?
throw is a statement only; it may not exist in a position where an expression is required. For similar reasons, you can't put an if statement there, for example
var something = false || if (cond) { /* something */ }
is invalid syntax as well.
Only expressions (things that evaluate to a value) are permitted to be assigned to variables. If you want to throw, you have to throw as a statement, which means you can't put it on the right-hand side of an assignment.
I suppose one way would be to use an IIFE on the right-hand side of the ||, allowing you to use a statement on the first line of that function:
var un = undefined
var v2 = un || (() => { throw new Error('nope') })();
But that's pretty weird. I'd prefer the explicit if - throw.
Your problem is that an assignment expects an expression but you give it a statement
The Syntax for initializing/assigning a variable is:
var|let|const <variableName> = <expression>
but you use
var|let|const <variableName> = <statement>
which is invalid Syntax.
Expressions
An expression is something that produces a value.
What is a "value"?
A value is anything that is a type in Javascript
Numbers
Strings
Booleans
Objects
Arrays
Symbols
Examples for Expressions:
Literals
var x = 5;
x is assigned the value "5"
A function call
var x = myFunc();
myFunc() produces a value that is assigned to x
The produced value of a function is its return value - A function always returns, and if it doesn't explicitly, it returns undefined.
Functions have the added benefit of being able to contain statements in their body - Which will be the solution to your question - But more on that later.
Statements
A statement is something that performs an action. For Example:
A loop
for (var i = 0; i < 10; i++) { /* loop body */ }
This loop performs the action of executing the loop body 10 times
Throwing an error
throw new Error()
Unwinds the stack and stops the execution of the current frame
So why can't we mix both?
When you want to assign to a variable, you want an expression because you want the variable to have a value.
If you think about it, it should be clear that it will never work with a statement. Giving a variable an "action" is nonsense. What is that even supposed to mean?
Therefore you cannot use the throw statement since it does not produce a value.
You can only have one or the other.
Either you are (expression) something or you do (statement) something.
A fix
You can convert any statement into an expression by wrapping it in a function, I suggest using an IIFE (Immediately invoked function expression) - basically a function that invokes itself - to do just that
var x = 5 || (() => throw new Error())()
This works because the right side is now a function and a function is an expression which produces a value, The value is undefined in this case, but since we stop executing it doesnt matter anyways.
Future Possibilities
Technically there is nothing that prevents this from working.
Many languages (c++, ...) actually already treat throw as an expression. Some (kotlin, ...) even leave out statements completely and treat everything as an expression.
Others (c#, php, ...) provide workarounds like the ?? null-concealing or ?. elvis operator to solve this very use case.
Maybe in the future we get one of those features into the ecmascript standard (there is even an open proposal to include this) until then your best bet is to use a function like:
function assertPresent(value, message)
{
if(!value) {
throw new Error(message);
} else {
return value;
}
}
You could move the throwing of the exception into a function, because throw is a statement of control flow, and not an expression:
An expression is any valid unit of code that resolves to a value.
const throwError = function (e) { throw new Error(e); };
var un = undefined,
v3 = un || throwError('un is not set!');
As other answers have stated, it is because throw is a statement, which can't be used in contexts which expect expressions, such as on the right side of a ||. As stated by others, you can get around that by wrapping the exception in a function and immediately calling it, but I'm going to make the case that doing so is a bad idea because it makes your intent less clear. Three extra lines of code is not a big deal for making the intent of your code very clear and explicit. I personally think that throw being statement-only is a good thing because it encourages writing more straightforward code that is less likely to cause other developers to scratch their heads when encountering your code.
The || defaulting idiom is useful when you want to provide default or alternative values for undefined, null, and other falsy values, but I think it loses a lot of its clarity when used in a branching sense. By "branching sense", I mean that if your intent is to do something if a condition holds (the doing something in this case being throwing an exception), then condition || do_something() is really not a clear way to express that intent even though it is functionally identical to if (!condition) {do_something()}. Short-circuit evaluation isn't immediately obvious to every developer and || defaulting is only understood because it's a commonly-used idiom in Javascript.
My general rule of thumb is that if a function has side effects (and yes, exceptions count as side effects, especially since they're basically non-local goto statements), you should use an if statement for its condition rather than || or &&. You're not golfing.
Bottom line: which is going to cause less confusion?
return value || (() => {throw new Error('an error occurred')})()
or
if (!value) {
throw new Error('an error occurred')
}
return value
It's usually worth it to sacrifice terseness for clarity.
Like others have said the problem is that throw is a statement and not an expression.
There is however really no need for this dichotomy. There are languages where everything is an expression (no statements) and they're not "inferior" because of this; it simplifies both syntax and semantic (e.g. you don't need separate if statements and the ternary operator ?:).
Actually this is just one of the many reasons for which Javascript (the language) kind of sucks, despite Javascript (the runtime environment) being amazing.
A simple work-around (that can be used also in other languages with a similar limitation like Python) is:
function error(x) { throw Error(x); }
then you can simply write
let x = y.parent || error("No parent");
There is some complexity in having throw as an expression for statically typed languages: what should be the static type of x() ? y() : throw(z)?; for example C++ has a very special rule for handling a throw expression in the ternary operator (the type is taken from the other branch, even if formally throw x is considered an expression of type void).

JavaScript: declarations vs expressions vs statements

For the past few hours I have been trying to find the difference between the 3, not just the difference, I also have been trying to find out which are sort of synonymous, MDN calls all declarations "statements", so I presume that is true. However, none of the articles and SO questions I read provided me with a cheatsheet of sorts to distinguish between the 3 (or the 2, expressions vs statements).
Something I have noticed with statements is that they all somehow involve a special JavaScript keyword like break or for or var. The articles say that an expression evaluates to something, while a statement performs an action. What is a function then ? Is it a statement-expression hybrid (since it both performs an action when called, and returns a value) ? Right now, I am assuming that this is not the case since a function call does not involve a JavaScript keyword.
And then there are declarations, is every declaration also a statement ?
I am also aware of expression statements like 20 + 5 * 2 / 3;, but aren't these virtually useless ? Why would anyone pollute their code with a line like this ?
I would be more than glad if someone could ask the above questions (or at least some of them), or if someone could provide me with some sort of a cheatsheet. Why is there so little material on a topic that appears to be so simple in such a popular language ?
There are standard definitions of these terms that all languages, including JS, follow. My takes on them are the following:
An expression produces a value and can be written wherever a value is expected.
A statement on the other hand is is a standalone unit of execution. It does not return anything.
A declaration is a statement in which a value is assigned to a variable.
All declarations are statements, but not all statements are declarations.
Most statements and all declarations contain expressions.
Javadoc also gives nice, succinct definitions:
An expression is a construct made up of variables, operators, and method invocations, which are constructed according to the syntax of the language, that evaluates to a single value.
Statements are roughly equivalent to sentences in natural languages. A statement forms a complete unit of execution.
Now, your theory on keywords being necessarily involved is incorrect. Here is a statement that includes a keyword:
break;
And here is one that does not:
foo();
In the first example I execute a break, whereas in the second one I call a function. Both are statements, however only one includes any special keyword.
A function is not a statement. A function call is a statement, as demonstrated above. In the case of a function that returns something, the call can also be a declaration:
var bar = foo();
And for your final question, the reason there is so little material out there on this is because this is merely an issue of semantics. People do not linger on the exact definitions of these terms.
For further clarification, I recommend taking a look at this blog post by Axel Rauschmayer that specifically talks about the difference between statements and expressions in JS.
For the past few hours I have been trying to find the difference between the 3, not just the difference, I also have been trying to find out which are sort of synonymous, MDN calls all declarations "statements", so I presume that is true.
A declaration is any construct that "declares" a variable name into existence at compile/load time before the program executes. All declared names in their respective scopes are therefore known in advance.
Statements and expressions differ from each other in that the former does not produce a value a result, whereas the latter does. So an expression may be used anywhere a value is expected, and a statement may not be used in those places.
An expression statement is one where the statement is a single expression, or several included in an expression that requires zero or more sub-expressions. While the expression(s) produce a result, the statement does not.
Here's an expression:
x = foo() + 2
A full expression statement could be explicitly shown by adding a semicolon to the end.
x = foo() + 2;
The first example can be wrapped in a set of parens, because the parens as a grouping operator expects an expression, often provided as several expressions joined by the comma operator.
The second example can not be wrapped in parens (if you include the semicolon) because then it is a statement, and does not produce a value, which the grouping operator expects to receive and return as its own value.
Something I have noticed with statements is that they all somehow involve a special JavaScript keyword like break or for or var.
While most statements do involve a keyword, not all do. Most notably, the block statement has no keyword. Instead it uses a set of curly braces to delimit its start and end.
The articles say that an expression evaluates to something, while a statement performs an action. What is a function then ? Is it a statement-expression hybrid (since it both performs an action when called, and returns a value) ? Right now, I am assuming that this is not the case since a function call does not involve a JavaScript keyword.
There are three kinds of functions in JS. If you're talking about the ones that use the function keyword, then the may be either a declaration or an expression depending on its context.
If the function is used where an expression would be expected, then it's evaluated as an expression that returns a new function object. If not, then it is expected to be a declaration, which basically creates a variable with the function object assigned to it. As a declaration, a function name is required (for the variable name). As an expression, it's optional.
I am also aware of expression statements like 20 + 5 * 2 / 3;, but aren't these virtually useless ? Why would anyone pollute their code with a line like this ?
If the resulting value is ignored, it would be useless, given that example. But here's another expression statement.
foobar();
Now we have a side effect from the function call, which is most likely desired and useful.
Let's talk about expressions first. As you say, an expression is something that evaluates to a value. A function is a value. A function call, on the other hand, is an expression.
I don't agree with the characterization of a statement as something that "performs an action". As you say, calling a function involves running the function body, which consists of statements and declarations, so it performs actions "on the inside".
A better way to look at it is that expressions, statements, and declarations are syntactic categories. They arise from trying to describe the structure of the JavaScript grammar. See e.g. the ECMAScript 8 specification on expressions, statements, and declarations.
An expression statement like 20 + 5 * 2 / 3; is indeed useless because it has no effects, and the only point of a statement is its effects. But there are other kinds of much more useful expression statements:
a function call: foo();
assignment: x = 42; (= is an operator and can be used in expressions)
increment/decrement: i++; (similarly, ++ is an operator)
Statements other than expression statements tend to start with a special keyword to avoid syntactic ambiguity: The parser wants to be able to tell what kind of construct it is dealing with right from the start. Hence we get:
if statements: if (EXPR) STMT
while statements: while (EXPR) STMT
return statements: return; or return EXPR;
etc.
However, there are some statements that don't start with a keyword:
the empty statement: ;
a block: { ... }
Finally, declarations. In JavaScript the distinction between statements and declarations is somewhat arbitrary. The grammar distinguishes between the two, but in practice you can often treat them the same (e.g. the contents of a block statement are defined as a sequence of statement list items, and a statement list item is defined to be either a statement or a declaration). Declarations include:
function declarations: function foo() { ... } (including variants such as generators (function* foo() { ... }) and asynchronous functions (async function foo() { ... }))
let and const
class declarations
(But for some reason var foo; is classified as a statement, not a declaration.)

Why is `(foo) = "bar"` legal in JavaScript?

In Node.js's REPL (tested in SpiderMonkey as well) the sequence
var foo = null;
(foo) = "bar";
is valid, with foo subsequently equal to "bar" as opposed to null.
This seems counterintuitive because one would think the parenthesis would at least dereference bar and throw Invalid left-hand side in assignment`.
Understandably, when you do anything interesting it does fail in aforementioned way.
(foo, bar) = 4
(true ? bar : foo) = 4
According to ECMA-262 on LeftHandExpressions (so far as I can interpret) are no valid non-terminals that would lead to a parenthetical being accepted.
Is there something I'm not seeing?
It's valid indeed. You're allowed to wrap any simple assignment target in parenthesis.
The left hand part of the = operation is a LeftHandSideExpression as you correctly identified. This can be tracked down through the various precendence levels (NewExpression, MemberExpression) to a PrimaryExpression, which in turn might be a Cover­Parenthesized­Expression­And­Arrow­Parameter­List:
( Expression[In, ?Yield] )
(actually, when parsed with target PrimaryExpression, it's a ParenthesizedExpression).
So it's valid by the grammar, at least. Whether it's actually valid JS syntax is determined by another factor: early error static semantics. Those are basically prose or algorithmic rules that make some production expansions invalid (syntax errors) in certain cases. This for example allowed the authors to reuse the array and object initialiser grammars for destructuring, but only applying certain rules. In the early errors for assignment expressions we find
It is an early Reference Error if LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral and IsValidSimpleAssignmentTarget of LeftHandSideExpression is false.
We can also see this distinction in the evaluation of assignment expressions, where simple assignment targets are evaluated to a reference that can be assigned to, instead of getting the destructuring pattern stuff like object and array literals.
So what does that IsValidSimpleAssignmentTarget do to LeftHandSideExpressions? Basically it allows assignments to property accesses and disallows assignments to call expressions. It doesn't state anything about plain PrimaryExpressions which have their own IsValidSimpleAssignmentTarget rule. All it does is to extract the Expression between the parentheses through the Covered­Parenthesized­Expression operation, and then again check IsValidSimpleAssignmentTarget of that. In short: (…) = … is valid when … = … is valid. It'll yield true only for Identifiers (like in your example) and properties.
As per #dlatikay's suggestion, following an existing hunch, research into CoveredParenthesizedExpression yielded a better understanding of what's happening here.
Apparently, the reason why a non-terminal cannot be found in the spec, to explain why (foo) is acceptable as a LeftHandExpression, is surprisingly simple. I'm assuming you understand how parsers work, and that they operate in two separate stages: Lexing and Parsing.
What I've learned from this little research tangent is that the construct (foo) is not technically being delivered to parser, and therefor the engine, as you might think.
Consider the following
var foo = (((bar)));
As we all know, something like this is perfectly legal. Why? Well you visually can just ignore the parenthesis while the statement remains making perfect sense.
Similarly, here is another valid example, even from a human readability perspective, because the parentheses only explicate what PEMDAS already makes implicit.
(3 + ((4 * 5) / 2)) === 3 + 4 * 5 / 2
>> true
One key observation can be loosely derived from this, given an understanding of how parsers already work. (remember, Javascript still is being parsed (read: compiled) and then run) So in a direct sense, these parentheses are "stating the obvious".
So all that being said, what exactly is going on?
Basically, parentheses (with the exception of function parameters) are collapsed into proper groupings of their containing symbols. IANAL but, in lay man's terms, that means that parentheses are only interpreted to guide the parser how to group what it reads. If the context of the parentheses is already "in order", and thus does not require any tweaking of the emitted AST, then the (machine) code is emitted as if those parentheses did not exist at all.
The parser is more or less being lazy, assuming the parens are impertinent. (which in this edge-case, is not true)
Okay, and where exactly is this happening?
According to 12.2.1.5 Static Semantics: IsValidSimpleAssignmentTarget in the spec,
PrimaryExpression: (CoverParenthesizedExpressionAndArrowParameterList)
Let expr be CoveredParenthesizedExpression of CoverParenthesizedExpressionAndArrowParameterList.
Return IsValidSimpleAssignmentTarget of expr.
I.E. If expecting primaryExpression return whatever is inside the parenthesis and use that.
Because of that, in this scenario, it does not convert (foo) into CoveredParenthesizedExpression{ inner: "foo" }, it converts it simply into foo which preserves the fact that it is an Identifier and thus syntactically, while not necessarily lexically, valid.
TL;DR
It's wat.
Want a little more insight?
Check out #Bergi's answer.

Difference between statement and function

It's almost midnight and I just got a question in my head is "for loop" a statement or a function.
I always thought it is a statement, but I did a google search on it being a function and there are indeed results for that. So what is it? And in that case what is the difference between function and statement?
A for loop is a not usually a function, it is a special kind of statement called a flow control structure.
A statement is a command. It does something. In most languages, statements do not return values. Example:
print "Hello World"
A function is a subroutine that can be called elsewhere in the program. Functions often (but not necessarily) return values. Example:
function(a) { return a * 2 }
A control structure, also known as a compound statement, is a statement that is used to direct the flow of execution. Examples:
if (condition) then { branch_1 } else { branch_2 }
for (i = 0; i < 10; i += 1) { ... }
Also worth noting is that an expression is a piece of code that evaluates to a value. Example:
2 + 2
All examples are in pseudocode, not tied to any particular language. Also note that these are not exclusive categories, they can overlap.
Out of the three language tags you've chosen, I'm only very familliar with Python, but I believe many other languages have a similar view of these concepts. All the example code here is Python.
A statement is a thing that is executed; an "instruction to do something" that the language implementation understands. e.g.
print "Hello World"
pass
def foo(n):
return n + 1
if condition:
print 'yay'
else:
print 'doh'
The above block contains a print statement, a pass statement, a function definition statement, and an if/else statement. Note that the function definition and the if/else statement are compound statements; they contain other statements (possibly many of them, and possibly other compound statements).
An expression is something that can be evaluated to produce a value. e.g.
1
"foo"
2 * 6
function(argument)
None
The above contains a numeric literal expression, a string literal expression, an expression involving numeric operators, a function call expression, and the literal None expression. Other than literals and variables, expressions are made up of other expressions. In function(argument), function and argument are also both expressions.
The key difference is that statements are instructions that tell the language implementation to "go do something". Expressions are evaluated to a value (which possibly requires to language implementation to "go do something" on the way).
A consequence of this is that anywhere you see a value (including an expression), you could substitute any other expression and you would still get something that makes some sort of sense. It may fail to compile, or throw exceptions at runtime, or whatever, but on at least some level you can understand what's going on.
A statement can never appear inside an expression (I believe this is not true in Ruby and Javascript in some sense, as they allow literal code blocks and functions which are then used as a value as a whole, and functions and code blocks contain statements; but that's kind of different from what I'm talking about). An expression must have a value (even if it's an uninteresting one like None). A statement is a command; it doesn't make sense for it to appear as part of an expression, because it has no value.
Many languages also allow expressions to be used as statements. The usual meaning of this is "evaluate this expression to get a value, then throw it away". In Python, functions that always return None are usually used this way:
write_to_disk(result)
It's used as a "command", so it looks like a statement, but technically it's an expression, we just don't use the value it evaluates to for anything. You can argue that a "bare expression" is one of the possible statements in a language (and they're often parsed that way).
Some languages though distinguish between functions that must be used like statements with no return value (often called procedures) and functions that are used like an expression, and give you errors or warnings for using a function like a statement, and definitely give you an error for using a procedure as an expression.
So, if foo is an expression, I can write 1 + foo and while it may be result in a type error, it at least makes that much sense. If foo is a statement, then 1 + foo is usually a parse error; the language implementation won't even be able to understand what you're trying to say.
A function on the other hand, is a thing you can call. It's not really either an expression or a statement in itself. In Python, you use a def statement to create a function, and a function call is an expression. The name bound to the function after you create it is also an expression. But the function itself is a value, which isn't exactly an expression when you get technical, but certainly isn't a statement.
So, for loops. This is a for loop in Python:
for thing in collection:
do_stuff(thing)
Looks like a statement (a compound statement, like an if statement). And to prove it, this is utterly meaningless (and a parse error):
1 + for thing in collection:
do_stuff(thing)
In some languages though, the equivalent of a for loop is an expression, and has a value, to which you can attempt to add 1. In some it's even a function, not special syntax baked into the language.
This answer is relevant to Python 2.7.2. Taken from the python tutorial:
"4. More Control Flow Tools
4.2. for Statements:
The for statement in Python differs a bit from what you may be used to in C or Pascal. Rather than always iterating over an arithmetic progression of numbers (like in Pascal), or giving the user the ability to define both the iteration step and halting condition (as C), Python’s for statement iterates over the items of any sequence (a list or a string), in the order that they appear in the sequence."

Categories

Resources