Что означает "чистый" в "чистом функциональном языке"?
Хаскелл был назван "чистым функциональным языком".
Что означает "чистый" в этом контексте? Каковы последствия этого для программиста?
Ответы
Ответ 1
В чистом функциональном языке вы не можете делать ничего, что имеет побочный эффект.
Побочный эффект будет означать, что оценка выражения изменяет некоторое внутреннее состояние, которое впоследствии приведет к тому, что одно и то же выражение будет иметь другой результат. На чистом функциональном языке вы можете оценивать одно и то же выражение так часто, как хотите, с теми же аргументами, и оно всегда будет возвращать одно и то же значение, потому что не существует состояния для изменения.
Например, чистый функциональный язык не может иметь оператор присваивания или делать ввод/вывод, хотя для практических целей даже чистые функциональные языки часто называют нечистые библиотеки для ввода-вывода.
Ответ 2
"Чистый" и "функциональный" - это две отдельные концепции, хотя один из них не очень полезен без другого.
Чистое выражение является идемпотентом: оно может быть оценено любое число раз с одинаковыми результатами каждый раз. Это означает, что выражение не может иметь никаких наблюдаемых побочных эффектов. Например, если функция мутировала свои аргументы, задала переменную где-то или изменила поведение на основе чего-то другого, кроме ее ввода, то вызов этой функции не является чистым.
Функциональный язык программирования - это тот, в котором функции являются первоклассными. Другими словами, вы можете манипулировать функциями с той же легкостью, с помощью которой вы можете манипулировать всеми другими первоклассными значениями. Например, возможность использования "функции, возвращающей bool" в качестве "структуры данных, представляющей набор", будет легким на функциональном языке программирования.
Программирование в языках функционального программирования часто выполняется в основном чистом стиле, и трудно быть строго чистым без манипуляции с более высоким порядком, поддерживаемой функциональными языками программирования.
Haskell - это язык функционального программирования, в котором (почти) все выражения чисты; Таким образом, Haskell является чисто функциональным языком программирования.
Ответ 3
Чистая функция - это функция, которая не имеет побочных эффектов - она принимает значение и возвращает значение. Нет глобального состояния, которое функции изменяют. Чистым функциональным языком является тот, который заставляет функции быть чистыми. Чистота имеет ряд интересных последствий, например, тот факт, что оценка может быть ленивой - поскольку вызов функции не имеет никакой цели, кроме как вернуть значение, тогда вам не нужно фактически выполнять функцию, если вы не собираетесь использовать его значение. Благодаря этому в Haskell распространены такие вещи, как рекурсивные функции в бесконечных списках.
Другим следствием является то, что неважно, в каком порядке оцениваются функции - поскольку они не могут влиять друг на друга, вы можете делать их в любом удобном для вас порядке. Это означает, что некоторые проблемы, возникающие при параллельном программировании, просто не существуют, поскольку для выполнения функций не существует "неправильного" или "правильного" порядка.
Ответ 4
Строго говоря, чистый функциональный язык - это функциональный язык (т.е. язык, где функции являются первоклассными значениями), где выражения не имеют побочных эффектов. Термин "чисто функциональный язык" является синонимом.
По этому определению, Haskell не является чистым функциональным языком. Любой язык, на котором вы можете писать программы, отображающие их результат, чтение и запись файлов, иметь графический интерфейс и т.д., Не является чисто функциональным. Таким образом, ни один язык программирования общего назначения не является чисто функциональным (но есть полезные функционально-функциональные языки, специфичные для конкретной области: их обычно можно рассматривать как внедренные языки каким-либо образом).
Существует полезный расслабленный смысл, в котором такие языки, как Haskell и Erlang, можно считать чисто функциональными, но языки, такие как ML и Scheme, не могут. Язык можно считать чисто функциональным, если имеется достаточно большое, полезное и хорошо охарактеризованное подмножество, где побочные эффекты невозможны. Например, в Haskell все программы, тип которых не построен из IO
или другой монады, обозначающей эффект, являются побочными эффектами. В Erlang все программы, которые не используют IO-индуцирующие библиотеки или функции concurrency, не имеют побочных эффектов (это больше, чем случай Haskell). И наоборот, в ML или Scheme побочный эффект может быть похоронен в любой функции.
С этой точки зрения чисто функциональное подмножество Haskell можно рассматривать как встроенный язык для решения поведения внутри каждой монады (конечно, это странная перспектива, так как почти все вычисления происходят в этом "встроенном" подмножестве), а чисто функциональное подмножество Erlang можно рассматривать как встроенный язык, который имеет дело с локальным поведением.
Грэм Хаттон имеет немного другую и весьма интересную перспективу на тему чисто функциональных языков
Иногда термин "чисто функциональный" также используется в более широком смысле для обозначения языков, которые могут включать в себя вычислительные эффекты, но не изменяя понятия "функции" (о чем свидетельствует тот факт, что существенные свойства функций сохраняются. ) Как правило, оценка выражения может дать "задачу", которая затем выполняется отдельно, чтобы вызывать вычислительные эффекты. Фазы оценки и выполнения разделяются таким образом, что этап оценки не ставит под угрозу стандартные свойства выражений и функций. Механизмы ввода/вывода Haskell, например, относятся к этому типу.
т.е. в Haskell функция имеет тип a -> b
и не может иметь побочных эффектов. Выражение типа IO (a -> b)
может иметь побочные эффекты, но это не функция. Таким образом, в Haskell функции должны быть чистыми, поэтому Haskell является чисто функциональным.
Ответ 5
Поскольку в чистом функциональном коде не может быть никаких побочных эффектов, тестирование становится намного проще, поскольку нет внешнего состояния для проверки или проверки. Кроме того, из-за этого расширение кода может стать проще.
Я потерял счет количества раз, когда у меня были проблемы с неочевидными побочными эффектами при расширении/исправлении (или исправлении) кода.
Ответ 6
Как отмечали другие, термин "чистый" в "чистом языке функционального программирования" относится к отсутствию наблюдаемых побочных эффектов. Для меня это приводит прямо к вопросу:
Что такое побочный эффект?
Я видел побочные эффекты, объясняемые как
- то, что функция делает иначе, чем просто вычислить ее результат
- что-то, что может повлиять на результат функции, отличной от входов функции.
Если первое определение является правильным, любая функция, которая делает I/O (например, запись в файл), не может считаться "чистой" функцией. В то время как программы Haskell могут вызывать функции, которые заставляют выполнять операции ввода-вывода, казалось бы, что Haskell не является чистым функциональным языком программирования (как утверждается, в соответствии с этим определением).
По этой и другим причинам я считаю, что второе определение более полезно. Согласно второму определению, Haskell по-прежнему может претендовать на совершенно чистый язык функционального программирования, поскольку функции, которые заставляют выполнять операции ввода-вывода, вычисляют результаты, основанные только на функциональных входах. Как Haskell примиряет эти, казалось бы, противоречивые требования, довольно интересно, я думаю, но я буду сопротивляться искушению отклониться от ответа на фактический вопрос.
Ответ 7
Амр Сабри написал paper о том, что такое чистый функциональный язык. Haskell по этому определению считается чистым, если игнорировать такие вещи, как unsafePerformIO. Использование этого определения также делает ML и Erlang нечистыми. Есть подмножества большинства языков, которые квалифицируются как чистые, но лично я не думаю, что очень полезно говорить о том, что C является чистым языком.
Высший порядок ортогонален чистоте, вы можете создать чистый функциональный язык первого порядка.