Почему он не является функциональным языком программирования?
с возобновленным интересом к функциональным языкам программирования я видел некоторые сходства между Smalltalk и FPL, а именно замыкания ( BlockClosures в Smalltalk), но Smalltalk не является FPL?
Что необходимо рассматривать его как таковой?
9 ответов
Программирование с объектно-ориентированной парадигмой-это создание программы путем идентификации и моделирования сущностей проблемной области как объектов, а затем заставить их сотрудничать между собой для решения каждого экземпляра проблемы. Программирование с функциональной парадигмой моделирует задачу как математическую задачу и создает математическую функцию (составляя другие функции), которая для каждого экземпляра задачи вычисляет решение задачи.
на мой взгляд, функциональный язык программирования-это язык, который дает решение проблемы, решаемой с использованием парадигмы функционального программирования, язык может выразить это решение точно так, как оно было задумано. Если вам нужно "преобразовать" какую-то часть вашего решения, чтобы она соответствовала тому, что может выразить язык, тогда она не полностью поддерживает парадигму, которую вы использовали для решения.
Он может выразить в большинстве случаев все решения, созданные с использованием объектно-ориентированной парадигмы программирования, но это не может выразить примитивно много решений, созданных с использованием парадигмы функционального программирования. Вот почему я не считаю это FPL. Несмотря на то, что вы не можете выразить каждое решение, которое может FPL, Smalltalk является чрезвычайно расширяемым, и вы можете расширить его, чтобы выразить все решения, которые может FPL.
нет принятого определения функционального языка программирования.
Если вы определяете функциональный язык как язык, поддерживающий функции первого класса, то да, Smalltalk *является * функциональным языком.
Если вы также рассматриваете такие факторы, как поддержка неизменяемости, алгебраические типы данных, сопоставление шаблонов, частичное применение и т. д., то нет, Smalltalk *не является функциональным языком.
Я бы рекомендовал вам прочитать следующее сообщения в блоге (а также комментарии под ними):
Smalltalk не может быть "чистым функциональным языком" (что бы это ни было). Однако естественное использование Smalltalk часто приводит к функциональному коду. (То, что я думаю, люди Scala назвали бы "объектно-функциональным".)
например, класс точки скрипа имеет функциональный API: методы, такие как 1@1 translateBy: 1@1
возвращает новые точки с новым состоянием, вместо изменения внутреннего состояния. (Это делает точку практически неизменной, так как единственный способ изменить внутреннее состояние объекта - через механизмы отражения, такие как #instVarAt:.)
вполне нормально использовать функции более высокого порядка в Smalltalk, такие как карты, фильтры, складки и тому подобное. Учитывая, что они запечены в API коллекций, часто проще написать код, который использует коллекции функциональным способом, чем нет.
так много людей имеют так много определений "функционального языка программирования" , что вопрос "Foo a FPL" так же бесполезен, как вопрос " Является ли Foo объектно-ориентированным язык."
сказав, что вот мои два цента: функциональный язык программирования это язык, на котором он естественные и идиоматическое использовать функциональные методы: первоклассные функции, избегание мутабельного государства, функций побочного эффекта свободных, функций более высокого порядка.
по этому описанию Smalltalk является функциональным языком программирования. Он вызывает функции первого порядка "методы" или "блоки" в зависимости от того, являются ли они по имени или без имени. Объекты хранят состояние в переменных экземпляра. Функции более высокого порядка-это просто методы, которые принимают блоки в качестве параметров.
сказав это, да, вы можете писать Smalltalk нефункциональным образом. Он допускает изменчивое состояние. Это останавливает Smalltalk от того, чтобы называться функциональным языком? Если это так, то эти языки не являются функциональными: Common Lisp, Erlang (общее состояние через словарь процессов, ets/dets).
Итак, вкратце, Smalltalk является FPL потому что:
- функции-это первоклассные сущности (объекты, в Smalltalk - CompiledMethods или BlockClosures, если быть точным).
- Smalltalk поддерживает закрытие (он называет их блоками).
- Smalltalk позволяет писать функционально естественным, идиоматическим образом.
и Smalltalk не является FPL потому что:
- вы как программист должны убедиться, что ваш структуры данных (объекты) неизменяемы (с помощью сеттеров/мутаторов, возвращающих копии объекта с измененным состоянием).
- вы как программист должны убедиться, что ваши методы (функции) не имеют побочных эффектов.
(некоторые из слухов делают, видимо, поддержка неизменяемых объектов. Мой опыт ограничен скрипом, который не поддерживает неизменность уровня VM.)
Edit: я не понимаю потребность igouy в именованных определениях функций, кроме как через определение методов для объекта. Но в любом случае, мы идем:
Smalltalk at: #func put: [:x | x + 1].
func value: 1.
Smalltalk-это чисто объектно-ориентированный язык, где почти весь код-это в основном объекты, обменивающиеся сообщениями. Функциональное программирование ориентировано на вызовы функций и композиции между функциями для создания более сложного поведения (избегая состояния для данных, в отличие от внутренних состояний, которые объекты имеют в любом объектно-ориентированном языке).
чисто функциональные языки обычно имеют неизменяемые переменные, что делает их более похожими на переменные в математическом смысле.
язык не становится функциональным языком, имея именованные функции - по этому определению, C будет функциональным ! Важнее функциональная семантика в математическом смысле, что результат зависит только от аргументов (в частности: никаких побочных эффектов). По этому определению объекты, которые могут быть изменены сеттерами, противоречат функциональному стилю программирования. Однако, как уже отмечалось, даже объекты могут использоваться в функциональном стиле (пример прямоугольника), если вы запретите побочные эффекты. И, кстати. существует двойственность между объектами с методами и набором функций, которые определены в закрытии над частным состоянием (см. SICP для деталей). Они могут моделировать друг друга взаимно:
(def (make_foo initVal1 ... initValN)
(let ((instVar1 initVal1) ... (instVarN initValN))
(define (method1 args) ...)
...
(define (methodN args) ...)
(define (lookup selector)
(cond ((eq? selector 'method1) method1)
...
((eq? selector 'methodN) methodN)
(true doesNotUnderstandCode)))
lookup)) ; returns the lookup function (provides "access into the closure") !
(defMacro (method1 receiver.args)
((receiver selector) args))
(define foo (make_foo 1 2 ...))
(method1 foo ...)
выше это моделирование "чистых" функциональных объектов и семантически то же самое, что и много Smalltalk кода! Однако, чтобы реализовать метод setter, вы должны добавить метод, который делает (set! instVar newValue). И, потому что сет! не функционирует, нарушает "функциональность" схемы.
резюме: посмотрите на семантику, а не на источник, люк !
спасибо всем за все ответы.
Я добавлю свой Здесь, который в основном является моим (вероятно, пропустить) понимание вашего.
Я думаю, что критерии, чтобы назвать что-то OO или FP, - это то, как "материал" строится с использованием языка; не то, как легко или трудно это сделать, я имею в виду, используемая ментальная парадигма.
например, как показали ссылки, может быть сложнее ввести что-то в Scala, чем в OCaml, но это не делает его менее FPL ( возможно, неполным или нечистые, но определенно функциональные ); потому что цель Scala-использовать функции в качестве основных строительных блоков, а не объектов.
с другой стороны, упрощение написания функции на языке не делает ее функциональной, если стиль или цель-использовать другие артефакты. Например, Smalltalk упрощает запись анонимного блока или предоставляет подключаемый компаратор сортировки, но это не делает его функциональным вообще, потому что фокус заключается в использовании объектов и передавать сообщения. Blockclosures-это просто механизм для кодирования этих сообщений (а не функций), даже если они выглядят так, как будто они были функциями.
возникает путаница, потому что OO и FP ортогональны ( as Рахул указано через twitter), поэтому то, что выглядит как закодированное сообщение в Smalltalk, выглядит в значительной степени как анонимная функция в Scala. Но делать что-то подобное не превращает язык одной парадигмы в другую.
сделать хуже всего, Scala также использует парадигму OO, чтобы сделать ее более легкой для программистов mainstream ( Java, C++, C#), чтобы дать скачок, и, если вы видите, у нее было больше успеха, чем у любого другого FPL. И, конечно, это было благодаря Java (IMHO, если Clojure имеет какой-либо успех, будет по той же причине, JVM )
в заключение: язык программирования может быть классифицирован по парадигме, которую он использует для создания "вещей". Есть языки, которые чисты, как [Smalltalk: OO, Haskell: Functional, C: Procedural] или гибриды, такие как Scala или multi paradigm, такие как C++, Ruby, Python.
тот факт, что вы можете писать один стиль с другим языком, не делает его языком этого стиля. Как имитировать объекты с Лиспом не ОО, ни использование функций с Java сделать ее функциональной.
чтобы ответить на вопрос, который будет считаться функциональным, Smalltalk должен будет использовать функции в качестве строительных блоков, чего он не делает потому что он использует объекты.
Я видел некоторые сравнения между Smalltalk и FPL, а именно замыкания
существует более основное сходство-каждое сообщение Smalltalk всегда возвращает значение.
но теперь посмотрите на Принципы Проектирования За Smalltalk
[Smalltalk] отправляет имя пожеланная деятельность, вместе с любым аргументы, как сообщение К числу, с пониманием того, что приемник лучше знает, как носить из нужная операция.
это описывает то, что вы думаете о функциональном программировании?
@Frank Shearar-это описывает Erlang тоже. Эрланг теперь не функционирует?
Erlang - это что - то вроде химеры-последовательное Программирование основано на функциях, но параллельное программирование основано на передаче сообщений между процессами. Так что Erlang-это не мульти парадигмы или гибрид в сторону, что другие языки позволяют стили, используемые для достижения одной и той же цели - он использует разные стили для разных целей.
что было бы необходимо рассмотреть его как таких?
способ объявления функций, а не способ объявления методов в классе
способ структурирования программы вокруг функций, а не вокруг объектов
@Missing Faktor-но не является ли func в этом примере именованным функции?
|func v|
func := [:x | x + 1].
v := func value: 5.
нет func
локальная переменная. Ты связан!--25-->анонимная функция к локальной переменной func
.
|func v|
func := [:x | x + 1].
func := 2.
v := func value: 5.
чтобы увидеть разницу, посмотрите на этот пример Erlang который показывает как анонимную функцию, так и именованную функцию.