He estado buscando en la web una definición de programación declarativa e imperativa que me aclare algo. Sin embargo, el lenguaje utilizado en algunos de los recursos que he encontrado es desalentador, por ejemplo, en Wikipedia . ¿Alguien tiene un ejemplo del mundo real que pueda mostrarme que pueda aportar alguna perspectiva a este tema (tal vez en C #)?
541
Respuestas:
Un gran ejemplo de C # de programación declarativa versus imperativa es LINQ.
Con la programación imperativa , le dice al compilador lo que quiere que suceda, paso a paso.
Por ejemplo, comencemos con esta colección y elija los números impares:
Con una programación imperativa, deberíamos pasar por esto y decidir qué queremos:
Aquí estamos diciendo:
Con la programación declarativa , por otro lado, escribes código que describe lo que quieres, pero no necesariamente cómo obtenerlo (declara los resultados deseados, pero no paso a paso):
Aquí, estamos diciendo "Danos todo donde sea extraño", no "Pasar por la colección. Marque este elemento, si es extraño, agréguelo a una colección de resultados".
En muchos casos, el código también será una mezcla de ambos diseños, por lo que no siempre es en blanco y negro.
fuente
collection.Where
no utiliza la sintaxis declarativa que proporciona Linq; consulte msdn.microsoft.com/en-us/library/bb397906.aspx para ver ejemplos,from item in collection where item%2 != 0 select item
sería la forma declarativa. Llamar a una función no se convierte en programación declarativa solo porque esa función está en el espacio de nombres System.Linq.La programación declarativa es cuando dices lo que quieres, y el lenguaje imperativo es cuando dices cómo obtener lo que quieres.
Un ejemplo simple en Python:
El primer ejemplo es declarativo porque no especificamos ningún "detalle de implementación" para construir la lista.
Para vincular un ejemplo de C #, generalmente, usar LINQ resulta en un estilo declarativo, porque no está diciendo cómo obtener lo que desea; solo dices lo que quieres. Se podría decir lo mismo sobre SQL.
Una ventaja de la programación declarativa es que permite que el compilador tome decisiones que podrían dar como resultado un código mejor que el que podría tomar a mano. Ejecutando con el ejemplo de SQL, si tuviera una consulta como
el "compilador" de SQL puede "optimizar" esta consulta porque sabe que
id
es un campo indexado, o tal vez no está indexado, en cuyo caso tendrá que iterar sobre todo el conjunto de datos de todos modos. O tal vez el motor SQL sabe que este es el momento perfecto para utilizar los 8 núcleos para una búsqueda paralela rápida. Usted , como programador, no está preocupado por ninguna de esas condiciones, y no tiene que escribir su código para manejar ningún caso especial de esa manera.fuente
filter(lambda x: x < 5, range(20))
es simplemente otra refactorización en una notación más corta. Esto no es de ninguna manera significativa diferente de la expresión de comprensión de la lista (que tiene secciones claras de "mapa" y "filtro"), que fue creada (ver pep 202 ) con la intención explícita de crear una notación más concisa. Y esta comprensión de la lista sería más clara / idiomática en este caso.Declarativo versus imperativo
Un paradigma de programación es un estilo fundamental de programación de computadoras. Hay cuatro paradigmas principales: imperativo, declarativo, funcional (que se considera un subconjunto del paradigma declarativo) y orientado a objetos.
Programación declarativa : es un paradigma de programación que expresa la lógica de un cálculo (Qué hacer) sin describir su flujo de control (Cómo hacerlo). Algunos ejemplos bien conocidos de lenguajes específicos de dominio declarativo (DSL) incluyen CSS, expresiones regulares y un subconjunto de SQL (consultas SELECT, por ejemplo) Muchos lenguajes de marcado como HTML, MXML, XAML, XSLT ... a menudo son declarativos. La programación declarativa intenta difuminar la distinción entre un programa como un conjunto de instrucciones y un programa como una afirmación sobre la respuesta deseada.
Programación imperativa : es un paradigma de programación que describe la computación en términos de declaraciones que cambian el estado de un programa. Los programas declarativos pueden verse de manera dual como comandos de programación o aserciones matemáticas.
Programación funcional: es un paradigma de programación que trata la computación como la evaluación de funciones matemáticas y evita el estado y los datos mutables. Enfatiza la aplicación de funciones, en contraste con el estilo de programación imperativo, que enfatiza los cambios de estado. En un lenguaje funcional puro, como Haskell, todas las funciones no tienen efectos secundarios, y los cambios de estado solo se representan como funciones que transforman el estado.
El siguiente ejemplo de programación imperativa en MSDN , recorre los números del 1 al 10 y encuentra los números pares.
Ambos ejemplos producen el mismo resultado, y uno no es ni mejor ni peor que el otro. El primer ejemplo requiere más código, pero el código es comprobable y el enfoque imperativo le brinda control total sobre los detalles de implementación. En el segundo ejemplo, el código es posiblemente más legible; sin embargo, LINQ no le da control sobre lo que sucede detrás de escena. Debe confiar en que LINQ proporcionará el resultado solicitado.
fuente
Todas las respuestas anteriores y otras publicaciones en línea mencionan lo siguiente:
Lo que no nos han dicho es cómo lograrlo . Para que una parte del programa sea más declarativa, otras partes deben proporcionar la abstracción para ocultar los detalles de implementación (que son los códigos imperativos ).
list.Where()
para obtener una nueva lista filtrada. Para que esto funcione, Microsoft ha hecho todo el trabajo pesado detrás de la abstracción LINQ.De hecho, una de las razones por las que la programación funcional y las bibliotecas funcionales son más declarativas es porque han abstraído los bucles y las creaciones de la lista, ocultando todos los detalles de implementación (probablemente códigos imperativos con bucles) detrás de escena.
En cualquier programa, siempre tendrá códigos imperativos y declarativos, lo que debe buscar es ocultar todos los códigos imperativos detrás de las abstracciones, para que otras partes del programa puedan usarlos declarativamente .
Finalmente, aunque la programación funcional y LINQ pueden hacer que su programa sea más declarativo, siempre puede hacerlo aún más declarativo al proporcionar más abstracciones. Por ejemplo:
PD: el extremo de la programación declarativa es inventar nuevos lenguajes específicos de dominio (DSL):
fuente
debit
,deposit
, etc., en lugar de repetir código imparativaaccount.balance += depositAmount
Agregaré otro ejemplo que rara vez aparece en la discusión de programación declarativa / imperativa: ¡la interfaz de usuario!
En C #, puede crear una interfaz de usuario utilizando diversas tecnologías.
En el extremo imperativo, puede usar DirectX u OpenGL para dibujar sus botones, casillas de verificación, etc ... línea por línea (o realmente, triángulo por triángulo). Depende de usted decir cómo dibujar la interfaz de usuario.
Al final declarativo, tienes WPF. Básicamente escribes algo de XML (sí, sí, "XAML" técnicamente) y el marco hace el trabajo por ti. Usted dice cómo se ve la interfaz de usuario. Depende del sistema descubrir cómo hacerlo.
De todos modos, solo otra cosa en que pensar. El hecho de que un idioma sea declarativo o imperativo no significa que no tenga ciertas características del otro.
Además, un beneficio de la programación declarativa es que el propósito generalmente se entiende más fácilmente al leer el código, mientras que el imperativo le brinda un control más preciso sobre la ejecución.
La esencia de todo:
Declarativo ->
what
quieres hacerloImperativo ->
how
quieres que se hagafuente
Me gustó una explicación de un curso de Cambridge + sus ejemplos:
int x;
- qué (declarativo)x=x+1;
- cómofuente
CSS
es imperativo ?La diferencia tiene que ver principalmente con el nivel general de abstracción. Con la declaración, en algún momento, está tan lejos de los pasos individuales que el programa tiene mucha libertad con respecto a cómo obtener su resultado.
Podrías ver cada instrucción como si cayera en algún lugar en un continuo:
Grado de abstracción:
Ejemplo declarativo del mundo real:
Ejemplo imperativo del mundo real:
fuente
Calvert, C Kulkarni, D (2009). LINQ esencial. Addison Wesley. 48)
fuente
La programación imperativa es decirle a la computadora explícitamente qué hacer y cómo hacerlo, como especificar el orden y tal
C#:
Declarativo es cuando le dices a la computadora qué hacer, pero no cómo hacerlo. Datalog / Prolog es el primer idioma que viene a la mente a este respecto. Básicamente todo es declarativo. Realmente no puedes garantizar el pedido.
C # es un lenguaje de programación mucho más imperativo, pero ciertas características de C # son más declarativas, como Linq
Lo mismo podría escribirse imperativamente:
(ejemplo de wikipedia Linq)
fuente
De http://en.wikipedia.org/wiki/Declarative_programming
en pocas palabras, el lenguaje declarativo es más simple porque carece de la complejidad del flujo de control (bucles, sentencias if, etc.)
Una buena comparación es el modelo de "código subyacente" ASP.Net. Tiene archivos declarativos '.ASPX' y luego los archivos de código imperativo 'ASPX.CS'. A menudo encuentro que si puedo hacer todo lo que necesito en la mitad declarativa del guión, mucha más gente puede seguir lo que se está haciendo.
fuente
Robando a Philip Roberts aquí :
Dos ejemplos:
1. Duplicar todos los números en una matriz
Imperativamente:
Declarativamente:
2. Sumar todos los artículos en una lista
Imperativo
Declarativamente
Observe cómo los ejemplos imperativos implican crear una nueva variable, mutarla y devolver ese nuevo valor (es decir, cómo hacer que algo suceda), mientras que los ejemplos declarativos se ejecutan en una entrada dada y devuelven el nuevo valor en función de la entrada inicial (es decir, , lo que queremos que suceda).
fuente
Programación imperativa
Un lenguaje de programación que requiere disciplina de programación como C / C ++, Java, COBOL, FORTRAN, Perl y JavaScript. Los programadores que escriben en dichos lenguajes deben desarrollar un orden de acciones adecuado para resolver el problema, basado en el conocimiento del procesamiento y la programación de datos.
Programación declarativa
Un lenguaje de computadora que no requiere escribir lógica de programación tradicional; Los usuarios se concentran en definir la entrada y la salida en lugar de los pasos del programa requeridos en un lenguaje de programación de procedimientos como C ++ o Java.
Ejemplos de programación declarativa son CSS, HTML, XML, XSLT, RegX.
fuente
el programa declarativo es solo un dato para su implementación imperativa más o menos "universal" / vm.
ventajas: especificar solo un dato, en un formato codificado (y verificado), es más simple y menos propenso a errores que especificar directamente la variante de algún algoritmo imperativo. algunas especificaciones complejas no pueden escribirse directamente, solo en alguna forma DSL. best y freq utilizados en las estructuras de datos DSL son conjuntos y tablas. porque no tienes dependencias entre elementos / filas. y cuando no tiene dependencias tiene libertad para modificar y facilidad de soporte. (compare, por ejemplo, módulos con clases: con módulos que le satisfacen y con clases que tiene un problema de clase base frágil) todos los bienes de declaratividad y DSL se deducen inmediatamente de los beneficios de esas estructuras de datos (tablas y conjuntos). Otra ventaja: puede cambiar la implementación del lenguaje declarativo vm, si DSL es más o menos abstracto (bien diseñado). hacer implementación paralela, por ejemplo.
desventajas: adivinas bien. La implementación de algoritmo / vm imperativo genérico (y parametrizado por DSL) puede ser más lenta y / o hambrienta de memoria que la específica. en algunos casos. Si ese caso es raro, solo olvídalo, deja que sea lento. si es frecuente, siempre puede extender su DSL / vm para ese caso. en algún lugar ralentizando todos los demás casos, claro ...
PS Frameworks está a medio camino entre DSL e imperativo. y como todas las soluciones intermedias ... combinan deficiencias, no beneficios. no son tan seguros Y no tan rápidos :) mire el haskell de Jack-of-all-trades: está a medio camino entre el ML simple fuerte y el metaprog flexible Prolog y ... qué monstruo es. puedes ver a Prolog como un Haskell con funciones / predicados booleanos solamente. y cuán simple es su flexibilidad contra Haskell ...
fuente
Me pregunto por qué nadie ha mencionado las clases de atributos como una herramienta de programación declarativa en C #. La respuesta popular de esta página acaba de hablar de LINQ como una herramienta de programación declarativa.
De acuerdo con Wikipedia
Entonces LINQ, como sintaxis funcional, es definitivamente un método declarativo, pero las clases de atributos en C #, como herramienta de configuración, también son declarativas. Aquí hay un buen punto de partida para leer más al respecto: Descripción rápida de la programación de atributos de C #
fuente
Solo para agregar otro ejemplo en términos de desarrollo de aplicaciones móviles. En iOS y Android, tenemos Interface Builders, donde podemos definir la interfaz de usuario de las aplicaciones.
La interfaz de usuario dibujada con estos Constructores es de naturaleza declarativa, donde arrastramos y soltamos los componentes. El dibujo real ocurre debajo y realizado por el marco y el sistema.
Pero también podemos dibujar todos los componentes en código, y eso es imprescindible por naturaleza.
Además, algunos idiomas nuevos como Angular JS se están centrando en el diseño de interfaces de usuario declarativamente y es posible que veamos muchos otros idiomas que ofrecen el mismo soporte. Al igual que Java no tiene una buena forma declarativa de dibujar aplicaciones de escritorio nativas en Java swing o Java FX, pero en el futuro cercano, tal vez sí.
fuente
Según tengo entendido, ambos términos tienen raíces en la filosofía, hay tipos de conocimiento declarativos e imperativos. El conocimiento declarativo son afirmaciones de verdad, declaraciones de hecho como axiomas matemáticos. Te dice algo. El conocimiento imperativo, o de procedimiento, le dice paso a paso cómo llegar a algo. Esa es esencialmente la definición de un algoritmo. Si lo desea, compare un lenguaje de programación de computadora con el idioma inglés. Las oraciones declarativas dicen algo. Un ejemplo aburrido, pero aquí hay una forma declarativa de mostrar si dos números son iguales entre sí, en Java:
Las oraciones imperativas en inglés, por otro lado, dan una orden o hacen algún tipo de solicitud. La programación imperativa, entonces, es solo una lista de comandos (hacer esto, hacer aquello). Aquí hay una forma imperativa de mostrar si dos números son iguales entre sí o no al aceptar la entrada del usuario, en Java:
Esencialmente, el conocimiento declarativo omite ciertos elementos para formar una capa de abstracción sobre esos elementos. La programación declarativa hace lo mismo.
fuente