FP para simulação e modelagem

12

Estou prestes a iniciar um projeto de simulação / modelagem. Eu já sei que o OOP é usado para esse tipo de projeto. No entanto, estudar Haskell me fez pensar em usar o paradigma FP para modelar um sistema de componentes. Deixe-me elaborar:

Digamos que eu tenha um componente do tipo A, caracterizado por um conjunto de dados (um parâmetro como temperatura ou pressão, um PDE e algumas condições de contorno, etc.) E um componente do tipo B, caracterizado por um conjunto de dados diferente (diferente ou mesmo parâmetro, PDE diferente e condições de contorno). Suponhamos também que as funções / métodos que serão aplicados em cada componente sejam os mesmos (um método de Galerkin, por exemplo). O estado mutável do objeto seria usado para parâmetros não constantes.

Se eu usasse uma abordagem OOP, criaria dois objetos que encapsulariam os dados de cada tipo, os métodos para resolver o PDE (a herança seria usada aqui para reutilização de código) e a solução para o PDE.

Por outro lado, se eu usasse uma abordagem FP, cada componente seria dividido em partes de dados e nas funções que atuariam sobre os dados para obter a solução para o PDE. Parâmetros não constantes seriam passados ​​como funções de outra coisa (tempo, por exemplo) ou expressos por algum tipo de mutabilidade (emulação de mutabilidade, etc.) Essa abordagem parece mais simples para mim, assumindo que operações lineares em dados seriam triviais.

Para concluir, a implementação da abordagem FP seria realmente mais simples e mais fácil de gerenciar (adicione um tipo diferente de componente ou novo método para resolver o PDE) em comparação com a abordagem OOP?

Eu venho de um background C ++ / Fortran, além de não ser um programador profissional, portanto, corrija-me em qualquer coisa que eu tenha errado.

heaptobesquare
fonte

Respostas:

7

Boa pergunta, eu tenho pensado em linhas semelhantes. Historicamente, o paradigma OO surgiu da necessidade de simulação por computador - veja a história do Simula - e, apesar das linguagens OO iniciais, como o Smalltalk, serem feitas por pessoas que sabiam o que estavam fazendo (por exemplo, Alan Kay), o OO agora é indiscutivelmente usado e traz muita complexidade acidental .

Geralmente, os programas no estilo FP serão mais curtos, mais fáceis de testar e mais fáceis de modificar do que os programas OO. Como Rob Harrop disse em sua palestra: O futuro é funcional? , você nunca pode ficar mais simples que funções e dados; os dois compõem infinitamente, para construir quaisquer abstrações necessárias. Portanto, uma maneira de responder sua pergunta (ou estou apenas reafirmando? :) é perguntar: Qual é a função de nível mais alto e os dados de entrada de nível mais alto -> dados de saída? Em seguida, você pode começar a dividir essas funções e tipos de dados "alfa" na próxima camada de abstrações e repetir conforme necessário.

Outra perspectiva (não exatamente respostas) da sua pergunta é olhar para este tópico (aviso de isenção de responsabilidade, eu o iniciei) no StackOverflow, algumas das respostas são muito interessantes: /programming/3431654/how-does- programação funcional-aplicar-a-simulações

Minha opinião neste momento é que, a menos que você esteja modelando uma situação em que realmente existem objetos discretos que apenas interagem de maneiras definidas (por exemplo, um modelo de rede de computadores) - e, portanto, mapeiam diretamente os recursos de um ambiente limpo de mensagens. linguagem OO de paradigma de passagem - é mais simples usar FP. Observe que mesmo na comunidade de programação de jogos - onde as simulações são muito prevalentes e os requisitos de desempenho são primordiais - desenvolvedores experientes estão se afastando do paradigma OO e / ou usando mais FP, por exemplo, veja esta discussão sobre HN ou os comentários de John Carmack sobre FP

limist
fonte
É bom saber que não sou o único a duvidar de OOP na simulação e obrigado por responder à minha pergunta! Eu tinha lido os comentários de John Carmack no FP e pensei em implementar alguns aspectos do FP no C ++ (copiar os objetos ou coletar a entrada e passá-la para uma função), mas novamente não sei se devo iniciar meu projeto com C ++ em vez de uma linguagem FP, como Haskell, pois os aspectos FP são incorporados e você expressa mutabilidade apenas quando necessário. Você continuou usando o Clojure ou o FP em geral, considerando que tinha um problema / pergunta semelhante?
Heaptobesquare
@heaptobesquare - Sim, eu tenho aumentado meu Clojure-fu com o objetivo de escrever simulações nele. Ainda não há nada pronto para mostrar, mas não vejo interrupções, e o design de Clojure é lindamente pragmático, por exemplo, você pode usar transientes / mutações, se necessário, além de seus agentes serem adequados a aspectos assíncronos. Em algum momento (não há promessas quando), escreverei um artigo sobre o tópico ... #
292
Dei uma olhada no Clojure, mas não posso dizer que gosto de expressões em S. Eu sei que é prático (código Lisp é dados), mas é fácil se acostumar?
Heaptobesquare
@heaptobesquare - S-expressões / Lisp sintaxe é realmente muito fácil de se acostumar; primeiro escolha um bom editor (Emacs ou vim, meu voto é para o Emacs, consulte dev.clojure.org/display/doc/Getting+Started+with+Emacs ) que possui um modo para o Clojure, obtenha um bom livro (por exemplo, Programming Clojure ) e comece a invadir. Depois de algumas semanas, no máximo, a sintaxe desaparecerá em segundo plano, como deveria - é tão perfeitamente consistente que você pensará exponencialmente com menos frequência e liberará ciclos mentais para coisas mais importantes. :)
limist
Definitivamente vou tentar. Afinal, a homoiconicidade de Lisp é interessante.
Heaptobesquare
2

IMHO para quase todas as tarefas de complexidade razoável, a pergunta "é um estilo FP ou OOP, a melhor escolha" não pode ser respondida objetivamente. Normalmente, em tal situação, a questão não é "FP ou OOP", mas como combinar as melhores partes dos dois paradigmas para resolver o seu problema.

O problema que você examinou acima parece ser muito matemático, e acho que você precisará de algumas operações de matriz. OOP é muito bom para modelar tipos de dados abstratos, e o cálculo de matriz pode ser facilmente implementado como "objetos de matriz" com operações em matrizes. Implementar isso de uma maneira em que todas as operações da matriz fazem parte de uma classe de matriz ajuda a manter as coisas que pertencem juntas, mantendo assim uma boa estrutura geral.

Por outro lado, os PDEs são equações de funções e a solução pode funcionar novamente. Portanto, usar uma abordagem funcional para esse tipo de "componentes" pode parecer natural aqui. Essas funções podem ter parâmetros de matriz, mostrando um exemplo de como combinar OOP e FP. Outro exemplo seria uma implementação de classe de matriz, que usa ferramentas funcionais para mapear uma determinada operação para cada elemento da sua matriz. Portanto, aqui também não é "OOP versus FP", mas "OOP combinado com FP" que oferece os melhores resultados.

Doc Brown
fonte
Obrigado pela sua resposta! Então, se eu onde usar C ++, encapsularia apenas os dados (ou seja, parâmetros, condições de contorno e PDE em forma de matriz) do componente para um objeto e definir as funções (mesmo algumas de ordem superior, no caso de um parâmetro é uma função de outra coisa), fora do escopo do objeto, que operaria nos dados do objeto, seria eficiente?
Heaptobesquare
@heaptobesquare: sinceramente, não sei dizer se será eficiente no seu caso. Experimente, pense grande, comece pequeno. Comece a programar algum "código rastreador" ( artima.com/intv/tracer.html ) para descobrir o que funciona melhor e o que não funciona. E se você chegar a uma situação em que percebe que algo não funciona corretamente, refatorar.
Doc Brown
Haskell tem a biblioteca Hmatrix, que é uma ligação para as bibliotecas BLAS / LAPACK, e uma sintaxe muito boa, que eu escolheria pessoalmente em uma abordagem OOP.
paul
@ paul: Obrigado, eu definitivamente vou dar uma olhada! As bibliotecas Haskell são geralmente consistentes e ricas em conteúdo? Os wikis dizem isso, mas isso é um fato?
Heaptobesquare
@heaptobesquare: A única biblioteca Haskell que já usei é o Parsec (usei para escrever um assembler), mas adorei usá-lo. Eu só fiz a exploração GHCI do Hmatrix e das ligações Haskell OpenGL, mas elas parecem bastante agradáveis. O Hmatrix parece quase tão conciso quanto o MATLAB (que já usei bastante) - que foi feito especificamente para esse tipo de coisa. Pela minha experiência limitada, as bibliotecas são consistentes - isso ocorre porque o Haskell é construído em um pequeno número de blocos de construção simples - e também são ricos porque os Haskellers não gostam de fazer coisas mundanas :)
paul