What is the difference between expression and expression?

I know this may be a duplicate, but I have not found sufficient answers to my examples. In general, what is the difference between expressions and expressions? This is a difference that I have not yet fully distinguished. I know that, as a rule, expressions are perhaps all that returns a value, such as a literal or function. Typically, messages are called interpreter commands, such as "print such-and-such" or "do ... bye." However, I do not understand this.

It makes no sense to say that printing is an expression, since it is a function of printing input (input output)? In addition, people usually say that x = 1 is an instruction, but could it not be considered an expression where the assignment operator is a function acting on two inputs and the output is that x refers to 1? Finally, there cannot be a flow control structure, for example, otherwise you can consider a function with three arguments, in which one of the other arguments is returned based on the truth value of the first input, making it an expression?

I'm probably confused because I have a background in LISP where everything is an expression. It seems like I cannot shy away from the idea that most software constructs are expressions in their core. So can anyone explain what is really the difference between the so-called expression and the expression?

+7
expression
source share
3 answers

The definition of an expression and a statement โ€” and even if it exists as one or the other โ€” refers to a particular language and grammar that describes it.

Well, let go:

  • An operator is some โ€œevaluation codeโ€ 1 which is not displayed in the context of the expression; and

  • An expression is code that appears in a context where the resulting value can be used by substituting the expression.

{Very weak "definition", but no single language. Although some languages โ€‹โ€‹are strict when side effects may not happen โ€” and code that runs without a result or side effect is useless โ€” I donโ€™t think that discussing this is fundamental to the differences.}

For example, let's look at printf in C. This is a function, on the other hand, is a side effect and returns a value ; usually the return value is ignored. This way printf can appear as a statement

 printf("Hello world!"); 

and expression

 if (8 == printf("Hello %s!", name)) { // .. 

(A function call with a void return type can only appear in the context of an operator in C, but this is imposed by the type system, not the parser.)

Similarly, take these two lines in JavaScript x = 1; and x = (y = 2); . x = .. is the operator, and y = 2 is the expression that gave the value.

In both of these examples, we see that this is a product of grammar, defined if it is considered as an expression or expression.

Unlike Ruby, it can consider a top-level assignment as an expression:

 [1].map {|x| x = 2} 

Now let's take the Python peak (2.x). In this case, print is a statement, so they work and do not work accordingly:

 print "Look ma, no parenthesis!" x = lambda y: print "Whoops!" # invalid, print not an expression 

What about if constructs are these expressions or expressions? Again, this depends on the specific language. In C and Java, such expressions are explicit statements: there is no way to use, for example, to replace a value.

On the other hand, Scala (and Ruby) allows you to use such flow control constructs as expressions, although they can also be displayed as operators:

 var emotionalResponse = if (color == "green") { log.cheer() new Cheering() } else { new Tears() } 

Phew This is a lot - and it is not very complete. But back to the "definition", which can be recounted as such, taking into account the following examples:

If the construction in question can occur where a value is required (for example, on the right side of an assignment, as an argument of a function, as an input to another expression), then this can be considered as an expression; and most definitely is an expression when in such a context. If a construct appears in a place where it is impossible to access through the substitution, then it (or, rather, can act as) an operator.


1 Another class of derived conditions is a declaration, such as function declarations in C definitions or classes in Java, and may not be statements; as the following is fragmented in the same way as most of the note.

+7
source share

An expression gives meaning, an operator does something.

for example, in C return a+5; - this is an operator, it gives a function that passes the value that calls the value obtained from the expression a+5 .

whether print is an expression or a statement depends on the language.

BASIC has a seal, which is not a function, like that which is processed as a special case by the copiler. Similarly, pascal has write and writeln , which are also special cases, not a calle function, on the other hand, C has puts () and printf (), which are both functions. and allows the programmer to write similar functions that work the same way.

+3
source share

The answer is more philosophical than practical. Statements usually have side effects, while expressions tend to be more algebraic.

In purely functional languages, there are no statements. That is, even those things that perform side effects (for example, in a file) are expressed in terms of values โ€‹โ€‹that represent (ideally) all mutations, including errors.

Imperative languages โ€‹โ€‹use operators to execute arbitrary code, such as assigning a value to a variable or printing to the console, as well as the ability to exchange error messages other than throwing exceptions.

Purely functional expressions simply reduce the cognitive overhead of fighting mutations by exposing these mutations as in-and-of-themselves values. Combine this with pattern matching, and you are forced to explicitly handle all success and failure scenarios, and therefore turn them into values, explicitly matching or filtering for any failures.

Imperative statements are not required to expose errors as values, and therefore there is always the possibility of arbitrary code that exists in an unsuspecting method, so that it is easy to overlook it. Expressions, such as method calls or variable assignments ( x = y = z() ), can generally correspond to the form of the expression, still executing arbitrary code and unable to report errors as values.

In the end, you cannot avoid a mutation. However, you can make it more explicit. This means that statements and expressions differ mainly in a philosophical way, both existing and answering the same question - how should we expose mutations in the context of code execution?

0
source share

All Articles