Eu tenho pesquisado na web procurando uma definição para programação declarativa e imperativa que me esclarecesse alguma coisa. 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 possam me mostrar que possa trazer alguma perspectiva para esse assunto (talvez em C #)?
541
Respostas:
Um ótimo exemplo de C # de programação declarativa vs. imperativa é o LINQ.
Com a programação imperativa , 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:
Com a programação imperativa, passaríamos por isso e decidiríamos o que queremos:
Aqui, estamos dizendo:
Com a programação declarativa , por outro lado, você escreve o código que descreve o que deseja, mas não necessariamente como obtê-lo (declare os resultados desejados, mas não o passo a passo):
Aqui, estamos dizendo "Dê-nos tudo o que for estranho", não "Passe pela coleção. Marque esse 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.
fonte
collection.Where
não está usando a sintaxe declarativa que o Linq fornece - consulte msdn.microsoft.com/en-us/library/bb397906.aspx para obter exemplos,from item in collection where item%2 != 0 select item
seria o formulário declarativo. Chamar uma função não se torna programação declarativa apenas porque essa função está no espaço para nome System.Linq.A programação declarativa é quando você diz o que deseja e a linguagem imperativa é quando você diz como conseguir o que deseja.
Um exemplo simples em Python:
O primeiro exemplo é declarativo porque não especificamos nenhum "detalhe de implementação" da criação da lista.
Para vincular um exemplo de C #, geralmente, o uso de LINQ resulta em um estilo declarativo, porque você não está dizendo como obter o que deseja; você está apenas dizendo o que deseja. Você poderia dizer o mesmo sobre SQL.
Um benefício da programação declarativa é que ele permite ao compilador tomar decisões que podem resultar em código melhor do que o que você pode fazer manualmente. Executando com o exemplo SQL, se você tivesse uma consulta como
o "compilador" do SQL pode "otimizar" essa consulta porque sabe que
id
é um campo indexado - ou talvez não esteja indexado; nesse caso, terá que iterar todo o conjunto de dados de qualquer maneira. Ou talvez o mecanismo SQL saiba que esse é o momento perfeito para utilizar todos os 8 núcleos para uma rápida pesquisa paralela. Você , como programador, não está preocupado com nenhuma dessas condições e não precisa escrever seu código para lidar com nenhum caso especial dessa maneira.fonte
filter(lambda x: x < 5, range(20))
é apenas mais uma refatoração em uma notação mais curta. Isso não difere de maneira significativa da expressão de compreensão da lista (que possui seções "mapa" e "filtro" claras), que foi criada (consulte pep 202 ) com a intenção explícita de criar uma notação mais concisa. E a compreensão dessa lista seria mais clara / idiomática nesse caso.Declarativo vs. Imperativo
Um paradigma de programação é um estilo fundamental de 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 uma computação (O que fazer) sem descrever seu fluxo de controle (Como fazer). Alguns exemplos conhecidos de linguagens declarativas de domínio específico (DSLs) incluem CSS, expressões regulares e um subconjunto de SQL (consultas SELECT, por exemplo) Muitas linguagens de marcação como HTML, MXML, XAML, XSLT ... geralmente são declarativas. A programação declarativa tenta embaçar 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 o estado de um programa. Os programas declarativos podem ser visualizados dupla- mente como comandos de programação ou asserções matemáticas.
Programação funcional: é um paradigma de programação que trata a computação como a avaliação de funções matemáticas e evita dados de estado e mutáveis. Ele enfatiza a aplicação de funções, em contraste com o estilo de programação imperativa, que enfatiza as mudanças de estado. Em uma linguagem funcional pura, como Haskell, todas as funções não têm efeitos colaterais e as alterações de estado são representadas apenas como funções que transformam o estado.
O exemplo a seguir de programação imperativa no MSDN , percorre os números de 1 a 10 e localiza os números pares.
Ambos os exemplos produzem o mesmo resultado, e um não é nem 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.
fonte
Todas as respostas acima e outras postagens on-line mencionam o seguinte:
O que eles não nos disseram é como alcançá-lo . Para que parte do programa seja mais declarativa, outras partes devem fornecer a abstração para ocultar os detalhes da implementação (que são os códigos imperativos ).
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.De fato, uma das razões pelas quais a programação funcional e as bibliotecas funcionais são mais declarativas é porque abstraíram loops e listam criações, ocultando todos os detalhes da implementação (provavelmente códigos imperativos com loops) nos bastidores.
Em qualquer programa, você sempre terá códigos imperativos e declarativos, o que você deve procurar é ocultar todos os códigos imperativos atrás das abstrações, para que outras partes do programa possam usá-los 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:
PS o extremo da programação declarativa é inventar novas linguagens específicas de domínio (DSL):
fonte
debit
,deposit
, etc., em vez de repetir código imparativeaccount.balance += depositAmount
Vou adicionar outro exemplo que raramente aparece na discussão sobre programação declarativa / imperativa: 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 o OpenGL para desenhar imperativamente seus botões, caixas de seleção, etc. linha por linha (ou, na verdade, triângulo por triângulo). Cabe a você dizer como desenhar a interface do usuário.
No final 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 mais uma coisa para pensar. Só porque um idioma é declarativo ou imperativo, não significa que ele não tenha certas características do outro.
Além disso, um benefício da programação declarativa é que o objetivo geralmente é mais facilmente compreendido pela leitura do código, enquanto que o imperativo fornece um controle mais preciso sobre a execução.
A essência de tudo:
Declarativo ->
what
você quer fazerImperativo ->
how
você quer que seja feitofonte
Gostei de uma explicação de um curso de Cambridge + dos exemplos deles:
int x;
- o que (declarativo)x=x+1;
- comofonte
CSS
é imperativo então?A diferença tem a ver principalmente com o nível geral de abstração. Com declarativo, em algum momento, você está tão longe das etapas individuais que o programa tem muita margem de lucro em relação a como obter seu resultado.
Você pode considerar cada instrução como caindo em algum lugar em um continuum:
Grau de abstração:
Exemplo declarativo do mundo real:
Exemplo imperativo do mundo real:
fonte
Calvert, C Kulkarni, D (2009). LINQ essencial. Addison Wesley. 48)
fonte
A programação imperativa é dizer explicitamente ao computador o que fazer e como fazê-lo, como especificar a ordem e tal
C #:
Declarativo é quando você diz ao computador o que fazer, mas não como realmente fazê-lo. Datalog / Prolog é a primeira língua 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 de C # são mais declarativos, como o Linq
A mesma coisa pode ser escrita imperativamente:
(exemplo da wikipedia Linq)
fonte
De http://en.wikipedia.org/wiki/Declarative_programming
em poucas palavras, a linguagem declarativa é mais simples porque carece da complexidade do fluxo de controle (loops, se, etc.)
Uma boa comparação é o modelo 'code-behind' do ASP.Net. Você tem arquivos declarativos '.ASPX' e, em seguida, os arquivos de código imperativos 'ASPX.CS'. Costumo achar que, se eu puder fazer tudo o que preciso na metade declarativa do script, muito mais pessoas poderão acompanhar o que está sendo feito.
fonte
Roubando de Philip Roberts aqui :
Dois exemplos:
1. Dobrar todos os números em uma matriz
Imperativamente:
Declarativamente:
2. Somando todos os itens em uma lista
Imperativamente
Declarativamente
Observe como os exemplos imperativos envolvem a criação de uma nova variável, a mutação e o retorno desse novo valor (ou seja, como fazer algo acontecer), enquanto os exemplos declarativos são executados em uma determinada entrada e retornam o novo valor com base na entrada inicial (ou seja, , o que queremos que aconteça).
fonte
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 adequada de ações para resolver o problema, com base no 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 na definição da entrada e da 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 declarativos são CSS, HTML, XML, XSLT, RegX.
fonte
programa declarativo é apenas um dado para sua implementação imperativa mais ou menos "universal" / vm.
vantagens: especificar apenas um dado, em algum formato codificado (e verificado), é mais simples e menos suscetível a erros do que especificar diretamente a variante de algum algoritmo imperativo. algumas especificações complexas simplesmente não podem ser escritas diretamente, apenas em alguma forma DSL. best e freq usados 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 possui dependências, tem liberdade para modificar e facilitar o suporte. (compare, por exemplo, módulos com classes - com módulos felizes e com classes com problemas frágeis de classe base) todos os bens de declaratividade e DSL seguem imediatamente os benefícios dessas estruturas de dados (tabelas e conjuntos). outra vantagem - você pode alterar a implementação da linguagem declarativa vm, se o DSL for mais ou menos abstrato (bem projetado). faça implementação paralela, por exemplo.
desvantagens: você acha certo. A implementação de algoritmo imperativo genérico (e parametrizado por DSL) / vm pode ser mais lenta e / ou com menos memória do que uma específica. em alguns casos. se esses casos forem raros - esqueça, deixe-o lento. se for frequente - você sempre poderá estender seu DSL / vm para esse caso. em algum lugar atrasando todos os outros casos, com certeza ...
PS Frameworks está a meio caminho entre DSL e imperativo. e como todas as soluções intermediárias ... elas combinam deficiências, não benefícios. eles não são tão seguros E não são tão rápidos :) olhe para o haskell do tipo "tudo de todos" - está a meio caminho entre um ML simples e forte e o metaprog flexível Prolog e ... que monstro ele é. você pode ver o Prolog como um Haskell com funções / predicados somente booleanos. e quão simples é sua flexibilidade contra Haskell ...
fonte
Eu 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
Portanto, o LINQ, como sintaxe funcional, é definitivamente um método declarativo, mas as classes Attribute em C #, como 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 em C #
fonte
Apenas para adicionar outro exemplo em termos de desenvolvimento de aplicativos para dispositivos móveis. No iOS e Android, temos os 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. O desenho real acontece por baixo e é executado pela estrutura e pelo sistema.
Mas também podemos desenhar todos os componentes no código, e isso é de natureza imperativa.
Além disso, algumas novas linguagens, como o Angular JS, estão focando no design de UIs declarativamente e podemos ver muitas outras linguagens oferecendo o mesmo suporte. Como o Java não tem uma boa maneira declarativa de desenhar aplicativos de desktop nativos em Java swing ou Java FX, mas em um futuro próximo, eles apenas poderão.
fonte
Do meu entendimento, ambos os termos têm raízes na filosofia, existem tipos de conhecimento declarativos e imperativos. Conhecimento declarativo são afirmações da verdade, declarações de fato como axiomas matemáticos. Isso diz uma coisa. O conhecimento imperativo ou processual diz a você passo a passo como chegar a algo. Isso é o que é essencialmente a definição de um algoritmo. Se preferir, compare uma linguagem de programação de computadores com a língua inglesa. Frases declarativas afirmam algo. Um exemplo chato, mas aqui está uma maneira declarativa de exibir se dois números são iguais entre si, em Java:
Frases 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 aquilo). Aqui está uma maneira imperativa de exibir se dois números são iguais um ao outro ou não ao aceitar a entrada do usuário, em Java:
Essencialmente, o conhecimento declarativo pula certos elementos para formar uma camada de abstração sobre esses elementos. A programação declarativa faz o mesmo.
fonte