Не численные варианты использования для функционального программирования?

Я только что закончил читать книгу на scala. Меня поражает то, что каждый пример во всей книге был численным в той или иной форме.

Как и многие программисты, единственная математика, которую я использую, - это дискретная и комбинаторная математика, и обычно это не математика, которую я программирую явным образом. Мне действительно не хватает некоторых убедительных примеров функциональных альтернатив/дополнений к обычным алгоритмам.

Каковы некоторые не численные варианты использования для функционального программирования?

Ответы

Ответ 1

Моя компания попросила меня написать собственное приложение, которое позволяло пользователям выполнять специальные запросы в отношении базы данных с плоскими файлами. Пользователями этого приложения были ваши типичные типы Joe Businessman. Они не программисты, и маловероятно, что они когда-либо видели инструкцию SQL в своей жизни.

В результате мне было поручено разработать дружественный интерфейс пользователя, который позволит пользователям выбирать столбцы, таблицы, условия и т.д. для создания запроса. Это сложно, потому что я могу представить оператор SQL в пользовательском интерфейсе без предварительного создания абстрактного представления его в памяти.

Первая итерация была написана на С#. Я создал классы лодок для представления абстрактного синтаксиса оператора SQL, что привело к действительно громоздкой объектной модели:

  • a Класс Join, класс коллекции Joins
  • класс WhereClause, класс коллекции WhereClauses
  • класс SelectedColumn, класс коллекции SelectedColumns
  • класс OrderBy, класс коллекций коллекции OrderBy
  • класс SqlStatement, который сгруппировал все связанные с ним классы

Преобразование экземпляра SqlStatement в строку было славно болезненным, уродливым и багги. Перемещение противоположного направления из строки в SqlStatement было еще хуже, поскольку оно разрывало части строки SQL, используя множество регулярных и строковых манипуляций.

Я взломал систему, создал приложение, которое сработало, но я был не очень доволен этим. Я особенно не был, когда бизнес-требования приложения изменились на меня, что заставило меня пересмотреть мой код на С#.

Как эксперимент, я переписал свой SqlStatement в F # и представлял его как объединение:


type dir = Asc | Desc
type op = Eq | Gt | Gte | Lt | Lte
type join = Inner | Left | Right

type sqlStatement =
    | SelectedColumns of string list
    | Joins of (string * join) list
    | Wheres of (string * op * string) list
    | OrderBys of (string * dir) list

type query = SelectedColumns * Joins * Wheres * OrderBys

Этот небольшой код заменил несколько сотен строк С# и дюжину классов. Что еще более важно, сравнение шаблонов упростило процесс, необходимый для преобразования абстрактного представления в строку SQL.

Интересной частью было преобразование строки SQL обратно в объект запроса с использованием fslex/fsyacc.

Если я правильно помню, исходный код С# насчитывал 600 строк и около десятка классов, много грязных регулярных выражений и требовал два дня, чтобы писать и тестировать. Для сравнения, код F # состоял из одного файла .fs длиной около 40 строк, 100 строк или около того для реализации lexer/parser и потреблял несколько часов из моего дня для тестирования.

Серьезно, написав эту часть приложения в F #, я почувствовал себя обманом, так как это было легко.

Ответ 3

Функциональное программирование - это парадигма, такая как процедурное/структурированное, объектно-ориентированное и обобщенное/шаблонное программирование. Это завершает, чтобы вы могли делать все, что захотите.

Помимо математики и науки, это упрощает комбинации комбинаторов, искусственный интеллект, concurrency, динамическую оценку, совлокальные подпрограммы, продолжения, краткую нотацию (более быстрый цикл "мозг от клавиатуры к тексту" и меньше кода для поддержки), строго типизированная параметризация (см. алгебраические типы Haskell) и динамическое самоотражение (например, минималистические метациркулярные интерпретаторы с REPL).

Ответ 5

Отъезд Обработка текста в Python. Книга начинается с некоторых простых, но хорошо мотивированных примеров, где методы функционального программирования делают код более удобным для чтения и, скорее всего, правильным.

Ответ 6

"Начало работы с Erlang" имеет обширный пример клиент/сервер (начиная с раздела 1.3.5), который может удовлетворить ваши потребности.

Ответ 7

У вас есть еще один для вас:

Я участвую в самых ранних этапах создания прототипов набора новых финансовых продуктов корпоративного масштаба, предназначенных для малых и средних банков, локальных органов власти, фондовых бирж и т.д. Вы, вероятно, думаете: "О, финансовые код, вы должны делать много математики" - на самом деле, нет. Эти продукты должны быть очень настраиваемыми и позволяют пользователям вводить бизнес-правила в стратегических точках приложения.

Мы используем F # для представления и интерпретации бизнес-правил. Чтобы использовать наивный пример, мы можем написать код для проверки, мы можем написать следующие правила:

type condition =
    | Test of string
    | And of condition * condition
    | Or of condition * condition
    | Not of condition

type transactionWorkflow =
    | Reject
    | Approve
    | AdministratorOverride of string
    | If of condition * transactionWorkflow list
         (* condition,  true condition *)
    | IfElse of condition * transactionWorkflow list * transactionWorkflow list
         (* condition,      true condition,            false condition *)
    | AttachForms of string list

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

let checkProcessingWorkflow =
    [If(Test("account doesn't exist")
        ,[AdministratorOverride("Account doesn't exist. Continue?");
          AttachForms ["40808A - Null Account Deposit"]]
       );
     If(Test("deposit > 10000")
        ,[
            If(And(Test("account created within 3 months")
                   ,Test("out of country check"))
               ,[Reject]);
            IfElse(Test("account state = TX")
                    ,[AttachForms ["16A"; "16B"]]
                    ,[AttachForms ["1018"]]
                 )
         ]
       );
     Approve
    ]

Итак, вместо того, чтобы писать один механизм бизнес-правил, чтобы управлять ими всеми, мы обрабатываем определенные процессы как очень крошечный язык, специфичный для домена, заданный F #. Я надеюсь, что этот подход позволит нам создавать очень простые бизнес-считываемые DSL файлы, не требуя обнаружения противоречивых правил.

Конечно, все, что указано выше, - это всего лишь концептуальный код, и мы все еще находимся на очень ранних стадиях даже прототипирования одной из наших правил. Мы используем F #, а не Java или С# по одной конкретной причине: соответствие шаблонов.

Ответ 8

Чем больше я использую функциональный стиль, тем лучше мне это нравится. Рассмотрим этот фрагмент Python из другого вопроса:

>>> testlist
[1, 2, 3, 5, 3, 1, 2, 1, 6]
>>> [i for i,x in enumerate(testlist) if x == 1]
[0, 5, 7]

Это, по общему признанию, более или менее математическое утверждение, но в Python есть много генераторов. Как только вы привыкнете к этому, использование понимания списка вместо цикла является простым для понимания и с меньшей вероятностью иметь ошибку (вы не получаете "отключены одним" ошибками.)

Ответ 9

Правда, многие книги по функциональному программированию используют "численное программирование" для обучения, но есть исключения.

Школа выражения Haskell - это книга для начинающих по Haskell, в которой используется мультимедиа как средство обучения.

Real World Haskell на самом деле не имеет никакого конкретного транспортного средства на протяжении всей книги, но есть несколько глав, посвященных написанию "реальных" программ в функциональном стиле.

Ответ 10

В эти дни я даже не стал бы рассматривать DSL lexer/parser на нефункциональном языке (в широком смысле этого слова). ADT и сопоставление образцов делают это намного проще.

Ответ 11

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

Однако, учитывая отличные компиляторы, которые мы имеем сегодня, функциональное программирование светит почти везде.

Ответ 12

Отметьте Чисто функциональные структуры данных "(и здесь кандидатская диссертация, которая вдохновила книгу).

Они показывают, как создавать стандартные структуры данных на чисто функциональных (без побочных эффектов) языках. Затем вы можете использовать их для программирования всего.

Отказ от ответственности: я тяну к Этвуду здесь, я едва прочитал пару обзоров книги и просмотрел тезис, это в моем списке дел.

Ответ 13

Преодоление разрыва алгоритма: линейная функциональная программа для форматирования абзаца (1997)
    Оге де Мур, Джереми Гиббонс
    http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.33.7923

Структурирование графических парадигм в TkGofer (1997) Коэн Классен, Тон Вуллингс, Эрик Мейер http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.38.5525

Моделирование офисных процессов с помощью функциональных парсеров (1994) Гертом Флорином
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.19.1307

Ответ 14

Лучшим конкретным примером, который я могу дать, является StringTemplate, используемый механизм шаблонов (среди многих других мест) в генераторе парсеров ANTLR.

В одной статье о разработке и разработке StringTemplate Теренс Парр писал, что он изначально скептически относился к функциональному программированию и так громко рассмеялся, когда понял, что StringTemplate по существу является функциональным языком для генерации текста.

Ответ 15

для тех, кто считает функциональный язык программирования LISP, там есть http-сервер, написанный общим LISP, представленный в документе 1994 года и все еще разрабатываемый в 2006 году:

для более современного материала, вы можете спросить у Google "haskell web server", вы, вероятно, найдете несколько интересных примеров. один заставляет меня найти этот сайт: http://code.haskell.org/.

Ответ 16

Тед Ньюард написал 10-ю часть статьи о Scala, нацеленную на программистов Java, и серия закончила с написания DSL в Scala. Этот конкретный DSL на самом деле является числовым калькулятором, но это не интересно, так как DSL можно легко собрать на функциональном языке.

Part1

Part2

Part3

Ответ 17

Действительно интересный вопрос, потому что я думал, что я единственный автор, пишущий книги по функциональному программированию для чисел!

Функциональное программирование исторически гораздо чаще использовалось для метапрограммирования, то есть для написания программ, которые управляют другими программами. Сюда входят интерпретаторы и компиляторы (например, для DSL), а также более эзотерические приложения, такие как теоретические прокси-машины (Coq, Isabelle) и терминальные системы перезаписи (например, системы компьютерной алгебры, такие как Mathematica). Для этого было специально разработано семейство языков метаязыков (ML).

Ответ 18

LINQ берет много сигналов от функционального программирования. Взглянув на то, как реализован произвольный поставщик LINQ, вы можете получить некоторую практическую информацию.