Expression Versus Statement

前端 未结 21 1765
别那么骄傲
别那么骄傲 2020-11-22 11:54

I\'m asking with regards to c#, but I assume its the same in most other languages.

Does anyone have a good definition of expressions and statements

相关标签:
21条回答
  • 2020-11-22 12:09

    The de-facto basis of these concepts is:

    Expressions: A syntactic category whose instance can be evaluated to a value.

    Statement: A syntactic category whose instance may be involved with evaluations of an expression and the resulted value of the evaluation (if any) is not guaranteed available.

    Besides to the very initial context for FORTRAN in the early decades, both definitions of expressions and statements in the accepted answer are obviously wrong:

    • Expressions can be unvaluated operands. Values are never produced from them.
      • Subexpressions in non-strict evaluations can be definitely unevaluated.
        • Most C-like languages have the so-called short-circuit evaluation rules to conditionally skip some subexpression evaluations not change the final result in spite of the side effects.
      • C and some C-like languages have the notion of unevaluated operand which may be even normatively defined in the language specification. Such constructs are used to avoid the evaluations definitely, so the remained context information (e.g. types or alignment requirements) can be statically distinguished without changing the behavior after the program translation.
        • For example, an expression used as the operand of the sizeof operator is never evaluated.
    • Statements have nothing to do with line constructs. They can do something more than expressions, depending on the language specifications.
      • Modern Fortran, as the direct descendant of the old FORTRAN, has concepts of executable statements and nonexecutable statements.
      • Similarly, C++ defines declarations as the top-level subcategory of a translation unit. A declaration in C++ is a statement. (This is not true in C.) There are also expression-statements like Fortran's executable statements.
      • To the interest of the comparison with expressions, only the "executable" statements matter. But you can't ignore the fact that statements are already generalized to be constructs forming the translation units in such imperative languages. So, as you can see, the definitions of the category vary a lot. The (probably) only remained common property preserved among these languages is that statements are expected to be interpreted in the lexical order (for most users, left-to-right and top-to-bottom).

    (BTW, I want to add [citation needed] to that answer concerning materials about C because I can't recall whether DMR has such opinions. It seems not, otherwise there should be no reasons to preserve the functionality duplication in the design of C: notably, the comma operator vs. the statements.)

    (The following rationale is not the direct response to the original question, but I feel it necessary to clarify something already answered here.)

    Nevertheless, it is doubtful that we need a specific category of "statements" in general-purpose programming languages:

    • Statements are not guaranteed to have more semantic capabilities over expressions in usual designs.
      • Many languages have already successfully abandon the notion of statements to get clean, neat and consistent overall designs.
        • In such languages, expressions can do everything old-style statements can do: just drop the unused results when the expressions are evaluated, either by leaving the results explicitly unspecified (e.g. in RnRS Scheme), or having a special value (as a value of a unit type) not producible from normal expression evaluations.
        • The lexical order rules of evaluation of expressions can be replaced by explicit sequence control operator (e.g. begin in Scheme) or syntactic sugar of monadic structures.
        • The lexical order rules of other kinds of "statements" can be derived as syntactic extensions (using hygienic macros, for example) to get the similar syntactic functionality. (And it can actually do more.)
      • On the contrary, statements cannot have such conventional rules, because they don't compose on evaluation: there is just no such common notion of "substatement evaluation". (Even if any, I doubt there can be something much more than copy and paste from existed rules of evaluation of expressions.)
        • Typically, languages preserving statements will also have expressions to express computations, and there is a top-level subcategory of the statements preserved to expression evaluations for that subcategory. For example, C++ has the so-called expression-statement as the subcategory, and uses the discarded-value expression evaluation rules to specify the general cases of full-expression evaluations in such context. Some languages like C# chooses to refine the contexts to simplify the use cases, but it bloats the specification more.
    • For users of programming languages, the significance of statements may confuse them further.
      • The separation of rules of expressions and statements in the languages requires more effort to learn a language.
      • The naive lexical order interpretation hides the more important notion: expression evaluation. (This is probably most problematic over all.)
        • Even the evaluations of full expressions in statements are constraint with the lexical order, subexpressions are not (necessarily). Users should ultimately learn this besides any rules coupled to the statements. (Consider how to make a newbie get the point that ++i + ++i is meaningless in C.)
        • Some languages like Java and C# further constraints the order of evaluations of subexpressions to be permissive of ignorance of evaluation rules. It can be even more problematic.
          • This seems overspecified to users who have already learned the idea of expression evaluation. It also encourages the user community to follow the blurred mental model of the language design.
          • It bloats the language specification even more.
          • It is harmful to optimization by missing the expressiveness of nondeterminism on evaluations, before more complicated primitives are introduced.
        • A few languages like C++ (particularly, C++17) specify more subtle contexts of evaluation rules, as a compromise of the problems above.
          • It bloats the language specification a lot.
          • This goes totally against to simplicity to average users...

    So why statements? Anyway, the history is already a mess. It seems most language designers do not take their choice carefully.

    Worse, it even gives some type system enthusiasts (who are not familiar enough with the PL history) some misconceptions that type systems must have important things to do with the more essential designs of rules on the operational semantics.

    Seriously, reasoning depending on types are not that bad in many cases, but particularly not constructive in this special one. Even experts can screw things up.

    For example, someone emphasizes the well-typing nature as the central argument against the traditional treatment of undelimited continuations. Although the conclusion is somewhat reasonable and the insights about composed functions are OK (but still far too naive to the essense), this argument is not sound because it totally ignores the "side channel" approach in practice like _Noreturn any_of_returnable_types (in C11) to encode Falsum. And strictly speaking, an abstract machine with unpredictable state is not identical to "a crashed computer".

    0 讨论(0)
  • 2020-11-22 12:10

    I prefer the meaning of statement in the formal logic sense of the word. It is one that changes the state of one or more of the variables in the computation, enabling a true or false statement to be made about their value(s).

    I guess there will always be confusion in the computing world and science in general when new terminology or words are introduced, existing words are 'repurposed' or users are ignorant of the existing, established or 'proper' terminology for what they are describing

    0 讨论(0)
  • 2020-11-22 12:12

    You can find this on wikipedia, but expressions are evaluated to some value, while statements have no evaluated value.

    Thus, expressions can be used in statements, but not the other way around.

    Note that some languages (such as Lisp, and I believe Ruby, and many others) do not differentiate statement vs expression... in such languages, everything is an expression and can be chained with other expressions.

    0 讨论(0)
  • 2020-11-22 12:13

    To improve on and validate my prior answer, definitions of programming language terms should be explained from computer science type theory when applicable.

    An expression has a type other than the Bottom type, i.e. it has a value. A statement has the Unit or Bottom type.

    From this it follows that a statement can only have any effect in a program when it creates a side-effect, because it either can not return a value or it only returns the value of the Unit type which is either nonassignable (in some languages such a C's void) or (such as in Scala) can be stored for a delayed evaluation of the statement.

    Obviously a @pragma or a /*comment*/ have no type and thus are differentiated from statements. Thus the only type of statement that would have no side-effects would be a non-operation. Non-operation is only useful as a placeholder for future side-effects. Any other action due to a statement would be a side-effect. Again a compiler hint, e.g. @pragma, is not a statement because it has no type.

    0 讨论(0)
  • 2020-11-22 12:14

    Statement,

    A statement is a procedural building-block from which all C# programs are constructed. A statement can declare a local variable or constant, call a method, create an object, or assign a value to a variable, property, or field.

    A series of statements surrounded by curly braces form a block of code. A method body is one example of a code block.

    bool IsPositive(int number)
    {
        if (number > 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    

    Statements in C# often contain expressions. An expression in C# is a fragment of code containing a literal value, a simple name, or an operator and its operands.

    Expression,

    An expression is a fragment of code that can be evaluated to a single value, object, method, or namespace. The two simplest types of expressions are literals and simple names. A literal is a constant value that has no name.

    int i = 5;
    string s = "Hello World";
    

    Both i and s are simple names identifying local variables. When those variables are used in an expression, the value of the variable is retrieved and used for the expression.

    0 讨论(0)
  • 2020-11-22 12:15

    Here is the summery of one of the simplest answer I found.

    originally Answered by Anders Kaseorg

    A statement is a complete line of code that performs some action, while an expression is any section of the code that evaluates to a value.

    Expressions can be combined “horizontally” into larger expressions using operators, while statements can only be combined “vertically” by writing one after another, or with block constructs.

    Every expression can be used as a statement (whose effect is to evaluate the expression and ignore the resulting value), but most statements cannot be used as expressions.

    http://www.quora.com/Python-programming-language-1/Whats-the-difference-between-a-statement-and-an-expression-in-Python

    0 讨论(0)
提交回复
热议问题