Википедия говорит, что Ruby - это функциональный язык, но я не уверен. Почему или почему нет?
Википедия говорит, что Ruby - это функциональный язык, но я не уверен. Почему или почему нет?
Ответы:
Я определенно считаю, что в Ruby можно использовать функциональный стиль.
Одним из наиболее важных аспектов программирования в функциональном стиле является то, поддерживает ли язык функции более высокого порядка ... что делает Ruby.
Тем не менее, на Ruby легко программировать и в нефункциональном стиле. Другой ключевой аспект функционального стиля - отсутствие состояния и наличие реальных математических функций, которые всегда возвращают одно и то же значение для заданного набора входных данных. Это можно сделать в Ruby, но не в языке, как в чем-то более строго функциональном, например, Haskell.
Так что да, он поддерживает функциональный стиль, но также позволяет программировать в нефункциональном стиле.
Is ruby a functional language?
и в прямом ответе просто нет. Ruby - это объектно-ориентированный язык с некоторыми функциональными возможностями.
Неважно, является ли язык функциональным языком или нет. Функциональное программирование - это тезис, лучше всего объясненный Филипом Уодлером (Суть функционального программирования) и Джоном Хьюзом (Почему функциональное программирование имеет значение).
Значимый вопрос: «Насколько Ruby поддается реализации тезиса функционального программирования?» Ответ - «очень плохо».
Я говорил об этом совсем недавно. Вот слайды.
Ruby действительно поддерживает функции более высокого уровня (см. Array # map, inject, & select), но это все еще императивный объектно-ориентированный язык.
Одна из ключевых характеристик функционального языка - это то, что он избегает изменчивого состояния. В функциональных языках нет концепции переменной, как в Ruby, C, Java или любом другом императивном языке.
Другой ключевой характеристикой функционального языка является то, что он фокусируется на определении программы в терминах «что», а не «как». При программировании на объектно-ориентированном языке мы пишем классы и методы, чтобы скрыть реализацию («как») от «что» (имя класса / метода), но в конце концов эти методы по-прежнему пишутся с использованием последовательности операторов. В функциональном языке вы не указываете последовательность выполнения даже на самом низком уровне.
Я утверждаю, что поддержка или способность программировать на языке в функциональном стиле не являются функциональным языком.
Я даже могу написать Java-код в функциональном стиле, если хочу нанести вред своим коллегам и себе через несколько месяцев .
Функциональный язык - это не только то, что вы можете делать, например, функции высшего порядка, функции первого класса и каррирование. Речь также идет о том, чего вы не можете делать, например о побочных эффектах в чистых функциях.
Это важно, потому что это большая часть причины, по которой функциональные программы или функциональный код в целом легче рассуждать. А когда код легче рассуждать, ошибки становятся более мелкими и всплывают на концептуальную поверхность, где их можно исправить, что, в свою очередь, дает меньше ошибок в коде.
Ruby по своей сути объектно-ориентирован, поэтому, хотя он имеет достаточно хорошую поддержку функционального стиля, сам по себе он не является функциональным языком.
Во всяком случае, это мое ненаучное мнение.
Изменить: оглядываясь назад и учитывая прекрасные комментарии, которые я получил к этому ответу, я думаю, что объектно-ориентированное и функциональное сравнение - это одно из яблок и апельсинов.
Настоящее отличие заключается в том, чтобы быть беспараентным в исполнении или нет. В функциональных языках выражение является основной лингвистической конструкцией, а порядок выполнения часто не определен или определяется как ленивый. Строгое исполнение возможно, но используется только при необходимости. На непаративном языке строгое выполнение является значением по умолчанию, и, хотя ленивое выполнение возможно, оно часто является трудоемким и может иметь непредсказуемые результаты во многих крайних случаях.
Теперь это мое ненаучное мнение.
Ruby должен будет соответствовать следующим требованиям, чтобы быть "НАСТОЯЩИМ" функциональным.
Неизменяемые значения: после того, как «переменная» установлена, ее нельзя изменить. В Ruby это означает, что переменные нужно рассматривать как константы. Не полностью поддерживается на языке, вам придется заблокировать каждую переменную вручную.
Никаких побочных эффектов: при передаче заданного значения функция всегда должна возвращать тот же результат. Это идет рука об руку с неизменными значениями; функция никогда не может принимать значение и изменять его, так как это может вызвать побочный эффект, не связанный с возвратом результата.
Функции высшего порядка: это функции, которые позволяют использовать функции в качестве аргументов или использовать функции в качестве возвращаемого значения. Это, пожалуй, одна из самых важных особенностей любого функционального языка.
Каррирование: включаемое функциями высшего порядка, каррирование преобразует функцию, которая принимает несколько аргументов, в функцию, которая принимает один аргумент. Это идет рука об руку с приложением частичной функции, которое преобразует функцию с несколькими аргументами в функцию, которая принимает меньше аргументов, чем это было изначально.
Рекурсия: цикл путем вызова функции изнутри себя. Когда у вас нет доступа к изменяемым данным, рекурсия используется для построения и цепочки построения данных. Это связано с тем, что цикл не является функциональной концепцией, так как он требует, чтобы переменные передавались для сохранения состояния цикла в данный момент времени.
Ленивая оценка или отложенная оценка: откладывание обработки значений до того момента, когда это действительно необходимо. Если, например, у вас есть код, который сгенерировал список чисел Фибоначчи с включенным отложенным вычислением, он фактически не будет обрабатываться и вычисляться до тех пор, пока одно из значений в результате не потребуется другой функции, такой как put.
Предложение (просто мысль)
Было бы здорово иметь какое-то определение, чтобы иметь mode
директиву для объявления файлов с функциональной парадигмой, например
режим 'функциональный'
Ruby - это мультипарадигмальный язык, поддерживающий функциональный стиль программирования.
Ruby - объектно-ориентированный язык, который может поддерживать другие парадигмы (функциональные, императивные и т. Д.). Однако, поскольку все в Ruby является объектом, это прежде всего объектно-ориентированный язык.
пример:
"hello" .reverse () = "olleh", каждая строка является экземпляром строкового объекта и так далее, и так далее.
Это зависит от вашего определения «функционального языка». Лично я считаю, что этот термин сам по себе довольно проблематичен, когда используется как абсолют. У «функционального языка» больше аспектов, чем просто языковых функций, и большинство из них зависит от того, откуда вы смотрите. Например, в этом отношении очень важна культура, окружающая язык. Поощряет ли это функциональный стиль? А как насчет доступных библиотек? Они побуждают вас использовать их функционально?
Например, большинство людей назвали бы Scheme функциональным языком. Но как насчет Common Lisp? Помимо проблемы с несколькими / одиночными пространствами имен и гарантированного исключения хвостового вызова (которое также поддерживается некоторыми реализациями CL, в зависимости от настроек компилятора), мало что делает Scheme как язык более подходящим для функционального программирования, чем Common Lisp, и тем не менее, большинство Lisp'ов не назовут CL функциональным языком. Зачем? Потому что окружающая его культура сильно зависит от императивных функций CL (например, макроса LOOP, который, вероятно, не понравится большинству программистов).
С другой стороны, программист на C вполне может считать CL функциональным языком. В конце концов, большая часть кода, написанного на любом диалекте Лиспа, безусловно, намного более функциональна по стилю, чем ваш обычный блок кода C. Точно так же Scheme - во многом императивный язык по сравнению с Haskell. Поэтому я не думаю, что когда-либо может быть однозначный ответ да / нет. Называть язык функциональным или нет - во многом зависит от вашей точки зрения.
Я думаю, что Ruby на самом деле не является многопарадигмальным языком. Мультипарадигма обычно используется людьми, которые хотят обозначить свой любимый язык как нечто полезное во многих различных областях.
Я бы описал Ruby как объектно-ориентированный язык сценариев. Да, функции - это объекты первого класса (вроде), но это не делает их функциональным языком. ИМО, могу добавить.
Рекурсия распространена в функциональном программировании. Практически любой язык поддерживает рекурсию, но рекурсивные алгоритмы часто неэффективны, если нет оптимизации хвостового вызова (TCO).
Функциональные языки программирования способны оптимизировать хвостовую рекурсию и выполнять такой код в постоянном пространстве. Некоторые реализации Ruby оптимизируют хвостовую рекурсию, другие - нет, но в целом реализации Ruby не требуют TCO. Смотрите, выполняет ли Ruby оптимизацию хвостового вызова?
Итак, если вы напишете какой-то функциональный стиль Ruby и полагаетесь на совокупную стоимость владения какой-то конкретной реализации, ваш код может оказаться очень неэффективным в другом интерпретаторе Ruby. Я думаю, что именно поэтому Ruby не является функциональным языком (как и Python).
Строго говоря, не имеет смысла называть язык «функциональным»; большинство языков способны к функциональному программированию. Даже C ++ есть.
Функциональный стиль - это более или менее подмножество императивных языковых функций, поддерживаемых синтаксическим сахаром и некоторыми оптимизациями компилятора, такими как неизменность и сглаживание хвостовой рекурсии,
Последнее, возможно, является незначительной технической особенностью конкретной реализации и не имеет ничего общего с реальным языком. Компилятор x64 C # 4.0 оптимизирует хвостовую рекурсию, тогда как компилятор x86 не делает этого по какой-то глупой причине.
Синтаксический сахар обычно можно в той или иной степени обойти, особенно если в языке есть программируемый прекомпилятор (например, #define в языке C).
Возможно, было бы немного более осмысленным спросить: «Поддерживает ли язык __ императивное программирование?», И ответ, например, с Lisp, будет «нет».
Пожалуйста, посмотрите начало книги: "A-Great-Ruby-eBook" . В нем обсуждается очень конкретная тема, которую вы задаете. На Ruby можно программировать разные типы. Если вы хотите программировать как функционально, вы можете это сделать. Если вы хотите программировать как императивно, вы можете это сделать. Насколько функциональна Ruby в конечном итоге - это вопрос определения. Пожалуйста, смотрите ответ пользователя camflan.