remarks example cref c# language-features expression

example - remarks c#



Expresión de Expresión Versus (18)

Estoy preguntando con respecto a c #, pero asumo que es lo mismo en la mayoría de los otros idiomas.

¿Alguien tiene una buena definición de expresiones y declaraciones y cuáles son las diferencias?


Algunas cosas sobre lenguajes basados ​​en expresiones:

Lo más importante: todo devuelve un valor.

No hay diferencia entre llaves y llaves para delimitar bloques de código y expresiones, ya que todo es una expresión. Sin embargo, esto no impide el alcance léxico: se podría definir una variable local para la expresión en la que está contenida su definición y todas las declaraciones contenidas en ella, por ejemplo.

En un lenguaje basado en expresiones, todo devuelve un valor. Esto puede ser un poco extraño al principio: ¿qué devuelve (FOR i = 1 TO 10 DO (print i)) ?

Algunos ejemplos simples:

  • (1) devuelve 1
  • (1 + 1) devuelve 2
  • (1 == 1) devuelve TRUE
  • (1 == 2) devuelve FALSE
  • (IF 1 == 1 THEN 10 ELSE 5) devuelve 10
  • (IF 1 == 2 THEN 10 ELSE 5) devuelve 5

Un par de ejemplos más complejos:

  • Algunas cosas, como algunas llamadas a funciones, realmente no tienen un valor significativo para devolver (¿Cosas que solo producen efectos secundarios?). Llamar a OpenADoor(), FlushTheToilet() o TwiddleYourThumbs() devolverá algún tipo de valor mundano, como Aceptar, Hecho o Éxito.
  • Cuando se evalúan múltiples expresiones no vinculadas dentro de una expresión más grande, el valor de la última cosa evaluada en la expresión grande se convierte en el valor de la expresión grande. Para tomar el ejemplo de (FOR i = 1 TO 10 DO (print i)) , el valor del bucle for es "10", hace que la expresión (print i) se evalúe 10 veces, cada vez que devuelva i como un cuerda. El tiempo final a través de devuelve 10 , nuestra respuesta final.

A menudo se requiere un ligero cambio de mentalidad para aprovechar al máximo un lenguaje basado en expresiones, ya que el hecho de que todo sea una expresión hace posible "en línea" muchas cosas

Como un ejemplo rápido:

FOR i = 1 to (IF MyString == "Hello, World!" THEN 10 ELSE 5) DO ( LotsOfCode )

es un reemplazo perfectamente válido para el no basado en expresiones

IF MyString == "Hello, World!" THEN TempVar = 10 ELSE TempVar = 5 FOR i = 1 TO TempVar DO ( LotsOfCode )

En algunos casos, el diseño que permite el código basado en expresiones me parece mucho más natural.

Por supuesto, esto puede llevar a la locura. Como parte de un proyecto de hobby en un lenguaje de script basado en expresiones llamado MaxScript, logré crear esta línea de monstruo

IF FindSectionStart "rigidifiers" != 0 THEN FOR i = 1 TO (local rigidifier_array = (FOR i = (local NodeStart = FindsectionStart "rigidifiers" + 1) TO (FindSectionEnd(NodeStart) - 1) collect full_array[i])).count DO ( LotsOfCode )


Aquí está el resumen de una de las respuestas más simples que encontré.

Originalmente respondida por Anders Kaseorg

Una declaración es una línea completa de código que realiza alguna acción, mientras que una expresión es cualquier sección del código que se evalúa como un valor.

Las expresiones se pueden combinar "horizontalmente" en expresiones más grandes utilizando operadores, mientras que las declaraciones solo se pueden combinar "verticalmente" escribiendo una tras otra, o con construcciones de bloque.

Cada expresión se puede usar como una declaración (cuyo efecto es evaluar la expresión e ignorar el valor resultante), pero la mayoría de las declaraciones no se pueden usar como expresiones.

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


Declaraciones -> Instrucciones para seguir secuencialmente
Expresiones -> Evaluación que devuelve un valor

Las declaraciones son básicamente como pasos, o instrucciones en un algoritmo, el resultado de la ejecución de una declaración es la actualización del puntero de instrucción (denominado en ensamblador)

Las expresiones no implican un orden de ejecución a primera vista, su propósito es evaluar y devolver un valor. En los lenguajes de programación imperativos, la evaluación de una expresión tiene un orden, pero es solo por el modelo imperativo, pero no es su esencia.

Ejemplos de declaraciones:

for goto return if

(Todos ellos implican el avance de la línea (declaración) de ejecución a otra línea)

Ejemplo de expresiones:

2+2

(No implica la idea de ejecución, sino de la evaluación).


Las declaraciones son oraciones gramaticalmente completas. Las expresiones no lo son. Por ejemplo

x = 5

lee como "x obtiene 5." Esta es una oración completa. El código

(x + 5)/9.0

dice: "x más 5, todo dividido por 9.0". Esta no es una oración completa. La declaración

while k < 10: print k k += 1

Es una oración completa. Observe que el encabezado del bucle no es; "mientras k <10," es una cláusula subordinada.


Las expresiones se pueden evaluar para obtener un valor, mientras que las declaraciones no devuelven un valor (son de tipo void ).

Las expresiones de llamada de función también pueden considerarse declaraciones, por supuesto, pero a menos que el entorno de ejecución tenga una variable especial incorporada para mantener el valor devuelto, no hay forma de recuperarlo.

Los idiomas orientados a las declaraciones requieren que todos los procedimientos sean una lista de declaraciones. Los lenguajes orientados a la expresión, que probablemente son todos los lenguajes funcionales, son listas de expresiones, o en el caso de LISP, una expresión S larga que representa una lista de expresiones.

Aunque ambos tipos se pueden componer, la mayoría de las expresiones se pueden componer de manera arbitraria siempre que los tipos coincidan. Cada tipo de declaración tiene su propia forma de componer otras declaraciones, si pueden hacerlo todo. Las declaraciones de Foreach y if requieren una declaración única o que todas las declaraciones subordinadas van en un bloque de declaración, una detrás de otra, a menos que las subestaciones permitan sus propias subestaciones.

Las declaraciones también pueden incluir expresiones, donde una expresión no incluye realmente ninguna declaración. Sin embargo, una excepción sería una expresión lambda, que representa una función, por lo que puede incluir cualquier cosa que una función pueda incluir a menos que el lenguaje solo permita lambdas limitadas, como las lambdas de expresión única de Python.

En un lenguaje basado en expresiones, todo lo que necesita es una expresión única para una función, ya que todas las estructuras de control devuelven un valor (muchos de ellos devuelven NIL). No hay necesidad de una declaración de retorno ya que la última expresión evaluada en la función es el valor de retorno.


Más precisamente, una declaración debe tener un "efecto secundario" (es decir, ser imperativo ) y una expresión debe tener un tipo de valor (es decir, no el tipo de fondo).

El tipo de una declaración es el tipo de unidad, pero debido a que la unidad de teorema de detención es ficticia, digamos el tipo de fondo .

Void no es precisamente el tipo de fondo (no es el subtipo de todos los tipos posibles). Existe en idiomas que no tienen un sistema de tipo de sonido completo . Esto puede sonar como una declaración de esnobismo, pero la integridad , como las anotaciones de varianza, es fundamental para escribir software extensible.

Veamos lo que Wikipedia tiene que decir sobre este asunto.

https://en.wikipedia.org/wiki/Statement_(computer_science)

En la programación informática, una declaración es el elemento independiente más pequeño de un lenguaje de programación imperativo que expresa alguna acción a realizar.

Muchos idiomas (por ejemplo, C) hacen una distinción entre declaraciones y definiciones, con una declaración que solo contiene código ejecutable y una definición que declara un identificador, mientras que una expresión se evalúa solo como un valor.


Me gustaría hacer una pequeña corrección a la respuesta de Joel arriba.

C # no permite que todas las expresiones se usen como declaraciones. En particular, solo las expresiones de asignación, llamada, incremento y decremento pueden usarse como declaraciones.

Por ejemplo, el compilador de C # marcará el siguiente código como un error de sintaxis:

1 + 2;


No estoy realmente satisfecho con ninguna de las respuestas aquí. Miré la gramática de C ++ (ISO 2008) . Sin embargo, tal vez por el bien de la didáctica y la programación, las respuestas podrían ser suficientes para distinguir los dos elementos (aunque la realidad parece más complicada).

Una declaración consta de cero o más expresiones, pero también pueden ser otros conceptos de lenguaje. Esta es la forma extendida de Backus Naur para la gramática (extracto de la declaración):

statement: labeled-statement expression-statement <-- can be zero or more expressions compound-statement selection-statement iteration-statement jump-statement declaration-statement try-block

Podemos ver los otros conceptos que se consideran declaraciones en C ++.

  • expresión-instrucción s se explica por sí misma (una declaración puede constar de cero o más expresiones, lea la gramática con cuidado, es difícil)
  • case por ejemplo, es una declaración etiquetada
  • Las declaraciones de selección son if if/else , case
  • iteración-declaración s son while , do...while , for (...)
  • las instrucciones de salto son break , continue , return (puede devolver expresión), goto
  • declaración-declaración es el conjunto de declaraciones
  • try-block es una declaración que representa try/catch bloques try/catch
  • y podría haber algo más en la gramática

Este es un extracto que muestra la parte de expresiones:

expression: assignment-expression expression "," assignment-expression assignment-expression: conditional-expression logical-or-expression assignment-operator initializer-clause throw-expression

  • Las expresiones son o contienen asignaciones a menudo.
  • La expresión condicional (suena engañosa) se refiere al uso de los operadores ( + , - , * , / , & , | , && , || , ...)
  • expresión de lanzamiento - uh? La cláusula de throw es una expresión también

Para mejorar y validar mi respuesta anterior, las definiciones de los términos del lenguaje de programación deben explicarse desde la teoría del tipo de ciencias de la computación cuando corresponda.

Una expresión tiene un tipo diferente al tipo Inferior, es decir, tiene un valor. Una declaración tiene la unidad o el tipo de fondo.

De esto se deduce que una declaración solo puede tener algún efecto en un programa cuando crea un efecto secundario, porque no puede devolver un valor o solo devuelve el valor del tipo de Unidad que no es asignable el void una C) o (como en Scala) se puede almacenar para una evaluación demorada de la declaración.

Obviamente, un @pragma o un /*comment*/ no tienen tipo y, por lo tanto, se diferencian de las declaraciones. Por lo tanto, el único tipo de declaración que no tendría efectos secundarios sería una no operación. La no operación solo es útil como marcador de posición para futuros efectos secundarios. Cualquier otra acción debida a una declaración sería un efecto secundario. De nuevo, una sugerencia de compilación, por ejemplo, @pragma , no es una declaración porque no tiene ningún tipo.


Para una explicación de las diferencias importantes en la composibilidad (encadenamiento) de las expresiones frente a las declaraciones, mi referencia favorita es el papel de premio de John Backus, ¿Se puede liberar la programación del estilo de von Neumann? .

Los lenguajes imperativos (Fortran, C, Java, ...) enfatizan las afirmaciones para estructurar programas, y tienen expresiones como una especie de pensamiento posterior. Los lenguajes funcionales enfatizan las expresiones. Los lenguajes puramente funcionales tienen expresiones tan poderosas que las declaraciones pueden eliminarse por completo.


Prefiero el significado de statement en el sentido lógico formal de la palabra. Es uno que cambia el estado de una o más de las variables en el cálculo, lo que permite hacer una declaración verdadera o falsa sobre sus valores.

Supongo que siempre habrá confusión en el mundo de la computación y en la ciencia en general cuando se introduzca una nueva terminología o palabras, las palabras existentes se "replanten" o los usuarios ignoren la terminología existente, establecida o "adecuada" para lo que describen.


Puede encontrar esto en wikipedia , pero las expresiones se evalúan con algún valor, mientras que las declaraciones no tienen un valor evaluado.

Por lo tanto, las expresiones se pueden usar en declaraciones, pero no al revés.

Tenga en cuenta que algunos idiomas (como Lisp, y creo que Ruby, y muchos otros) no diferencian enunciado vs expresión ... en dichos idiomas, todo es una expresión y se pueden encadenar con otras expresiones.


Simplemente: una expresión se evalúa como un valor, una declaración no.


Una declaración es un caso especial de una expresión, uno con tipo void . La tendencia de los idiomas a tratar las afirmaciones de manera diferente a menudo causa problemas, y sería mejor si se generalizaran adecuadamente.

Por ejemplo, en C # tenemos el muy útil conjunto de delegados genéricos de Func<T1, T2, T3, TResult> sobrecargado. Pero también tenemos que tener un conjunto correspondiente de Action<T1, T2, T3> , y la programación de orden superior de propósito general constantemente tiene que ser duplicada para lidiar con esta desafortunada bifurcación.

Ejemplo trivial: una función que verifica si una referencia es nula antes de llamar a otra función:

TResult IfNotNull<TValue, TResult>(TValue value, Func<TValue, TResult> func) where TValue : class { return (value == null) ? default(TValue) : func(value); }

¿Podría el compilador lidiar con la posibilidad de que TResult sea void ? Sí. Todo lo que tiene que hacer es exigir que el retorno vaya seguido de una expresión que sea de tipo void . El resultado del default(void) sería de tipo void , y la función que se está pasando debería tener la forma Func<TValue, void> (que sería equivalente a Action<TValue> ).

Algunas otras respuestas implican que no se pueden encadenar declaraciones como se pueden con expresiones, pero no estoy seguro de dónde proviene esta idea. Podemos pensar en el ; que aparece después de las sentencias como un operador de infijo binario, que toma dos expresiones de tipo void y las combina en una sola expresión de tipo void .


Una expresión es algo que devuelve un valor, mientras que una declaración no lo hace.

Por ejemplo:

1 + 2 * 4 * foo.bar() //Expression foo.voidFunc(1); //Statement

El gran problema entre los dos es que se pueden encadenar expresiones, mientras que las declaraciones no se pueden encadenar.


Statement ,

Una declaración es un bloque de construcción de procedimientos a partir del cual se construyen todos los programas de C #. Una declaración puede declarar una variable o constante local, llamar a un método, crear un objeto o asignar un valor a una variable, propiedad o campo.

Una serie de declaraciones rodeadas de llaves forman un bloque de código. Un cuerpo de método es un ejemplo de un bloque de código.

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

Las declaraciones en C # a menudo contienen expresiones. Una expresión en C # es un fragmento de código que contiene un valor literal, un nombre simple o un operador y sus operandos.

Expression

Una expresión es un fragmento de código que se puede evaluar a un solo valor, objeto, método o espacio de nombres. Los dos tipos más simples de expresiones son literales y nombres simples. Un literal es un valor constante que no tiene nombre.

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

Tanto i como s son nombres simples que identifican variables locales. Cuando esas variables se usan en una expresión, el valor de la variable se recupera y se usa para la expresión.


Expresión: Algo que se evalúa a un valor. Ejemplo: 1 + 2 / x
Declaración: Una línea de código que hace algo. Ejemplo: GOTO 100

En los primeros lenguajes de programación de propósito general, como FORTRAN, la distinción era muy clara. En FORTRAN, una declaración fue una unidad de ejecución, una cosa que hiciste. La única razón por la que no se llamó una "línea" fue porque a veces abarcaba varias líneas. Una expresión por sí sola no podía hacer nada ... tenías que asignarla a una variable.

1 + 2 / X

Es un error en FORTRAN, porque no hace nada. Tenías que hacer algo con esa expresión:

X = 1 + 2 / X

FORTRAN no tenía una gramática como la conocemos hoy, esa idea se inventó, junto con Backus-Naur Form (BNF), como parte de la definición de Algol-60. En ese punto, la distinción semántica ("tener un valor" frente a "hacer algo") estaba consagrada en la sintaxis : un tipo de frase era una expresión, y otro era una declaración, y el analizador podía distinguirlos.

Los diseñadores de lenguajes posteriores difuminaron la distinción: permitieron que las expresiones sintácticas hicieran cosas, y permitieron declaraciones sintácticas que tenían valores. El primer ejemplo de lenguaje popular que aún sobrevive es C. Los diseñadores de C se dieron cuenta de que no se hacía daño si se le permitía evaluar una expresión y tirar el resultado. En C, cada expresión sintáctica se puede convertir en una declaración con solo colocar un punto y coma en el extremo:

1 + 2 / x;

Es una afirmación totalmente legítima aunque no pasará absolutamente nada. De manera similar, en C, una expresión puede tener efectos secundarios: puede cambiar algo.

1 + 2 / callfunc(12);

porque callfunc podría hacer algo útil.

Una vez que permita que cualquier expresión sea una declaración, también puede permitir que el operador de asignación (=) contenga expresiones. Es por eso que C te permite hacer cosas como

callfunc(x = 2);

Esto evalúa la expresión x = 2 (asignando el valor de 2 a x) y luego pasa eso (el 2) a la función callfunc .

Este desenfoque de expresiones y declaraciones se produce en todas las derivadas C (C, C ++, C # y Java), que todavía tienen algunas declaraciones (como por ejemplo) pero que permiten que casi cualquier expresión se use como una declaración (en la asignación solo de C # , las expresiones de llamada, incremento y decremento pueden usarse como declaraciones; consulte la respuesta de Scott Wisniewski ).

Tener dos "categorías sintácticas" (que es el nombre técnico para el tipo de cosa que son las declaraciones y las expresiones) puede llevar a la duplicación de esfuerzos. Por ejemplo, C tiene dos formas de condicional, la forma de declaración

if (E) S1; else S2;

y la forma de expresión

E ? E1 : E2

Y a veces la gente quiere una duplicación que no existe: en el estándar C, por ejemplo, solo una declaración puede declarar una nueva variable local, pero esta capacidad es lo suficientemente útil como para que el compilador GNU C proporcione una extensión GNU que permita a una expresión declarar una variable local también.

A los diseñadores de otros idiomas no les gustó este tipo de duplicación, y vieron pronto que si las expresiones pueden tener efectos secundarios y valores, entonces la distinción sintáctica entre declaraciones y expresiones no es tan útil, por lo que se deshicieron de ella. . Haskell, Icon, Lisp y ML son todos los idiomas que no tienen declaraciones sintácticas, solo tienen expresiones. Incluso los bucles estructurados de clase y las formas condicionales se consideran expresiones y tienen valores, pero no muy interesantes.


  • una expresión es cualquier cosa que produce un valor: 2 + 2
  • Una declaración es uno de los "bloques" básicos de la ejecución del programa.

Tenga en cuenta que en C, "=" es en realidad un operador, que hace dos cosas:

  • Devuelve el valor de la subexpresión de la mano derecha.
  • copia el valor de la subexpresión de la mano derecha en la variable del lado izquierdo.

Aquí hay un extracto de la gramática ANSI C. Puede ver que C no tiene muchos tipos diferentes de declaraciones ... la mayoría de las declaraciones en un programa son expresiones de expresión, es decir, una expresión con un punto y coma al final.

statement : labeled_statement | compound_statement | expression_statement | selection_statement | iteration_statement | jump_statement ; expression_statement : '';'' | expression '';'' ;

http://www.lysator.liu.se/c/ANSI-C-grammar-y.html