Является ли Ruby функциональным языком? - PullRequest
85 голосов
/ 02 октября 2008

Википедия говорит, что Ruby - это функциональный язык, но я не уверен. Почему или почему нет?

Ответы [ 12 ]

57 голосов
/ 25 февраля 2010

Неважно, является ли язык функциональным или нет. Функциональное программирование - это тезис, лучше всего объясненный Филиппом Уодлером (Сущность функционального программирования) и Джоном Хьюзом (Почему функциональное программирование имеет значение).

Значительный вопрос звучит так: «Насколько Ruby поддается достижению тезиса функционального программирования?» Ответ «очень плохо».

Я говорил об этом совсем недавно. Вот слайды.

34 голосов
/ 02 октября 2008

Ruby поддерживает функции более высокого уровня (см. Array # map, inject и select), но это все еще обязательный объектно-ориентированный язык.

Одна из ключевых характеристик функционального языка - отсутствие изменяемого состояния. Функциональные языки не имеют понятия переменной, как в Ruby, C, Java или любом другом императивном языке.

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

29 голосов
/ 02 октября 2008

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

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

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

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

15 голосов
/ 02 октября 2008

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

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

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

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

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

Во всяком случае, это мое ненаучное мнение.

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

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

Теперь, это мое ненаучное мнение.

11 голосов
/ 19 февраля 2016

Ruby должен соответствовать следующим требованиям, чтобы быть «НАСТОЯЩИМ».

Неизменяемые значения: после установки «переменной» ее нельзя изменить. В Ruby это означает, что вам нужно обрабатывать переменные как константы. Язык не поддерживается полностью, вам придется заморозить каждую переменную вручную.

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

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

Curry: , включаемая функциями более высокого порядка, curry превращает функцию, которая принимает несколько аргументов, в функцию, которая принимает один аргумент. Это идет рука об руку с частичным применением функции, которая преобразует функцию с несколькими аргументами в функцию, которая принимает меньше аргументов, чем первоначально.

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

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

Предложение (Просто мысль) Было бы здорово иметь какое-то определение, чтобы иметь директиву mode для объявления файлов с функциональной парадигмой, например

режим «функциональный»

10 голосов
/ 02 октября 2008

Ruby - это мультипарадигмальный язык, который поддерживает функциональный стиль программирования.

4 голосов
/ 03 октября 2008

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

Большинство людей, например, называют Scheme функциональным языком. Но как насчет Common Lisp? Помимо проблемы множественных / единичных пространств имен и гарантированного устранения хвостовых вызовов (которые также поддерживаются некоторыми реализациями CL, в зависимости от настроек компилятора), мало что делает Scheme как язык более подходящим для функционального программирования, чем Common Lisp, и все же, большинство Lispers не назвали бы CL функциональным языком. Зачем? Поскольку культура, окружающая ее, в значительной степени зависит от императивных особенностей CL (например, от макроса LOOP, к которому, вероятно, большинство Schemers не одобрит).

С другой стороны, программист на Си вполне может считать CL функциональным языком. В конце концов, большая часть кода, написанного на любом диалекте Лиспа, гораздо более функциональна по стилю, чем ваш обычный блок кода на C. Кроме того, Scheme - очень обязательный язык по сравнению с Haskell. Поэтому я не думаю, что когда-либо может быть определенный ответ да / нет. Называть ли язык функциональным или нет, зависит от вашей точки зрения.

4 голосов
/ 02 октября 2008

Ruby - это объектно-ориентированный язык, который может поддерживать другие парадигмы (функциональные, императивные и т. Д.). Однако, поскольку все в Ruby является объектом, это прежде всего язык OO.

пример:

"hello" .reverse () = "olleh", каждая строка является экземпляром строкового объекта и т. Д. И т. П.

Читайте здесь или здесь

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

Строго говоря, не имеет смысла описывать язык как «функциональный»; большинство языков способны к функциональному программированию. Даже C ++ есть.

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

Последнее, возможно, является незначительной технической особенностью, связанной с реализацией, и не имеет ничего общего с реальным языком. Компилятор x64 C # 4.0 выполняет оптимизацию хвостовой рекурсии, а компилятор x86 - по какой-то глупой причине.

Синтаксический сахар обычно в той или иной степени можно обойти, особенно если в языке есть программируемый прекомпилятор (т. Е. C #define).

Возможно, было бы немного более содержательно спросить: «Поддерживает ли язык __ императивное программирование?», И ответ, например, на Лиспе, «нет».

2 голосов
/ 29 июня 2009

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

Функциональные языки программирования способны оптимизировать хвостовую рекурсию и могут выполнять такой код в постоянном пространстве. Некоторые реализации Ruby оптимизируют хвостовую рекурсию, другие - нет, но в общем случае реализации Ruby не требуется для TCO. См. Выполняет ли Ruby оптимизацию Tail Call?

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...