Является ли функциональный язык хорошим выбором для Flight Simulator? Как насчет Лисп? - PullRequest
11 голосов
/ 05 апреля 2009

Я занимаюсь объектно-ориентированным программированием уже несколько лет, и я мало занимался функциональным программированием. Я заинтересован в симуляторах полета и мне интересно узнать о функциональном программировании в Lisp. Симуляторы полета или любой другой симулятор реального мира имеет смысл для меня в объектно-ориентированной парадигме.

Вот мои вопросы:

Является ли объектно-ориентированный лучший способ представить область моделирования реального мира?

Я знаю, что в Common Lisp есть CLOS (OO для lisp), но мой вопрос действительно о написании симулятора полета на функциональном языке. Так что, если вы собираетесь написать это на Лиспе, вы бы предпочли использовать CLOS или написать это функционально?

Есть ли у кого-нибудь мысли о кодировании симулятора полета на языке lisp или на любом другом функциональном языке?

ОБНОВЛЕНИЕ 11/8/12 - Аналогичный вопрос SO для интересующихся -> Как функциональное программирование применяется к симуляциям?

Ответы [ 7 ]

12 голосов
/ 05 апреля 2009

Распространенная ошибка - считать Лисп функциональным языком. На самом деле это лучше всего рассматривать как семейство языков, возможно, но в наши дни, когда люди говорят на Лиспе, они обычно имеют в виду Common Lisp.

Common Lisp допускает функциональное программирование, но сам по себе он не является функциональным языком. Скорее это язык общего назначения. Схема - гораздо меньший вариант, более функциональный по ориентации, и, конечно, есть и другие.

Что касается вашего вопроса, это хороший выбор? Это действительно зависит от ваших планов. У Common Lisp, в частности, есть некоторые сильные стороны для такого рода вещей. Он интерактивен и интроспективен на уровне, который вы обычно видите на так называемых языках сценариев, что делает его очень быстрым в разработке. В то же время он скомпилирован и имеет эффективные компиляторы, поэтому вы можете ожидать производительности в том же приблизительном сценарии, что и другие эффективные компиляторы (с коэффициентом два из c является типичным моментом). Несмотря на большой язык, он имеет гораздо более согласованный дизайн, чем такие вещи, как c ++, а возможности метапрограммирования могут сделать очень чистый и легкий для понимания код для вашего конкретного приложения. Если вы только посмотрите на эти аспекты обычный шепот выглядит потрясающе.

Однако есть и недостатки. Сообщество маленькое, вы не найдете много людей, чтобы помочь, если это то, что вы ищете. Несмотря на то, что встроенная библиотека велика, вы не найдете столько сторонних библиотек, так что вы можете написать больше с нуля. Наконец, хотя это отнюдь не сад в стенах, CL не имеет такой плавной интеграции с иностранными библиотеками, как, например, в Python. Это не значит, что вы не можете вызывать код c, для этого есть хорошие инструменты.

Между прочим, CLOS - это самая мощная ОО-система, о которой я могу подумать, но это совсем другой подход, если вы работаете с мейнстримом c ++ / java / c # / etc. ОО фон (да, они различаются, но за пределами одного и нескольких дюймов. Не так уж много) на первый взгляд это может показаться немного странным, почти вывернутым наизнанку.

Если вы пойдете этим путем, вам придется следить за некоторыми проблемами с производительностью реального конвейера рендеринга, если вы пишете это сами с помощью CLOS. Система классов обладает невероятной гибкостью во время выполнения (т. Е. Обновление определений классов во время выполнения не путем внесения исправлений обезьянами и т. Д., А путем фактического изменения класса и обновления экземпляров), однако вы платите за это некоторую стоимость отправки.

Для чего бы то ни было, в прошлом я использовал CL для исследовательского кода, требующего численной эффективности, то есть для моделирования другого рода. Это хорошо работает для меня. В этом случае я не беспокоился об использовании существующего кода - его не было, поэтому я все равно писал практически все с нуля.

Таким образом, это может быть хорошим выбором языка для этого проекта, но не единственным. Если вы не используете язык как с аспектами высокого уровня, так и с хорошей производительностью (как у CL, как у OCaml и некоторых других), я бы определенно рассмотрел возможность двухуровневого подхода с таким языком, как lua ​​или, возможно, python (много библиотек) поверх некоторого кода на c или c ++, выполняющего тяжелую работу.

8 голосов
/ 05 апреля 2009

Если вы посмотрите на индустрию игр или симуляторов, вы обнаружите множество C ++ плюс, возможно, некоторый добавленный компонент сценариев. Там также могут быть инструменты, написанные на других языках для декорации или связанных задач. Но в этом домене используется очень мало Лисп. Вы должны быть хорошим хакером, чтобы получить необходимую производительность от Lisp и иметь возможность доступа или написания низкоуровневого кода. Как вы получаете это ноу-хау? Попробуй, проваливай, учись, пробуй, меньше проваливай, учись ... Нет ничего, кроме написания кода и экспериментов с ним. Lisp действительно полезен для хороших инженеров-программистов или тех, у кого есть потенциал стать хорошим инженером-программистом.

Одним из главных препятствий является сборщик мусора . Либо у вас очень простой (тогда у вас проблемы с производительностью со случайными паузами), либо у вас изощренный (тогда у вас есть проблемы с его правильной работой). Существует только несколько сборщиков мусора, которые могли бы быть подходящими - большинство реализаций Lisp имеют хорошие реализации GC, но все же они не настроены для использования в реальном времени или почти в реальном времени. Исключения существуют. С C ++ вы можете забыть GC, потому что обычно его нет.

Другой альтернативой автоматическому управлению памятью с помощью сборщика мусора является отсутствие ГХ и управление памятью «вручную». Это используется некоторыми (даже коммерческими) приложениями на Лиспе, которым требуется поддержка ответа в реальном времени (например, экспертные системы управления процессами).

Ближайшей разработкой в ​​этой области была игра Crash Bandicoot (и более поздние игры) для Playstation I (более поздние игры были для Playstation II) от Naughty Dog. Так как они были куплены Sony, они переключились на C ++ для Playstation III. Их среда разработки была написана на Allegro Common Lisp и включала компилятор для варианта Scheme (диалект Lisp). В системе разработки код компилируется и затем загружается на Playstation во время разработки. У них был собственный 3D-движок (очень впечатляющий, всегда получавший отличные отзывы от игровых журналов), инкрементальная загрузка уровней, сложный контроль поведения для множества разных актеров и т. Д. Так что Playstation действительно выполняла код Scheme, но управление памятью не было сделано через GC (afaik). Они должны были разработать все технологии самостоятельно - никто не предлагал инструменты на основе Lisp - но они могли, потому что они были отличными разработчиками программного обеспечения. С тех пор я не слышал о подобном проекте. Обратите внимание, что это был не просто Лисп для сценариев - это был Лисп до самого конца.

На стороне Схемы есть также новая интересная реализация, названная Схема Ипсилона . Он разработан для игры в пинбол - он может стать основой и для других игр.

Со стороны Common Lisp, есть приложения Lisp, которые общаются с симуляторами полета и управляют их аспектами. Есть несколько игровых библиотек, основанных на SDL. Есть интерфейсы для OpenGL. Также есть что-то вроде «Open Agent Engine». Есть также некоторые приложения для трехмерной графики, написанные на Common Lisp - даже некоторые сложные. Но в области моделирования полета очень мало известного уровня техники.

По теме CLOS против функционального программирования. Вероятно, никто бы не использовал ни один. Если вам нужно выжать из системы всю возможную производительность, то в CLOS уже есть некоторые накладные расходы, которых можно избежать.

6 голосов
/ 07 апреля 2009

Взгляните на Функциональное реактивное программирование . Для этого в Haskell есть ряд структур (не знаю о других языках), большинство из которых основаны на стрелках. Основная идея состоит в том, чтобы представлять отношения между изменяющимися во времени значениями и событиями. Так, например, вы бы написали (в нотации стрелок на Haskell без конкретной библиотеки):

   velocity <- {some expression of airspeed, heading, gravity etc.}
   position <- integrate <- velocity

Вторая строка объявляет связь между положением и скоростью. Операторы <- стрелки являются синтаксическим сахаром для множества библиотечных вызовов, которые связывают все вместе. </p>

Затем вы могли бы сказать что-то вроде:

   groundLevel <- getGroundLevel <- position
   altitude <- getAltitude <- position
   crashed <- liftA2 (<) altitude groundLevel

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

IO не является проблемой в этой парадигме. Входные данные представляют собой изменяющиеся во времени значения, такие как джойстик X и Y, в то время как изображение на экране является просто другим изменяющимся во времени значением. На самом верхнем уровне весь ваш симулятор - стрелка от входов к выходам. Затем вы вызываете функцию «Выполнить», которая преобразует стрелку в действие ввода-вывода, запускающее игру.

Если вы напишите это на Лиспе, вы, вероятно, обнаружите, что создаете кучу макросов, которые в основном заново изобретают стрелки, так что, возможно, стоит просто узнать о стрелках, с чего начать.

2 голосов
/ 06 апреля 2009

Я ничего не знаю о симуляторах полета, и вы ничего не перечислили, в частности, из чего они состоят, так что в основном это предположение о написании FS на Лиспе.

Почему бы и нет:

  • Лисп превосходит при поисковом программировании. Я думаю, что с тех пор, как ФС были так долго, и есть бесплатные примеры с открытым исходным кодом, это не принесло бы столько пользы от этого типа программирования.

  • Симуляторы полета в основном (я предполагаю) написаны на статических, скомпилированных на родном языке языках. Если вы ищете чистую производительность во время выполнения, в Лиспе это обычно означает объявления типов и другие не очень-лиспские конструкции. Если вы не получите нужную производительность с наивными подходами, ваш оптимизированный Lisp может в конечном итоге выглядеть почти как C, а Lisp не так хорош в C при написании C.

  • Я полагаю, что большая часть FS взаимодействует с графической библиотекой, такой как OpenGL, которая написана на C. В зависимости от того, как связаны ваши FFI / OpenGL привязки, это может снова сделать ваш код похож на C-in-Lisp. У вас может не быть большого выигрыша, который есть у Lisp, скажем, в веб-приложении (которое состоит в создании древовидной структуры простого текста, в чем Lisp великолепен).

Почему:

  • Я взглянул на исходный код FlightGear и вижу множество структурных шаблонов - даже прямой порт может оказаться вдвое меньше.

  • Они используют строки для ключей повсюду (C ++ не имеет символов). Они используют XML для полуконтурируемых файлов конфигурации (в C ++ нет программы чтения во время выполнения). Простое переключение на нативные конструкции Lisp здесь может быть большой победой при минимальных усилиях.

  • Ничто не выглядит сложным, даже "ИИ". Это просто вопрос организации всего, и Лисп будет в этом преуспевать, потому что он будет намного короче.

Но в Lisp есть одна изюминка - мультипарадигма. Вы можете использовать OO для организации «объектов» и FP для вычислений внутри каждого объекта. Я говорю, просто начни писать и посмотри, куда это тебя приведет.

1 голос
/ 07 апреля 2009

Сначала я бы подумал о характере симуляции.

Некоторые симуляции требуют взаимодействия, например, симулятор полета. Я не думаю, что функциональное программирование может быть хорошим выбором для интерактивного приложения (читай: интенсивная загрузка процессора / критическая реакция). Конечно, если у вас есть доступ к 8 PS3, подключенным вместе с Linux, вы не будете сильно беспокоиться о производительности.

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

1 голос
/ 05 апреля 2009

Я бы не сказал, что функциональное программирование особенно хорошо подходит для моделирования полета. В целом, функциональные языки могут быть очень полезными для написания научных симуляций, хотя это немного специализированный случай. На самом деле, вам, вероятно, будет лучше использовать стандартный императивный (предпочтительно ООП) язык, такой как C ++ / C # / Java, так как они будут иметь лучшие физические библиотеки, а также графические API, которые вы должны будете использовать очень сильно. Кроме того, подход ООП может облегчить представление вашей среды. Еще один момент, который следует учитывать, это то, что (насколько мне известно) популярные на сегодняшний день симуляторы полета написаны почти полностью на C ++.

По сути, моя философия заключается в том, что если нет особенно веской причины, по которой вам нужно использовать функциональные парадигмы, не используйте функциональный язык (хотя ничто не мешает вам использовать функциональные конструкции в ООП / смешанных языках). Я подозреваю, что процесс разработки будет гораздо менее болезненным с использованием хорошо протестированных API-интерфейсов для C ++ и языков, более часто связанных с разработкой игр (что имеет много общего с Flight Sim). Теперь, если вы хотите добавить какой-нибудь сложный ИИ в симулятор, Лисп может показаться более очевидным выбором, хотя даже тогда я бы даже не стал его прыгать. И, наконец, если вы действительно заинтересованы в использовании функционального языка, я бы рекомендовал вам использовать один из более универсальных языков, таких как Python или даже F # (оба на самом деле смешанные императивно-функциональные языки), в отличие от Lisp, который может в конечном итоге становится довольно уродливым для такого проекта.

0 голосов
/ 05 апреля 2009

Есть несколько проблем с функциональными языками, то есть они плохо сочетаются с состоянием, но хорошо сочетаются с процессом. Таким образом, можно сказать, что они ориентированы на действия. Это означает, что вы будете тратить время на симуляцию самолета, а вы хотите симулировать действия полета самолета. Как только вы мрачны, вы, вероятно, можете заставить его работать.

Теперь, как побочный эффект, haskell не будет хорошим ИМХО, потому что это слишком абстрактно для «игры», такого рода приложения все о вводе / выводе, но Haskell о том, чтобы избегать ввода-вывода, поэтому он станет Монадой кошмар, и ты будешь работать против языка. Lisp - лучший выбор, или Lua или Javascript, они также функциональны, но не чисто функциональны, поэтому для вашего случая попробуйте Lisp. В любом случае, на любом из этих языков ваша графика будет C или C ++.

Серьезная проблема, однако, заключается в том, что документации очень мало, и меньше учебников по функциональным языкам и «играм», конечно, научные симуляции документированы академически, но эти статьи довольно плотные, если вам это удастся, возможно, вы сможете написать свой опыт, другие, поскольку это довольно пустое поле прямо сейчас

...