Pergunta

Eu tenho pesquisado na web procurando uma definição de programação declarativa e imperativa que esclareceria a minha luz. No entanto, o idioma usado em alguns dos recursos que encontrei é assustador - por exemplo Wikipedia. Alguém tem um exemplo do mundo real que eles poderiam me mostrar que pode trazer alguma perspectiva para esse assunto (talvez em C#)?

Foi útil?

Solução

Um ótimo exemplo C# de programação declarativa vs. imperativa é o LINQ.

Com imperativo Programação, você diz ao compilador o que deseja que aconteça, passo a passo.

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

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

Com a programação imperativa, passaríamos 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. Passe por cada número na coleção
  3. Verifique o número, se for estranho, adicione -o aos resultados

Com declarativo Programação, por outro lado, você escreve código que descreve o que deseja, mas não necessariamente como obtê-lo (declara os resultados desejados, mas não o passo a passo):

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

Aqui, estamos dizendo "Dê -nos tudo o que é estranho", não "passe pela coleção. Verifique este item, se for estranho, adicione -o a uma coleção de resultados".

Em muitos casos, o código também será uma mistura de ambos os designs, então nem sempre é preto e branco.

Outras dicas

A programação declarativa é quando você diz o que você quer, e a linguagem imperativa é quando você diz Como as Para conseguir o que você 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 "detalhes de implementação" da construção da lista.

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

Um benefício da programação declarativa é que ele permite que o compilador tome decisões que possam resultar em um código melhor do que o que você pode tomar manualmente. Correndo com o exemplo do SQL, se você tivesse uma consulta como

SELECT score FROM games WHERE id < 100;

O SQL "Compiler" pode "otimizar" esta consulta porque sabe disso id é um campo indexado - ou talvez não seja indexado; nesse caso, terá que iterar em todo o conjunto de dados. Ou talvez o mecanismo SQL saiba que este é o momento perfeito 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 você não precisa escrever seu código para lidar com nenhum caso especial dessa maneira.

Declarativo vs. Imperativo

UMA paradigma de programação é um estilo fundamental da programação de computadores. Existem quatro paradigmas principais: imperativo, declarativo, funcional (que é considerado um subconjunto do paradigma declarativo) e orientado a objetos.

Programação declarativa : é um paradigma de programação que expressa a lógica de um cálculo (o que faz) sem descrever seu fluxo de controle (como fazer). Alguns exemplos bem conhecidos de idiomas específicos de domínio declarativo (DSLs) incluem CSS, expressões regulares e um subconjunto de SQL (selecione consultas, por exemplo) muitos idiomas de marcação como HTML, MXML, XAML, XSLT ... são frequentemente declarativos. A programação declarativa tenta desfocar a distinção entre um programa como um conjunto de instruções e um programa como uma afirmação sobre a resposta desejada.

Programação imperativa : é um paradigma de programação que descreve a computação em termos de declarações que alteram um estado de programa. Os programas declarativos podem ser vistos duplamente como comandos de programação ou afirmações matemáticas.

Programação funcional: é um paradigma de programação que trata a computação como a avaliação das funções matemáticas e evita dados de estado e mutável. Ele enfatiza a aplicação de funções, em contraste com o estilo de programação imperativo, que enfatiza as mudanças no estado. Em uma linguagem funcional pura, como Haskell, todas as funções são sem efeitos colaterais, e as mudanças de estado são representadas apenas como funções que transformam o estado.

O exemplo a seguir de programação imperativa em Msdn, percorre os números de 1 a 10 e encontra os 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 odd"
var evenNumbers = numbersOneThroughTen.Select(number => number % 2 == 0);

Ambos os exemplos produzem o mesmo resultado, e um não é melhor nem pior que o outro. O primeiro exemplo requer mais código, mas o código é testável e a abordagem imperativa fornece controle total sobre os detalhes da implementação. No segundo exemplo, o código é indiscutivelmente mais legível; No entanto, o LINQ não fornece controle sobre o que acontece nos bastidores. Você deve confiar que o LINQ fornecerá o resultado solicitado.

Vou adicionar outro exemplo que raramente aparece na discussão declarativa/imperativa à programação: a interface do usuário!

Em C#, você pode criar uma interface do usuário usando várias tecnologias.

No final imperativo, você pode usar o DirectX ou OpenGL para desenhar muito imperativamente seus botões, caixas de seleção, etc ... linha a linha (ou realmente, triângulo por triângulo). Cabe a você dizer como desenhar a interface do usuário.

No fim declarativo, você tem WPF. Você basicamente escreve um XML (sim, sim, "xaml" tecnicamente) e a estrutura faz o trabalho para você. Você diz como é a interface do usuário. Cabe ao sistema descobrir como fazê -lo.

Enfim, apenas outra coisa em que pensar. Só porque um idioma é declarativo ou imperativo não significa que não tem certos recursos do outro.

Além disso, um benefício da programação declarativa é que esse objetivo geralmente é mais facilmente compreendido ao ler o código, enquanto o Imperativo oferece um controle mais refinado sobre a execução.

A essência de tudo:

Declarativo -> what você quer ter feito

Imperativo -> how Você quer fazer isso

Todas as respostas acima e outras postagens on -line mencionam a seguir:

  • Com declarativo Programação, você escreve código que descreve o que deseja, mas não necessariamente como obtê -lo
  • Você deve preferir a programação declarativa do que 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 imperativo códigos).

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

De fato, uma das razões pelas quais a programação funcional e as bibliotecas funcionais é mais declarativa é porque elas abstrairam loops e listam criações, ocultando todos os detalhes da implementação (os códigos imperativos provavelmente com loops) nos bastidores.

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

Por fim, 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
const bestProducts = [];
for(let i = 0; i < products.length; i++) {
    let product = products[i];
    if (product.rating >= 5 && product.price < 100) {
        bestProducts.push(product);
    }
}


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

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

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

  • Declarativo - especificamos o que façam, não como para fazer isso
    • Por exemplo: o HTML descreve o que deve aparecer em uma página da web, não como ela deve ser desenhada na tela
  • Imperativo - Especifique ambos o que e Como as
    • int x; - O que (declarativo)
    • x=x+1; - Como as

A programação imperativa exige que os desenvolvedores definam passo a passo como o código deve ser executado. Para dar instruções de maneira imperativa, você diz: "Vá para a 1st Street, vire à esquerda na Main, dirija dois quarteirões, vire à direita em Maple e pare na terceira casa à esquerda". A versão declarativa pode parecer algo assim: "Drive To Sue's House". Um diz como fazer algo; O outro diz o que precisa ser feito.

O estilo declarativo tem duas vantagens sobre o estilo imperativo:

  • Não force o viajante a memorizar um longo conjunto de instruções.
  • Ele permite que o viajante otimize a rota quando possível.

Calvert, C Kulkarni, D (2009). Linq essencial. Addison Wesley. 48.

A diferença tem principalmente a ver com o nível geral de abstração. Com declaração, em algum momento, você está tão longe das etapas individuais que o programa tem muita latitude sobre como obter seu resultado.


Você pode olhar para todas as instruções como caindo em algum lugar em um continuum:

Grau de abstração:

Declarative <<=====|==================>> Imperative

Exemplo declarativo do mundo real:

  1. Bibliotecário, confira uma cópia de Moby Dick. (Bibliotecário, a seu critério, escolhe o melhor método para executar a solicitação)

Exemplo imperativo do mundo real:

  1. Vá para a biblioteca
  2. Encontre o sistema de organização de livros (Catálogo de Cartas - Old School)
  3. Pesquise como usar catálogos de cartões (você também esqueceu, certo)
  4. Descubra como as prateleiras são rotuladas e organizadas.
  5. Descubra como os livros são organizados em uma prateleira.
  6. Localização do livro de referência cruzada do Card Catalog With Organization System para encontrar o referido livro.
  7. Pegue o livro para o sistema de check-out.
  8. Confira o livro.

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. Datalog / Prolog é o primeiro idioma que vem à mente a esse respeito. Basicamente, tudo é declarativo. Você realmente não pode garantir o pedido.

C# é uma linguagem de programação muito mais imperativa, mas certos recursos de 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};

O mesmo poderia ser escrito imperativamente:

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

(Exemplo da Wikipedia Linq)

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

A partir de http://en.wikipedia.org/wiki/Declarative_Programming

Em poucas palavras, a linguagem declarativa é mais simples porque não possui a complexidade do fluxo de controle (loops, se declarações, etc.)

Uma boa comparação é o modelo ASP.NET 'Code-Behind'. Você tem arquivos '.aspx' declarativos e, em seguida, os arquivos de código 'ASPX.CS' imperativos. Costumo achar que, se posso fazer tudo o que preciso na metade declarativa do roteiro, muito mais pessoas podem seguir o que está sendo feito.

Roubar de Philip Roberts aqui:

  • A programação imperativa diz à máquina como fazer algo (resultando no que você quer que aconteça)
  • A programação declarativa diz à máquina o que você gostaria que acontecesse (e o computador descobre como fazê -lo)

Dois exemplos:

1. Dobrar todos os números em uma matriz

Imperativamente:

var numbers = [1,2,3,4,5]
var doubled = []

for(var i = 0; i < numbers.length; i++) {
  var newNumber = numbers[i] * 2
  doubled.push(newNumber)
}
console.log(doubled) //=> [2,4,6,8,10]

Declarativamente:

var numbers = [1,2,3,4,5]

var doubled = numbers.map(function(n) {
  return n * 2
})
console.log(doubled) //=> [2,4,6,8,10]

2. Resumindo todos os itens em uma lista

Imperativamente

var numbers = [1,2,3,4,5]
var total = 0

for(var i = 0; i < numbers.length; i++) {
  total += numbers[i]
}
console.log(total) //=> 15

Declarativamente

var numbers = [1,2,3,4,5]

var total = numbers.reduce(function(sum, n) {
  return sum + n
});
console.log(total) //=> 15

Observe como os exemplos imperativos envolvem a criação de uma nova variável, a mutando e retornando esse novo valor (ou seja, como fazer algo acontecer), enquanto os exemplos declarativos são executados em uma dada entrada e retornam o novo valor com base na entrada inicial (ou seja, , o que queremos acontecer).

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 nessas linguagens devem desenvolver uma ordem de ação adequada para resolver o problema, com base no conhecimento do processamento e programação de dados.

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

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

Apenas para adicionar outro exemplo em termos de desenvolvimento de aplicativos móveis. No iOS e Android, temos construtores de interface, 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. O draeing real ocorre embaixo e executado pela estrutura e sistema.

Mas também podemos desenhar todos os componentes do código, e isso é imperativo de natureza.

Além disso, alguns novos idiomas, como o Angular JS, estão se concentrando em projetar declarativamente as UIs e podemos ver muitas outras línguas oferecendo o mesmo suporte. Como o Java não possui uma boa maneira declarativa de desenhar aplicativos de desktop nativos em Java Swing ou Java FX, mas no futuro próximo eles simplesmente podem.

O Programa Declarativo é apenas um dados para sua implementação imperativa "Universal" mais ou menos.

Valores: especificar apenas um dados, em algum formato codificado (e verificado), é mais simples e menos propenso a erros do que especificar diretamente de algum algoritmo imperativo. Algumas especificações complexas simplesmente não podem ser escritas diretamente, apenas em algum formulário DSL. Best e Freq usado nas estruturas de dados DSLS são conjuntos e tabelas. Porque você não tem dependências entre elementos/linhas. E quando você não tem dependências, você tem liberdade para modificar e facilitar o apoio. (Compare, por exemplo, módulos com as classes - com módulos que você está feliz e com as aulas, você tem um problema frágil da classe base) Todos os bens de declaração e DSL segue imediatamente a partir dos benefícios dessas estruturas de dados (tabelas e conjuntos). Outra vantagem-você pode alterar a implementação da VM da linguagem declarativa, se o DSL for um resumo mais ou menos (bem projetado). Faça implementação paralela, por exemplo. ou porta para outros sistemas operacionais etc. Todas as boas interfaces ou protocolos de isolamento modular especificados oferecem tanta liberdade e fácilza de suporte.

Menus: você acha que certo. O algoritmo imperativo genérico (e parametrizado por DSL)/a implementação da VM pode estar mais lento e/ou com fome de memória do que um específico. em alguns casos. Se esses casos forem raros - apenas esqueça, deixe -o ser lento. Se for frequente - você sempre pode estender seu DSL/VM para esse caso. Em algum lugar desacelerando todos os outros casos, com certeza ...

O PS Frameworks é meio entre DSL e Imperativo. E como todas as soluções de meio caminho ... eles combinam deficiências, não benefícios. Eles não são tão seguros e nem tão rápidos :) Olhe para Haskell de Jack-of-All-Trades-está a meio caminho entre o ML simples e o Metaprog Prolog flexível e ... que monstro é. Você pode considerar o Prolog como um Haskell com funções/predicados somente booleanos. E quão simples é sua flexibilidade contra Haskell ...

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

De acordo com a Wikipedia

As linguagens declarativas comuns incluem as das 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, o 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#

Pelo meu entendimento, ambos os termos têm raízes na filosofia, existem tipos declarativos e imperativos de conhecimento. Conhecimento declarativo são afirmações da verdade, declarações de fato como axiomas matemáticos. Ele te diz algo. Conhecimento imperativo, ou processual, diz que você passo a passo como chegar a alguma coisa. É essencialmente a definição de um algoritmo. Se você fizer, compare uma linguagem de programação de computador com o idioma inglês. As sentenças declarativas indicam algo. Um exemplo chato, mas aqui está uma maneira declarativa de mostrar se dois números são iguais um ao outro, em Java:

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

As frases imperativas em inglês, por outro lado, dão um comando ou faça 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 demonstrar se dois números são iguais ou não enquanto aceitam 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, conhecimento declarativo pula Certos elementos para formar uma camada de abstração sobre esses elementos. A programação declarativa faz o mesmo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top