Подтвердить что ты не робот

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

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

Прежде чем я открою свою книгу о Haskell и погрузиться в функциональное программирование, мне хотелось бы по крайней мере базовое представление о том, что я действительно могу использовать для нее (за пределами примеров из книги). Итак, что же такое функциональное программирование? Каковы проблемы, для которых он не подходит?

Update

У меня есть хорошие ответы об этом до сих пор. Я не могу дождаться, чтобы начать изучать Haskell сейчас - мне просто нужно подождать, пока я не освою C:)

Причины, по которым функциональное программирование велико:

  • Очень краткий и лаконичный - он может выражать сложные идеи короткими, непромокаемыми утверждениями.
  • Легче проверять, чем императивные языки - хорошо, когда безопасность в системе критическая.
  • Чистота функций и неизменность данных делает параллельное программирование более правдоподобным.
  • Хорошо подходит для написания сценариев и написания компиляторов (я был бы признателен за то, что, хотя).
  • Математические проблемы решаются просто и красиво.

Области, в которых борьба с функциональным программированием:

  • Debatable: веб-приложения (хотя, я думаю, это будет зависеть от приложения).
  • Настольные приложения (хотя это зависит от языка, вероятно, F # будет хорош в этом, не так ли?).
  • Все, что критически важно для производительности, например игровые движки.
  • Все, что связано с большим количеством состояний программы.
4b9b3361

Ответ 1

Функциональное программирование превосходит при сжатии из-за существования функций более высокого уровня (map, lfold, grep) и вывод типа.

Он также отлично подходит для общего программирования по тем же причинам и что еще больше увеличивает способность выражать сложные идеи в кратком заявлении без запутывания.

Я ценю эти свойства, поскольку они делают интерактивное программирование правдоподобным. (например, R, SML).

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

Ответ 2

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

            Back-end   Front-end
Low-level   C          C++
High-level  FP         VB, C#

Ответ 3

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

F #:

type 'a stack = Cons of 'a * stack | Nil
let rec to_seq = function
    | Nil -> Seq.empty;
    | Cons(hd, tl) -> seq { yield hd; yield! to_seq tl }
let rec append x y =
    match x with
    | Nil -> y
    | Cons(hd, tl) -> Cons(hd, append tl y)
let x = Cons(1, Cons(2, Cons(3, Cons(4, Nil))))
let y = Cons(5, Cons(6, Cons(7, Cons(8, Nil))))
let z = append x y
to_seq z |> Seq.iter (fun x -> printfn "%i" x)

Java:

interface IStack<T> extends Iterable<T>
{
    IStack<T> Push(T value);
    IStack<T> Pop();
    T Peek();
    boolean IsEmpty();
}
final class EmptyStack<T> implements IStack<T>
{
    public boolean IsEmpty() { return true; }
    public IStack<T> Push(T value) { return Stack.cons(value, this); }
    public IStack<T> Pop() { throw new Error("Empty Stack"); }
    public T Peek() { throw new Error("Empty Stack"); }
    public java.util.Iterator<T> iterator()
    {
        return new java.util.Iterator<T>()
        {
            public boolean hasNext() { return false; }
            public T next() { return null; }
            public void remove() { }
        };
    }
}
final class Stack<T> implements IStack<T>
{
    public static <T> IStack<T> cons(T hd, IStack<T> tl) { return new Stack<T>(hd, tl); }
    public static <T> IStack<T> append(IStack<T> x, IStack<T> y)
    {
        return x.IsEmpty() ? y : new Stack(x.Peek(), append(x.Pop(), y));
    }
    private final T hd;
    private final IStack<T> tl;
    private Stack(T hd, IStack<T> tl)
    {
        this.hd = hd;
        this.tl = tl;
    }
    public IStack<T> Push(T value) { return new <T> Stack(value, this); }
    public IStack<T> Pop() { return this.tl; }
    public T Peek() { return this.hd; }
    public boolean IsEmpty() { return false; }
    public java.util.Iterator<T> iterator()
    {
        final IStack<T> outer = this;
        return new java.util.Iterator<T>()
        {
            private IStack<T> current = outer;
            public boolean hasNext() { return !current.IsEmpty(); }
            public T next()
            {
                T hd = current.Peek();
                current = current.Pop();
                return hd;
            }
            public void remove() { }
        };
    }
}
public class Main
{
    public static void main(String[] args)
    {
        IStack<Integer> x = Stack.cons(1, Stack.cons(2, Stack.cons(3, Stack.cons(4, new EmptyStack()))));
        IStack<Integer> y = Stack.cons(5, Stack.cons(6, Stack.cons(7, Stack.cons(8, new EmptyStack()))));
        IStack<Integer> z = Stack.append(x, y);

        for (Integer num : z)
        {
            System.out.printf("%s ", num);
        }
    }
}

Ответ 4

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

Ответ 5

Некоторые проблемы Я нашел функциональное программирование, подходящее для:

  • concurrency
  • Компиляторы
  • сценарии

Проблемы, которые я лично считаю не очень подходящими:

  • веб-приложения (но, возможно, только я, Hacker News, например, реализована в LISP)
  • настольные приложения
  • игровые движки
  • вещи, в которых вы проходите много состояний.

Ответ 6

Я нахожу, что Хаскелл хорошо подходит для того, чтобы делать что-то математическое. Не то, чтобы это был настоящий профессиональный проект, но я сделал с ним сумоку-решатель и анализатор покера. Наличие программы, математически доказуемой, замечательно.

Насколько он не подходит, это что-то, где производительность является приоритетом. У вас меньше контроля над используемыми алгоритмами, поскольку он более декларативный, чем императивный.

Ответ 7

Я не согласен с тем, что FP нельзя использовать для веб-приложений. Я знаю, что Paul Grahm и Robert Morris запустили Viaweb, который использовал Lisp для доставки веб-приложений. Я думаю, что когда вы приближаетесь к аппаратным средствам (драйверы устройств, ядро ​​и т.д.), Вы хотите использовать как язык низкого уровня, насколько это возможно. Это связано с тем, что, если используются больше абстракций, тогда его сложнее отлаживать в случае ошибок. Взгляните на статью "Закон лихорадочной абстракции" Джоэла Спольского.

Ответ 8

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

Ответ 9

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

Ответ 10

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

Я сказал: "У меня проблемы", а не "нельзя использовать" (из-за эквивалентности Тьюринга все может быть использовано для чего угодно).

Интересный вопрос заключается в том, является ли эта проблема фундаментальной в функциональном программировании (поскольку физические устройства имеют состояние) или если мы можем представить системно-ориентированный язык/среды функционального программирования. Например, BitC является лишь частично функциональным (он сильно зависит от изменчивости).

Ответ 11

Функциональная и объектно-ориентированная парадигма имеют силу ортогональности. вы можете сказать, что функциональное программирование имеет особое значение для глаголов и объектно-ориентированного программирования существительных. Или, более практично: Ориентация объектов делает добавление новых данных простым, а функциональное программирование упрощает добавление новых инструментов. Оба требуют изменения кода для достижения другой цели. Вы хотели бы прочитать http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.18.4525&rep=rep1&type=pdf (Синтезирование проектно-ориентированного и функционального дизайна для содействия повторному использованию