Sou desenvolvedor web há algum tempo e recentemente comecei a aprender programação funcional. Como outros, tive alguns problemas significativos ao aplicar muitos desses conceitos ao meu trabalho profissional. Para mim, a principal razão para isso é que vejo um conflito entre o objetivo da FP de permanecer apátrida parece bastante em desacordo com o fato de que a maioria dos trabalhos de desenvolvimento da Web que eu fiz foi fortemente vinculada a bancos de dados, que são muito centrados em dados.
Uma coisa que me tornou um desenvolvedor muito mais produtivo foi a descoberta de mapeadores de objetos relacionais, como MyGeneration d00dads para .Net, Class :: DBI para perl, ActiveRecord para ruby, etc. Isso me permitiu ficar longe desde escrever, inserir e selecionar instruções o dia todo, e concentrar-se em trabalhar com os dados facilmente como objetos. Obviamente, eu ainda poderia escrever consultas SQL quando a energia delas fosse necessária, mas, caso contrário, ela seria bem resumida nos bastidores.
Agora, voltando-se para a programação funcional, parece que em muitas estruturas da Web FP, como o Links, é necessário escrever muito código sql padrão, como neste exemplo . Weblocks parece um pouco melhor, mas parece usar um tipo de modelo OOP para trabalhar com dados e ainda exige que o código seja escrito manualmente para cada tabela em seu banco de dados, como neste exemplo . Suponho que você use alguma geração de código para escrever essas funções de mapeamento, mas isso parece decididamente não-cibernético.
(Observe que não observei os Weblocks ou Links com muita atenção; talvez eu esteja entendendo mal como eles são usados).
Portanto, a pergunta é: para as partes de acesso ao banco de dados (que eu acredito que são muito grandes) do aplicativo Web ou outro desenvolvimento que requer interface com um banco de dados sql, parecemos ser forçados a seguir um dos seguintes caminhos:
- Não use programação funcional
- Acessar dados de uma maneira irritante e sem abstração, que envolve escrever manualmente muitos códigos SQL ou semelhantes a SQL
- Force a nossa linguagem funcional a um paradigma de pseudo-POO, removendo assim um pouco da elegância e estabilidade da verdadeira programação funcional.
Claramente, nenhuma dessas opções parece ideal. Encontrou uma maneira de contornar esses problemas? Existe mesmo um problema aqui?
Nota: Pessoalmente, eu estou mais familiarizado com o LISP na parte frontal do FP, portanto, se você quiser dar exemplos e conhecer vários idiomas FP, o lisp provavelmente será o idioma preferido
PS: Para questões específicas para outros aspectos do desenvolvimento da Web, consulte esta pergunta .
fonte
Respostas:
Antes de tudo, eu não diria que o CLOS (Common Lisp Object System) é "pseudo-OO". É OO de primeira classe.
Segundo, acredito que você deve usar o paradigma que se adapta às suas necessidades.
Você não pode armazenar dados sem estado, enquanto uma função é fluxo de dados e realmente não precisa de estado.
Se você tem várias necessidades misturadas, misture seus paradigmas. Não se limite a usar apenas o canto inferior direito da sua caixa de ferramentas.
fonte
Chegando a isso da perspectiva de uma pessoa de banco de dados, acho que os desenvolvedores de front-end se esforçam demais para encontrar maneiras de fazer com que os bancos de dados se ajustem ao seu modelo, em vez de considerar as maneiras mais eficazes de usar banco de dados que não são orientados a objetos ou funcionais, mas relacionais e usando teoria de conjuntos. Vi isso geralmente resultar em código com baixo desempenho. Além disso, cria um código difícil de ajustar o desempenho.
Ao considerar o acesso ao banco de dados, há três considerações principais: integridade dos dados (por que todas as regras de negócios devem ser aplicadas no nível do banco de dados e não através da interface do usuário), desempenho e segurança. O SQL foi escrito para gerenciar as duas primeiras considerações com mais eficiência do que qualquer linguagem de front-end. Porque é projetado especificamente para fazer isso. A tarefa de um banco de dados é muito diferente da tarefa de uma interface do usuário. É de se admirar que o tipo de código mais eficaz no gerenciamento da tarefa seja conceitualmente diferente?
E os bancos de dados mantêm informações críticas para a sobrevivência de uma empresa. É de se admirar que as empresas não estejam dispostas a experimentar novos métodos quando sua sobrevivência está em risco. Heck muitas empresas não estão dispostas a atualizar para novas versões do banco de dados existente. Portanto, existe um conservadorismo inerente no design do banco de dados. E é deliberadamente assim.
Eu não tentaria escrever T-SQL ou usar conceitos de design de banco de dados para criar sua interface de usuário. Por que você tentaria usar sua linguagem de interface e conceitos de design para acessar meu banco de dados? Porque você acha que o SQL não é chique (ou novo) o suficiente? Ou você não se sente confortável com isso? Só porque algo não se encaixa no modelo com o qual você se sente mais confortável, não significa que seja ruim ou errado. Isso significa que é diferente e provavelmente diferente por uma razão legítima. Você usa uma ferramenta diferente para uma tarefa diferente.
fonte
Você deve ler o artigo "Out of the Tar Pit" de Ben Moseley e Peter Marks, disponível aqui: "Out of the Tar Pit" (6 de fevereiro de 2006)
É um clássico moderno que detalha um paradigma / sistema de programação chamado Programação Funcional-Relacional. Embora não esteja diretamente relacionado aos bancos de dados, ele discute como isolar interações com o mundo externo (bancos de dados, por exemplo) do núcleo funcional de um sistema.
O artigo também discute como implementar um sistema em que o estado interno do aplicativo é definido e modificado usando uma álgebra relacional, que obviamente está relacionada a bancos de dados relacionais.
Este documento não fornecerá uma resposta exata de como integrar bancos de dados e programação funcional, mas ajudará você a projetar um sistema para minimizar o problema.
fonte
As linguagens funcionais não têm o objetivo de permanecer sem estado, elas têm o objetivo de tornar explícito o gerenciamento de estado. Por exemplo, em Haskell, você pode considerar a mônada do Estado como o coração do estado "normal" e a mônada IO como uma representação do estado que deve existir fora do programa. Ambas as mônadas permitem (a) representar explicitamente ações com estado e (b) criar ações com estado, compondo-as usando ferramentas referencialmente transparentes.
Você faz referência a vários ORMs que, por seu nome, abstraem bancos de dados como conjuntos de objetos. Na verdade, não é isso que as informações em um banco de dados relacional representam! Por seu nome, ele representa dados relacionais. SQL é uma álgebra (linguagem) para lidar com relacionamentos em um conjunto de dados relacionais e, na verdade, é bastante "funcional". Trago isso à tona para considerar que (a) ORMs não são a única maneira de mapear informações de banco de dados, (b) que SQL é realmente uma linguagem bastante agradável para alguns projetos de banco de dados e (c) que linguagens funcionais geralmente têm álgebra relacional mapeamentos que expõem o poder do SQL de uma maneira idiomática (e no caso de Haskell, verificado de forma tipográfica).
Eu diria que a maioria dos lisps é a linguagem funcional de um homem pobre. É totalmente capaz de ser usado de acordo com práticas funcionais modernas, mas como não exige, é menos provável que a comunidade as use. Isso leva a uma mistura de métodos que podem ser altamente úteis, mas certamente obscurecem como interfaces funcionais puras ainda podem usar bancos de dados de maneira significativa.
fonte
Eu não acho que a natureza sem estado das linguagens fp seja um problema com a conexão com bancos de dados. Lisp é uma linguagem de programação funcional não pura, portanto não deve ter nenhum problema em lidar com o estado. E linguagens de programação funcionais puras, como Haskell, têm maneiras de lidar com entradas e saídas que podem ser aplicadas ao uso de bancos de dados.
Da sua pergunta, parece que seu principal problema está em encontrar uma boa maneira de abstrair os dados baseados em registros que você recebe do banco de dados em algo que é lisp-y (lisp-ish?) Sem precisar escrever muito SQL código. Isso parece mais um problema com as ferramentas / bibliotecas do que um problema com o paradigma da linguagem. Se você quer fazer FP puro, talvez o cisco não seja o idioma certo para você. Lisp comum parece mais sobre integrar boas idéias de oo, fp e outros paradigmas do que sobre fp puro. Talvez você deva usar Erlang ou Haskell se quiser seguir a rota FP pura.
Eu acho que as idéias de 'pseudo-oo' no lisp também têm seu mérito. Você pode experimentá-los. Se eles não se encaixam na maneira como você deseja trabalhar com seus dados, tente criar uma camada sobre Weblocks que permita trabalhar com os dados da maneira que desejar. Isso pode ser mais fácil do que escrever tudo sozinho.
Disclaimer: Eu não sou um especialista em Lisp. Estou interessado principalmente em linguagens de programação e tenho tocado com Lisp / CLOS, Scheme, Erlang, Python e um pouco de Ruby. Na vida diária da programação, ainda sou forçado a usar C #.
fonte
Se seu banco de dados não destruir informações, você poderá trabalhar com elas de maneira funcional, consistente com os valores de programação "puramente funcionais", trabalhando nas funções de todo o banco de dados como um valor.
Se no momento T o banco de dados declara que "Bob gosta de Suzie" e você possui uma função que aceita um banco de dados e um liker, desde que você possa recuperar o banco de dados no momento T, você tem um programa funcional puro que envolve um banco de dados . por exemplo
Para fazer isso, você nunca pode descartar as informações que você pode usar (o que, com toda a praticidade, significa que você não pode descartar as informações), portanto, suas necessidades de armazenamento aumentarão monotonicamente. Mas você pode começar a trabalhar com seu banco de dados como uma série linear de valores discretos, em que os valores subsequentes estão relacionados aos anteriores por meio de transações.
Essa é a principal idéia por trás da Datomic , por exemplo.
fonte
De modo nenhum. Há um gênero de bancos de dados conhecido como 'Bancos de Dados Funcionais', dos quais Mnesia é talvez o exemplo mais acessível. O princípio básico é que a programação funcional é declarativa, portanto pode ser otimizada. Você pode implementar uma junção usando Compreensões de lista em coleções persistentes, e o otimizador de consulta pode descobrir automaticamente como implementar o acesso ao disco.
Mnesia está escrito em Erlang e há pelo menos um framework da Web ( Erlyweb ) disponível para essa plataforma. Erlang é inerentemente paralelo a um modelo de encadeamento de nada compartilhado; portanto, de certa maneira, ele se presta a arquiteturas escalonáveis.
fonte
Um banco de dados é a maneira perfeita de acompanhar o estado em uma API sem estado. Se você se inscrever no REST, seu objetivo é escrever um código sem estado que interaja com um armazenamento de dados (ou algum outro back-end) que rastreie as informações de estado de maneira transparente, para que seu cliente não precise.
A idéia de um Mapeador Objeto-Relacional, em que você importa um registro de banco de dados como um objeto e depois o modifica, é tão aplicável e útil à programação funcional quanto à programação orientada a objetos. A única ressalva é que a programação funcional não modifica o objeto no local, mas a API do banco de dados pode permitir que você modifique o registro no local. O fluxo de controle do seu cliente ficaria assim:
O banco de dados atualizará o registro com suas alterações. A programação funcional pura pode impedir a reatribuição de variáveis no escopo do seu programa , mas a API do banco de dados ainda pode permitir atualizações no local.
fonte
Estou mais confortável com Haskell. A estrutura da Web Haskell mais proeminente (comparável ao Rails e Django) é chamada Yesod. Parece ter um ORM muito legal, com segurança de tipo e de back-end. Dê uma olhada no capítulo Persistência no livro.
fonte
Bancos de dados e programação funcional podem ser fundidos.
por exemplo:
Clojure é uma linguagem de programação funcional baseada na teoria de bancos de dados relacionais.
Nota: Na última especificação2, a especificação é mais parecida com o RMDB. veja: wiki spec-alpha2: Esquema e seleção
Defendo: Construir um modelo de dados relacionais sobre o mapa de hash para obter uma combinação de vantagens NoSQL e RMDB. Esta é realmente uma implementação reversa do posgtresql.
Digitação de pato: Se parece um pato e grasna como um pato, deve ser um pato.
Se o modelo de dados do clojure como um RMDB, as instalações do clojure como um RMDB e a manipulação de dados do clojure como um RMDB, o clojure deve ser um RMDB.
Clojure é uma linguagem de programação funcional baseada na teoria de bancos de dados relacionais
Tudo é RMDB
Implementar modelo de dados relacionais e programação com base no mapa de hash (NoSQL)
fonte