c# - programação - programming paradigms




Qual é a diferença entre programação declarativa e imperativa? (11)

A programação imperativa requer que os desenvolvedores definam passo a passo como o código deve ser executado. Para dar instruções de forma imperativa, você diz: "Vá para a 1st Street, vire à esquerda na Main, dirija dois quarteirões, vire à direita na Maple e pare na terceira casa à esquerda". A versão declarativa pode soar mais ou menos assim: : “Dirija para a casa de Sue.” Um diz como fazer alguma coisa; o outro diz o que precisa ser feito.

O estilo declarativo tem duas vantagens sobre o estilo imperativo:

  • Não força o viajante a memorizar um longo conjunto de instruções.
  • Permite ao viajante otimizar a rota quando possível.

Calvert, C Kulkarni, D (2009). LINQ Essencial Addison Wesley. 48

https://code.i-harness.com

Eu tenho procurado na web em busca de uma definição para programação declarativa e imperativa que iria lançar alguma luz para mim. No entanto, a linguagem usada em alguns dos recursos que encontrei é assustadora - por exemplo, na Wikipedia . Alguém tem um exemplo do mundo real que eles poderiam me mostrar que pode trazer alguma perspectiva para este assunto (talvez em c #)?


Na ciência da computação, a programação declarativa é um paradigma de programação que expressa a lógica de uma computação sem descrever seu fluxo de controle.

De http://en.wikipedia.org/wiki/Declarative_programming

Em suma, a linguagem declarativa é mais simples porque não possui a complexidade do fluxo de controle (loops, if statements, etc.)

Uma boa comparação é o modelo 'code-behind' do ASP.Net. Você tem arquivos '.ASPX' declarativos e, em seguida, os arquivos de código 'ASPX.CS' imperativos. Eu sempre acho que se eu puder fazer tudo o que preciso na metade declarativa do script, muito mais pessoas podem seguir o que está sendo feito.


A programação imperativa está dizendo ao computador explicitamente o que fazer e como fazê-lo, como especificar a ordem e tal

C #:

for (int i = 0; i < 10; i++)
{
    System.Console.WriteLine("Hello World!");
}

Declarativo é quando você diz ao computador o que fazer, mas não como fazê-lo. O Datalog / Prolog é a primeira linguagem que vem à mente a esse respeito. Basicamente tudo é declarativo. Você não pode realmente garantir a ordem.

C # é uma linguagem de programação muito mais imperativa, mas certos recursos do C # são mais declarativos, como o Linq

dynamic foo = from c in someCollection
           let x = someValue * 2
           where c.SomeProperty < x
           select new {c.SomeProperty, c.OtherProperty};

A mesma coisa poderia ser escrita imperativamente:

dynamic foo = SomeCollection.Where
     (
          c => c.SomeProperty < (SomeValue * 2)
     )
     .Select
     (
          c => new {c.SomeProperty, c.OtherProperty}
     )

(exemplo de wikipedia Linq)


Apenas para adicionar outro exemplo em termos de desenvolvimento de aplicativos para dispositivos móveis. Em iOS e Android, temos Interface Builders, onde podemos definir a interface do usuário dos aplicativos.

A interface do usuário desenhada usando esses construtores é de natureza declarativa, onde arrastamos e soltamos os componentes. A drenagem real acontece embaixo e executada pela estrutura e pelo sistema.

Mas também podemos desenhar os componentes inteiros no código, e isso é de natureza imperativa.

Além disso, alguns novos idiomas, como o Angular JS, estão focalizando a criação de UIs declarativamente e podemos ver muitas outras linguagens oferecendo o mesmo suporte. Como o JAVA não tem nenhuma boa maneira declarativa de desenhar aplicativos de desktop nativos em JAVA swing ou JAVA FX, mas no futuro próximo eles podem.


Eu só me pergunto por que ninguém mencionou classes de atributo como uma ferramenta de programação declarativa em C #. A resposta popular desta página acaba de falar sobre LINQ como uma ferramenta de programação declarativa.

De acordo com a Wikipedia

As linguagens declarativas comuns incluem as linguagens de consulta de banco de dados (por exemplo, SQL, XQuery), expressões regulares, programação lógica, programação funcional e sistemas de gerenciamento de configuração.

Portanto, LINQ, como uma sintaxe funcional, é definitivamente um método declarativo, mas as classes de atributo em C #, como uma ferramenta de configuração, também são declarativas. Aqui está um bom ponto de partida para ler mais sobre isso: Visão Geral Rápida da Programação de Atributos C #


Gostei de uma explicação de um curso de Cambridge + seus exemplos:

  • Declarativo - especifique o que fazer, não como fazê-lo
    • Por exemplo: o HTML descreve o que deve aparecer em uma página da Web, não como deve ser desenhado na tela
  • Imperativo - especifique o que e como
    • int x; - o que (declarativo)
    • x=x+1; - como

Pelo que entendi, ambos os termos têm raízes na filosofia, existem tipos declarativos e imperativos de conhecimento. Conhecimento declarativo são afirmações da verdade, afirmações de fato, como axiomas matemáticos. Isso te diz uma coisa. Conhecimento imperativo, ou procedural, lhe diz passo a passo como chegar a algo. Isso é o que a definição de um algoritmo é essencialmente. Se você quiser, compare uma linguagem de programação de computador com o idioma inglês. Sentenças declarativas afirmam algo. Um exemplo chato, mas aqui está uma maneira declarativa de mostrar se dois números são iguais entre si, em Java:

public static void main(String[] args)
{
    System.out.print("4 = 4.");
}

As sentenças imperativas em inglês, por outro lado, dão um comando ou fazem algum tipo de solicitação. A programação imperativa, então, é apenas uma lista de comandos (faça isso, faça isso). Aqui está uma maneira imperativa de mostrar se dois números são iguais entre si ou não, aceitando a entrada do usuário, em Java:

private static Scanner input;    

public static void main(String[] args) 
{
    input = new Scanner(System.in);
    System.out.println();
    System.out.print("Enter an integer value for x: ");
    int x = input.nextInt();
    System.out.print("Enter an integer value for y: ");        
    int y = input.nextInt();

    System.out.println();
    System.out.printf("%d == %d? %s\n", x, y, x == y);
}

Essencialmente, o conhecimento declarativo ignora certos elementos para formar uma camada de abstração sobre esses elementos. A programação declarativa faz o mesmo.


Programação declarativa é quando você diz o que quer, e a linguagem imperativa é quando você diz como conseguir o que quer.

Um exemplo simples em 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)

O primeiro exemplo é declarativo porque não especificamos nenhum "detalhes de implementação" da construção da lista.

Para amarrar um exemplo em C #, geralmente, usar o LINQ resulta em um estilo declarativo, porque você não está dizendo como obter o que deseja; você está apenas dizendo o que você quer. Você poderia dizer o mesmo sobre o SQL.

Um benefício da programação declarativa é que ela permite que o compilador tome decisões que possam resultar em um código melhor do que o que você poderia fazer à mão. Rodando com o exemplo SQL, se você tivesse uma consulta como

SELECT score FROM games WHERE id < 100;

o "compilador" SQL pode "otimizar" essa consulta porque sabe que id é um campo indexado - ou talvez não esteja indexado, caso em que terá que fazer a iteração de todo o conjunto de dados. Ou talvez o mecanismo SQL saiba que esse é o momento ideal para utilizar todos os 8 núcleos para uma pesquisa paralela rápida. Você , como programador, não está preocupado com nenhuma dessas condições e não precisa escrever seu código para lidar com qualquer caso especial dessa maneira.


Todas as respostas acima e outras mensagens on-line mencionam o seguinte:

  • Com a programação declarativa , você escreve um código que descreve o que você quer, mas não necessariamente como obtê-lo
  • Você deve preferir programação declarativa sobre a programação imperativa

O que eles não nos disseram é como alcançá-lo . Para que parte do programa seja mais declarativo, outras partes devem fornecer a abstração para ocultar os detalhes da implementação (que são os códigos imperativos ).

  • Por exemplo, LINQ é mais declarativo do que loops (for, while, etc.), por exemplo, você pode usar list.Where () para obter uma nova lista filtrada. Para que isso funcione, a Microsoft fez todo o trabalho pesado por trás da abstração do LINQ.

Na verdade, uma das razões pelas quais a programação funcional e as bibliotecas funcionais são mais declarativas é porque elas abstraíram loops e criações de listas, ocultando todos os detalhes da implementação (provavelmente códigos imperativos com loops) por trás da cena.

Em qualquer programa, você sempre terá ambos os códigos imperativo e declarativo, o que você deve procurar é esconder todos os códigos imperativos por trás das abstrações, para que outras partes do programa possam usá-los declarativamente .

Finalmente, embora a programação funcional e o LINQ possam tornar seu programa mais declarativo, você sempre pode torná-lo ainda mais declarativo, fornecendo mais abstrações. Por exemplo:

// JavaScript example

// Least declarative
var bestProducts = [];
for(var i = 0; i < products.length; i++) {
    var product = products[i];
    if (product.rating >= 5 && product.price < 100) {
        bestProducts.push(product);
    }
}


// More declarative
var bestProducts = products.filter(function(product) {
    return product.rating >= 5 && product.price < 100;
});

// Most declarative, implementation details are hidden in a function
var bestProducts = getBestProducts();

Um ótimo exemplo de programação declarativa versus imperativa é o LINQ.

Com a programação imperativa , você diz ao compilador o que você quer que aconteça, passo a passo.

Por exemplo, vamos começar com essa coleção e escolher os números ímpares:

List<int> collection = new List<int> { 1, 2, 3, 4, 5 };

Com uma programação imperativa, passamos por isso e decidimos o que queremos:

List<int> results = new List<int>();
foreach(var num in collection)
{
    if (num % 2 != 0)
          results.Add(num);
}

Aqui estamos dizendo:

  1. Crie uma coleção de resultados
  2. Percorra cada número na coleção
  3. Verifique o número, se for estranho, adicione-o aos resultados

Com a programação declarativa , por outro lado, você escreve um código que descreve o que você quer, mas não necessariamente como obtê-lo (declare seus resultados desejados, mas não o passo-a-passo):

var results = collection.Where( num => num % 2 != 0);

Aqui, estamos dizendo "Dê-nos tudo onde for estranho", não "Percorrer a coleção. Marque este item, se for estranho, adicione-o a uma coleção de resultados".

Em muitos casos, o código também será uma mistura dos dois designs, portanto, nem sempre é em preto e branco.


Programação imperativa
Uma linguagem de programação que requer disciplina de programação, como C / C ++, Java, COBOL, FORTRAN, Perl e JavaScript. Os programadores que escrevem nesses idiomas devem desenvolver uma ordem adequada de ações para resolver o problema, com base em um conhecimento de processamento e programação de dados.

Programação declarativa
Uma linguagem de computador que não requer a escrita da lógica de programação tradicional; Os usuários se concentram em definir a entrada e a saída, em vez das etapas do programa necessárias em uma linguagem de programação procedural, como C ++ ou Java.

Exemplos de programação declarativa são CSS, HTML, XML, XSLT, RegX.





declarative-programming