Solución:
Un gran ejemplo de C # de programación declarativa frente a programación imperativa es LINQ.
Con imperativo programación, le dices al compilador lo que quieres que suceda, paso a paso.
Por ejemplo, comencemos con esta colección y escojamos los números impares:
List<int> collection = new List<int> { 1, 2, 3, 4, 5 };
Con la programación imperativa, pasaríamos por esto y decidiríamos lo que queremos:
List<int> results = new List<int>();
foreach(var num in collection)
{
if (num % 2 != 0)
results.Add(num);
}
Aquí estamos diciendo:
- Crea una colección de resultados
- Recorre cada número de la colección
- Verifique el número, si es impar, agréguelo a los resultados
Con declarativo La programación, por otro lado, escribe código que describe lo que desea, pero no necesariamente cómo obtenerlo (declare los resultados deseados, pero no el paso a paso):
var results = collection.Where( num => num % 2 != 0);
Aquí, estamos diciendo “Danos todo lo que sea extraño”, no “Recorre 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.
La programación declarativa es cuando dices qué quieres, y el lenguaje imperativo es cuando dices cómo para conseguir lo que quieres.
Un ejemplo simple en Python:
# Declarative
small_nums = [x for x in range(20) if x < 5]
# Imperative
small_nums = []
for i in range(20):
if i < 5:
small_nums.append(i)
El primer ejemplo es declarativo porque no especificamos ningún “detalle de implementación” de la construcción de la lista.
Para vincular un ejemplo de C #, generalmente, el uso de LINQ da como resultado un estilo declarativo, porque no está diciendo cómo para obtener lo que desea; solo estas diciendo qué quieres. Podría decirse lo mismo de SQL.
Un beneficio de la programación declarativa es que permite al compilador tomar decisiones que pueden resultar en un código mejor que el que podría hacer a mano. Ejecutando con el ejemplo de SQL, si tuvieras una consulta como
SELECT score FROM games WHERE id < 100;
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.
Declarativo frente a imperativo
Un paradigma de programación es un estilo fundamental de programación informática. 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 hacer). Algunos ejemplos conocidos de lenguajes específicos de dominio declarativos (DSL) incluyen CSS, expresiones regulares y un subconjunto de SQL (consultas SELECT, por ejemplo). Muchos lenguajes de marcado como HTML, MXML, XAML, XSLT … suelen ser 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 como comandos de programación o afirmaciones 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 estados y datos mutables. Enfatiza la aplicación de funciones, en contraste con el estilo de programación imperativa, 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.
var numbersOneThroughTen = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
//With imperative programming, we'd step through this, and decide what we want:
var evenNumbers = new List<int>();
foreach (var number in numbersOneThroughTen)
{ if (number % 2 == 0)
{
evenNumbers.Add(number);
}
}
//The following code uses declarative programming to accomplish the same thing.
// Here, we're saying "Give us everything where it's even"
var evenNumbers = numbersOneThroughTen.Select(number => number % 2 == 0);
Ambos ejemplos dan 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 se puede probar y el enfoque imperativo le brinda control total sobre los detalles de implementación. En el segundo ejemplo, se puede decir que el código es 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.