ФП для симуляции и моделирования

12

Я собираюсь начать проект моделирования / моделирования. Я уже знаю, что ООП используется для такого рода проектов. Однако изучение Haskell заставило меня задуматься об использовании парадигмы FP для моделирования системы компонентов. Позвольте мне уточнить:

Допустим, у меня есть компонент типа A, характеризуемый набором данных (такой параметр, как температура или давление, PDE и некоторые граничные условия и т. Д.), И компонент типа B, характеризующийся другим набором данных (отличающимся или один и тот же параметр, разные PDE и граничные условия). Предположим также, что функции / методы, которые будут применяться к каждому компоненту, одинаковы (например, метод Галеркина). Изменчивое состояние объекта будет использоваться для непостоянных параметров.

Если бы я использовал подход ООП, я бы создал два объекта, которые будут инкапсулировать данные каждого типа, методы для решения PDE (здесь будет использоваться наследование для повторного использования кода) и решение для PDE.

С другой стороны, если бы я использовал подход FP, каждый компонент был бы разбит на части данных и функции, которые воздействовали бы на данные, чтобы получить решение для PDE. Непостоянные параметры будут передаваться как функции чего-то другого (например, времени) или выражаться некоторой изменчивостью (эмуляция изменчивости и т. Д.). Этот подход мне кажется более простым, если предположить, что линейные операции с данными будут тривиальными.

В заключение, будет ли реализация подхода FP на самом деле проще и проще в управлении (добавить компонент другого типа или новый метод для решения pde) по сравнению с ООП?

Я родом из C ++ / Fortran, плюс я не профессиональный программист, поэтому поправьте меня во всем, что я ошибся.

heaptobesquare
источник

Ответы:

7

Хороший вопрос, я думал в том же духе. Исторически ОО-парадигма возникла из-за необходимости компьютерного моделирования - посмотрите историю Simula - и, несмотря на то, что ранние ОО-языки, такие как Smalltalk , создавались людьми, которые знали, что они делали (например, Алан Кей), ОО сейчас, вероятно, чрезмерно используются и вносит слишком много случайных сложностей .

Как правило, программы в стиле FP будут короче, проще для тестирования и проще в модификации, чем программы OO. Как сказал Роб Харроп в своем выступлении: «Будущее функционирует?» , вы никогда не можете стать проще, чем функции и данные; эти два составляют бесконечно, чтобы построить любые абстракции, необходимые. Итак, один из способов ответить на ваш вопрос (или я просто повторяю его? :) - это спросить, как выглядит функция высшего уровня, а как выглядят данные верхнего уровня -> выходные данные? Затем вы можете начать разбивать эти «альфа» функции и типы данных на следующий уровень абстракций и повторять при необходимости.

Другая точка зрения (не совсем ответы) на ваш вопрос заключается в том, чтобы взглянуть на эту ветку (заявление об отказе, я ее начал) в StackOverflow, некоторые ответы очень интересны: /programming/3431654/how-does- функционально-программирование применить к симуляции

Мое собственное мнение на данный момент таково, если вы не моделируете ситуацию, когда действительно существуют дискретные объекты, которые взаимодействуют только определенным образом (например, модель компьютерной сети) - и, таким образом, отображаются непосредственно на возможности чистого сообщения. Проходная парадигма ОО языка - проще перейти на ФП. Обратите внимание, что даже в сообществе разработчиков игр, где моделирование очень распространено и требования к производительности имеют первостепенное значение, опытные разработчики отходят от ОО-парадигмы и / или используют больше FP, например, см. Это обсуждение HN или комментарии Джона Кармака по FP

limist
источник
Приятно знать, что я не единственный, кто сомневается в ООП в симуляции, и спасибо за ответ на мой вопрос! Я читал комментарии Джона Кармака по FP и думал о реализации некоторых аспектов FP на C ++ (копирование объектов или сбор входных данных и передача их в функцию), но опять же я не знаю, должен ли я начать свой проект с C ++ вместо языка FP, такого как Haskell, аспекты FP встроены, и вы выражаете изменчивость только тогда, когда это необходимо. Вы продолжали использовать Clojure или FP в целом, учитывая, что у вас была похожая проблема / вопрос?
heaptobesquare
@heaptobesquare - Да, я неуклонно наращиваю моё Clojure-fu с целью написания в нем симуляций. Ничего готового к показу пока нет, но я не вижу стоп-шоу, и дизайн Clojure прекрасно прагматичен, например, вы можете использовать переходные процессы / мутации, если это необходимо, плюс его агенты хорошо подходят для асинхронных аспектов. В какой-то момент (без обещаний, когда) я напишу статью на эту тему ...
limist
Я взглянул на Clojure, но не могу сказать, что мне нравятся S-выражения. Я знаю, что это практично (код Lisp - это данные), но легко ли привыкнуть?
heaptobesquare
@heaptobesquare - s-выражения / синтаксис Lisp на самом деле очень легко привыкнуть; сначала выберите хорошего редактора (Emacs или vim, мой голос за Emacs, см. dev.clojure.org/display/doc/Getting+Started+with+Emacs ), в котором есть режим для Clojure, найдите хорошую книгу (например, Programming Clojure ) и начать взлом. Самое большее, через несколько недель, синтаксис уйдет на задний план, как и должно быть - он настолько идеален, что вы будете думать об этом экспоненциально реже, и освободите психические циклы для более важных вещей. :)
limist
Тогда я обязательно попробую. Гомиконичность Лиспа интересна в конце концов.
heaptobesquare
2

ИМХО почти для каждой задачи разумной сложности на вопрос «является ли стиль FP или стиль ООП лучшим выбором» нельзя ответить объективно. Как правило, в такой ситуации вопрос заключается не в «FP или OOP», а в том, как объединить лучшие части обеих парадигм для решения вашей проблемы.

Проблема, которую вы описали выше, кажется очень математической, и я предполагаю, что вам потребуются некоторые матричные операции. ООП очень хорош для моделирования абстрактных типов данных, и матричное исчисление может быть легко реализовано как «матричные объекты» с операциями над матрицами. Реализация этого таким образом, что все матричные операции являются частью матричного класса, помогает вам объединять вещи, которые принадлежат друг другу, таким образом поддерживая хорошую общую структуру.

С другой стороны, PDE являются уравнениями на функциях, и решение может снова быть функциональным. Таким образом, использование функционального подхода для этого типа «компонентов» может показаться здесь естественным. Эти функции могут иметь параметры матрицы, показывая один пример того, как объединить ООП и FP. Другим примером может быть реализация класса матрицы, которая использует функциональные инструменты для сопоставления определенной операции с каждым элементом вашей матрицы. Так что и здесь, это не «ООП против ФП», а «ООП в сочетании с ФП», который приносит вам лучшие результаты.

Док Браун
источник
Спасибо за ваш ответ! Таким образом, если бы я использовал C ++, инкапсулировал бы только данные (то есть параметры, граничные условия и PDE в матричной форме) компонента в объект и определял функции (даже некоторые из них более высокого порядка, в случае параметр является функцией чего-то другого), вне области объекта, который будет работать с данными объекта, будет ли эффективен?
heaptobesquare
@heaptobesquare: честно, я не могу сказать вам, будет ли это эффективно в вашем случае. Попробуйте, подумайте масштабно, начните с малого. Начните программировать некоторый «код трассировки» ( artima.com/intv/tracer.html ), чтобы узнать, что работает лучше, а что нет. И если вы попадаете в ситуацию, когда замечаете, что что-то не работает должным образом, проводите рефакторинг.
Док Браун
На Haskell есть библиотека Hmatrix, которая является связыванием для библиотек BLAS / LAPACK, и очень хороший синтаксис для нее, который я бы выбрал лично, используя подход ООП.
Пол
@Paul: Спасибо, я обязательно посмотрю на это! Являются ли библиотеки Haskell в целом согласованными и содержательными? Вики так говорят, но так ли это?
heaptobesquare
@heaptobesquare: единственная библиотека на Haskell, которую я когда-либо использовал, - это Parsec (я использовал ее для написания ассемблера), но я любил ее использовать. Я только исследовал привязки Hmatrix и Haskell OpenGL в GHCI, но они кажутся довольно хорошими. Hmatrix выглядит почти таким же лаконичным, как MATLAB (который я использовал довольно часто) - который был создан специально для такого рода вещей. Исходя из моего ограниченного опыта, библиотеки последовательны - это потому, что Haskell построен на небольшом количестве простых строительных блоков - и они также богаты, потому что Haskeller не любят делать мирские вещи :)
Пол