Нечисловые случаи использования для функционального программирования? - PullRequest
26 голосов
/ 19 декабря 2008

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

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

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

Ответы [ 18 ]

45 голосов
/ 19 декабря 2008

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

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

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

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

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

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

Так же, как эксперимент, я переписал свой 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

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

Самое интересное - преобразовать строку SQL обратно в объект запроса с помощью fslex / fsyacc.

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

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

10 голосов
/ 19 декабря 2008
7 голосов
/ 19 декабря 2008

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

Помимо математики и естественных наук, он облегчает работу комбинаторов синтаксического анализа, искусственного интеллекта, параллелизма, динамической оценки, сопрограмм, продолжений, краткой записи (более быстрый цикл «мозг-клавиатура-текст-файл» и меньше кода поддерживать), строго типизированную параметризацию (см. алгебраические типы Хаскелла) и динамическое саморефлексия (например, минималистичные метациркулярные интерпретаторы с REPL).

5 голосов
/ 19 декабря 2008

Возможно, вам будет интересно услышать этот выпуск Radio Engineering Radio вместе с создателем Эрланга, который разработал его во время работы в Ericsson.

http://www.se -radio.net / Подкаст / 2008-03 / эпизод-89-джо-армстронг-Эрл

4 голосов
/ 05 июня 2009

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

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

Мы используем 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 или C # по одной конкретной причине: сопоставление с образцом.

3 голосов
/ 19 декабря 2008

Чем больше я использую функциональный стиль, тем лучше он мне нравится. Рассмотрим этот фрагмент 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 есть лотов генераторов. Как только вы к этому привыкнете, использование понимания списка вместо цикла будет легко понять, и с меньшей вероятностью возникнет ошибка (вы не получите ошибки «от одного»).

3 голосов
/ 19 декабря 2008

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

3 голосов
/ 19 декабря 2008

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

2 голосов
/ 02 июля 2010

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

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

2 голосов
/ 20 декабря 2008

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

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

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

...