Является ли Clojure объектно-ориентированным в своем сердце? (Полиморфизм в последовательностях) - PullRequest
24 голосов
/ 10 октября 2009

Clojure - это функциональный шрифт, который, как сообщается, совсем не объектно-ориентирован, хотя он работает на JVM, виртуальной машине, предназначенной для объектно-ориентированного языка. Clojure предоставляет идентичные интерфейсы для перебора списков и векторов, абстрагируя их от интерфейса с именем seq. Это даже реализовано внутренне с использованием интерфейса Java, называемого ISeq. Разве это не пример объектно-ориентированной абстракции? Как можно утверждать, что Clojure не является объектно-ориентированным?

Полагаю, следствие этого вопроса - когда можно считать полиморфизм отличным от ориентации объекта?

Ответы [ 4 ]

27 голосов
/ 10 октября 2009

Idiomatic Clojure поддерживает определение независимых функций, которые работают с очень небольшим набором базовых структур данных; Такое разделение методов и данных является сильным утверждением против ориентации объекта и в пользу функционального стиля. Рич Хики (создатель Clojure) неоднократно заявлял о важности этого; например, здесь: "Clojure отказывается от традиционного объектно-ориентированного подхода создания нового типа данных для каждой новой ситуации, вместо этого предпочитая создавать большую библиотеку функций на небольшом наборе типов." .

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

Полагаю, следствие этого вопроса --- когда можно считать полиморфизм отличным от ориентации объекта?

Я использую мультиметоды Clojure (т.е. полиморфные средства) для отправки в различные реализации, основанные на расширении имени файла - не совсем объектно-ориентированные, но полиморфные.

17 голосов
/ 11 октября 2009

Полагаю, следствие этого вопроса --- когда можно считать полиморфизм отличным от ориентации объекта?

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

Функциональные языки, такие как ML или Haskell, имеют полиморфизм более 30 лет, и кто-то, кто лучше знает историю PL, может указать на некоторые примеры до 1962 года (т.е. до OO).

Кристофер Стрейчи описал различие между параметрическим полиморфизмом и специальным полиморфизмом в 1967 году, поэтому полиморфизм должен был уже существовать тогда. Поскольку полиморфизм был введен только в ОО в Simula-67, я предполагаю, что полиморфизм должен существовать до того, как он был введен в ОО.

6 голосов
/ 13 октября 2009

Имейте в виду, что такие вещи, как ISeq - это Java.

В Clojure абстракция seq на самом деле является просто «чем-то», что вы можете предоставить первой, остальной и n-й функциям (обратите внимание, что вы не вызываете сначала в seq, сначала вы вызываете с аргументом seq). Все основные функции языка Clojure работают с коллекциями, последовательностями или примитивными типами. В представленных интерфейсах нет данных, связанных с методами. Таким образом, реализация Clojure осуществляется на Java, и все взаимодействие с JVM будет включать классы / объекты, но сам язык Clojure этого не делает.

Объединение методов со структурами данных - вот что не одобряет Clojure.

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

(def farms [{:name "Swansea", :value 100}
            {:name "Broadmarsh", :value 200, :produce [:corn :wheat :rye]}
            {:name "Snug", :value 50, :animals [:goats :pigs]}])
(reduce + (map :value farms))
-> 350
(reduce + (map :value (filter :animals farms)))
-> 50
4 голосов
/ 13 октября 2009

Clojures Полиморфизм является естественным расширением Java. В java методы отправляются в соответствии с классом. В clojure это расширено, чтобы позволить вам отправлять вызовы, основываясь на чем угодно. Его по-прежнему очень легко отправить на урок, и в большинстве случаев так оно и есть. Если вам нужно что-то еще, вы можете написать свой собственный диспетчер. Встроенная функция derive для создания иерархии, основанной на чем угодно, и последующей отправки на isa.

больше добра в: http://clojure.org/multimethods

...