Почему smalltalk не является функциональным языком программирования? - PullRequest
21 голосов
/ 20 августа 2010

С возобновлением интереса к функциональным языкам программирования я видел некоторые сходства между Smalltalk и FPL, а именно замыкания (BlockClosures в Smalltalk). Тем не менее, Smalltalk не является FPL?

Что нужно было бы считать таковым?

Ответы [ 9 ]

27 голосов
/ 20 августа 2010

Нет принятого определения функционального языка программирования.

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

Если вы также учитываете такие факторы, как поддержка неизменяемости, алгебраические типы данных, сопоставление с образцом, частичное применение и т. Д., То нет, Smalltalk * не является * функциональным языком.


Я бы рекомендовал вам прочитать следующие похожие посты в блоге (а также комментарии под ними):

22 голосов
/ 20 августа 2010

Smalltalk может не быть «чисто функциональным языком» (каким бы он ни был).Однако естественное использование Smalltalk часто приводит к функциональному коду.(То, что люди из Scala называют «объектно-функциональными»).

Например, класс Point Squeak имеет функциональный API: методы, такие как 1@1 translateBy: 1@1, возвращают новые точки с новым состоянием, а не изменяют внутреннее состояние.государство.(Это делает Point практически неизменным, поскольку единственный способ изменить внутреннее состояние объекта - через механизмы отражения, такие как #instVarAt:.)

Вполне нормально использовать функции высокого порядка в Smalltalk, такие как карты, фильтры,складки и тому подобное.Учитывая, что они встроены в API коллекций, часто проще написать код, который использует коллекции функциональным способом, чем нет.

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

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

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

Сказав, что да, вы можете писать Smalltalk нефункциональным образом.Это допускает изменчивое состояние.Это мешает Smalltalk называться функциональным языком?Если это так, ни один из этих языков не функционирует: Common Lisp, Erlang (общее состояние через словарь процессов, ets / dets).

Итак, вкратце, Smalltalk - это FPL , потому что:

  • Функции - это объекты первого класса (точнее, объекты в Smalltalk - CompiledMethods или BlockClosures).
  • Smalltalk поддерживает замыкания (он называет их блоками).
  • Smalltalk позволяет писать функционально естественным идиоматическим образом.

и Smalltalk не является FPL , потому что:

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

(Некоторые Smalltalks, очевидно, поддерживают неизменяемые объекты. Мой опыт ограничен Squeak, который не поддерживает неизменяемость на уровне VM.)

Редактировать: Я неПонять, что Игуи нуждается в определениях именованных функций, кроме как путем определения методов для объекта.Но в любом случае, мы идем:

Smalltalk at: #func put: [:x | x + 1].
func value: 1.
13 голосов
/ 20 августа 2010

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

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

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

7 голосов
/ 20 августа 2010

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

5 голосов
/ 23 августа 2010

Язык не становится функциональным языком с именованными функциями - по этому определению C будет функциональным! Более важной является функциональная семантика в математическом смысле, что результат зависит только от аргументов (в частности: без побочных эффектов). По этому определению объекты, которые могут быть изменены сеттерами, противоречат функциональному стилю программирования. Однако, как уже указывалось, даже объекты можно использовать в функциональном стиле (пример Rectangle), если вы запрещаете побочные эффекты. И, кстати. Существует двойственность между объектами с методами и набором функций, которые определены в замыкании над частным состоянием (подробнее см. 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! Однако, чтобы реализовать метод установки, вы должны добавить метод, который выполняет (set! InstVar newValue). И, потому что установлено! не работает, нарушает «функциональность» схемы.

Резюме: посмотрите на семантику, а не на источник, Люк!

5 голосов
/ 20 августа 2010

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

2 голосов
/ 24 августа 2010

Спасибо всем за все ответы.

Я добавлю сюда мое, что в принципе и является моим (вероятно, мисс) пониманием вашего.

Я думаю, что критерии для того, чтобы называть что-либо OO или FP, - это то, как «материал» строится с использованием языка; не то, насколько легко или трудно это сделать, я имею в виду используемую ментальную парадигму.

Например, как показывают ссылки, может быть сложнее что-то набрать в Scala, чем в OCaml, но это не делает его менее FPL (может быть неполным или нечистым, но определенно функциональным); потому что целью Scala является использование функций в качестве основных строительных блоков, а не объектов.

С другой стороны, упрощение написания функции на языке не делает ее функциональной, если стиль или цель - использовать другие артефакты. Например, Smalltalk позволяет очень легко написать анонимный блок или предоставить подключаемый компаратор сортировки, но это вовсе не делает его ЛЮБЫМ функциональным, потому что основное внимание уделяется использованию объектов и передаче сообщений. Blockclosures - это просто механизм для кодирования этих сообщений (а не функций), даже если они выглядят так же, как и функции.

Путаница возникает из-за того, что OO и FP ортогональны (как Rahul указано в твиттере), поэтому то, что выглядит как закодированное сообщение в Smalltalk, во многом похоже на анонимную функцию в Scala. Но выполнение чего-то подобного не превращает язык одной парадигмы в другую.

Что еще хуже, Scala также использует OO-парадигму, чтобы облегчить переход программистам (Java, C ++, C #), и, если вы видите, он добился куда большего успеха, чем любой другой FPL сделал. И, конечно, это было благодаря Java (ИМХО, если Clojure добьется успеха, будет по той же причине, JVM)

В заключение : Язык программирования может быть классифицирован по парадигме, которую он использует для построения «вещей». Есть такие чистые языки, как [Smalltalk: OO, Haskell: Functional, C: Procedural] или гибриды, такие как Scala или multi-paradigm, например C ++, Ruby, Python.

Тот факт, что вы можете написать один стиль с другим языком, не делает его этим языком этого стиля. Подобно тому, как симуляция объектов с помощью Lisp не делает его OO, а использование функций с Java не делает его функциональным.

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

1 голос
/ 23 августа 2010

Я видел некоторые сходства между Smalltalk и FPL, а именно замыкания

Существует более базовое сходство - каждое сообщение Smalltalk всегда возвращает значение.

Но теперьвзгляните на Принципы разработки, стоящие за Smalltalk

[Smalltalk] отправляет имя нужной операции вместе с любыми аргументами в виде сообщения на номер, понимая, чтоПриемник лучше всех знает, как выполнить нужную операцию.

Описывает ли это то, что вы называете функциональным программированием?

@ Фрэнк Шеарар - Это также относится и к Эрлангу.Erlang теперь не работает?

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

0 голосов
/ 21 августа 2010

Что нужно было бы рассматривать как таковое?

  • способ объявления функций, а не способ объявления методов в классе

  • способ структурировать программу вокруг функций, а не вокруг объектов

@ Отсутствует фактор - но в данном примере это не func - именованная функция?

|func v|
func := [:x | x + 1].
v := func value: 5.

Нет func - локальная переменная.Вы связали анонимную функцию с локальной переменной func.

|func v|
func := [:x | x + 1].
func := 2.
v := func value: 5.

Чтобы увидеть разницу, посмотрите на этот пример Erlang , который показывает обаанонимная функция и именованная функция.

...