В чем преимущество чисто функциональной структуры данных?

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

примеры вдоль линии, как я использую data_structure_name на programming_language сделать приложение потому что это может сделать certain_thing.

спасибо.

PS: то, что я подразумеваю под чисто функциональной структурой данных, не совпадает с постоянной структурой данных. Постоянная структура данных-это структура данных, которая не меняется?? С другой стороны, чисто функциональная структура данных-это структура данных, работает чисто.

5 ответов


чисто функциональные (он же постоянные или неизменяемые) структуры данных дают вам несколько преимуществ:

  • вам никогда не придется запереть их, что чрезвычайно улучшает параллелизм.
  • они могут разделить структуру, которая уменьшает использование памяти. Например, рассмотрим list [1, 2, 3, 4] в Haskell и некоторые императивные языки, такие как Java. Чтобы создать новый список в Haskell, вам нужно только создать новый cons (пара значений и ссылка на следующий элемент) и подключите его к предыдущему списку. В Java вы должны создать совершенно новый список, чтобы не повредить предыдущий.
  • вы можете сделать постоянные структуры данных лень.
  • кроме того, если вы используете функциональный стиль, вы можете не думать о времени и последовательности операций и так, сделать ваши программы более декларативный.
  • факт, что структура данных является неизменным, позволяет сделать еще несколько предположений и так расширить возможности языка. Например, Clojure использует факт неизменности для правильного предоставления реализаций метода hashCode () для каждого объекта, поэтому любой объект может использоваться в качестве ключа на карте.
  • с неизменяемыми данными и функциональным стилем вы также можете свободно использовать memoization.

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


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

module CharSet = Set.Make(Char)
let a = List.fold_right CharSet.add ['a';'b';'c';'d'] CharSet.empty in
let b = List.fold_right CharSet.add ['e';'f';'g';'h'] a in
...

a остается неизмененном после добавления новых символов (он содержит только a-d), в то время как b содержит a-h, и они разделяют некоторые из той же памяти (с set Это довольно сложно расскажите, сколько памяти разделяется, так как это дерево AVL и форма дерева изменяется). Я могу продолжать делать это, отслеживая все изменения, которые я сделал в дереве, позволяя мне вернуться в предыдущее состояние.

вот отличная диаграмма из статья Википедии о чисто функциональной это показывает результаты вставки символа 'e' в двоичное дерево xs:

alt text


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


возьмите этот маленький фрагмент F#:

let numbers = [1; 2; 3; 4; 5]

вы можете со 100% уверенностью сказать, что это неизменяемый список целых чисел от 1 до 5. Вы можете передать ссылку на этот список и никогда не беспокоиться о том, что список может быть изменен. Для меня этого достаточно.


чисто функциональные структуры данных имеют следующие преимущества:

  • Persistence: старые версии могут быть повторно использованы безопасно, зная, что они не могут быть изменены.

  • совместное использование: многие версии структуры данных могут храниться одновременно с только скромными требованиями к памяти.

  • безопасность потока: любая мутация скрыта внутри ленивых ударов (если таковые имеются) и, следовательно, обрабатывается языком реализация.

  • простота: отсутствие необходимости отслеживать изменения состояния упрощает использование чисто функциональных структур данных, особенно в контексте параллелизма.

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

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

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

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