2009-10-10 12 views
24

Clojure è una lisp funzionale, a quanto pare non orientata agli oggetti, anche se gira su JVM, una VM progettata per un linguaggio orientato agli oggetti. Clojure fornisce interfacce identiche per iterare su liste e vettori estraendoli a un'interfaccia chiamata seq. Questo è anche implementato internamente usando un'interfaccia Java chiamata ISeq. Non è questo un esempio di astrazione orientata agli oggetti? Come si può sostenere che Clojure non sia orientato agli oggetti?Clojure è orientato agli oggetti al centro? (Polymorphism in seqs)

Immagino un corollario a questa domanda --- quando il polimorfismo può essere considerato distinto dall'orientamento dell'oggetto?

+0

Un collegamento a una fonte per "riferito non a tutti object-oriented" sarebbe utile a capire se l'argomento è tecnico vs politico ... –

+2

http://clojure.org/rationale parla di OOP e del perché Clojure lo evita. –

+0

http://blog.thinkrelevance.com/2009/8/12/rifle-oriented-programming-with-clojure-2 è un articolo interessante che illustra come Clojure consente effettivamente l'uso di tutti i principali principali di OO. Tuttavia trovo che sia difficile combinarli. Ad esempio, l'utilizzo dell'incapsulamento di chiusura esclude l'estensione per eredità. L'approccio generale sembra essere quello di rinunciare all'incapsulamento a favore dell'estensibilità. –

risposta

27

Idiomatic Clojure favorisce la definizione di funzioni indipendenti che operano su un insieme molto piccolo di strutture di dati fondamentali; questa separazione di metodi e dati è una forte affermazione contro l'orientamento agli oggetti e in favore di uno stile funzionale. Rich Hickey (creatore di Clojure) ha ripetutamente affermato l'importanza di questo; per esempio qui: "Clojure eschews the traditional object-oriented approach of creating a new data type for each new situation, instead preferring to build a large library of functions on a small set of types.".

La dipendenza dalle strutture di dati fondamentali è ancora più importante in Clojure rispetto ad altri linguaggi funzionali, in quanto è possibile sfruttare appieno i vantaggi dell'SM di Clojure quando si utilizzano le strutture di dati persistenti di Clojure.

Immagino un corollario a questa domanda --- quando il polimorfismo può essere considerato distinto dall'orientamento dell'oggetto?

sto usando multimethods di Clojure (cioè strutture polimorfiche) di inviare a diverse implementazioni in base all'estensione di un nome di file - non è affatto orientata agli oggetti, ma polimorfico.

+14

"È meglio avere 100 funzioni su una struttura dati di 10 funzioni su 10 strutture dati." - Alan J. Perlis – Jonas

16

Immagino un corollario a questa domanda --- quando il polimorfismo può essere considerato distinto dall'orientamento dell'oggetto?

Il polimorfismo non ha assolutamente alcuna relazione con l'orientamento dell'oggetto. Significa semplicemente che la stessa operazione può comportarsi diversamente a seconda del/i tipo/i dei suoi operandi.

I linguaggi funzionali come ML o Haskell hanno avuto polimorfismo per più di 30 anni e qualcuno con una migliore conoscenza della storia PL può probabilmente indicare alcuni esempi pre-1962 (cioè pre-OO).

Christopher Strachey ha descritto la distinzione tra polimorfismo parametrico e polimorfismo ad-hoc nel 1967, quindi il polimorfismo deve avere già già esistente. Dal momento che il polimorfismo è stato introdotto solo in OO in Simula-67, la mia ipotesi è che il polimorfismo deve essere prima di essere introdotto in OO.

4

Clojures Il polimorfismo è un'estensione nativa di Java. Nei metodi java sono inviati in base alla classe. In Clojure questo è esteso per consentire di inviare chiamate in base a qualsiasi cosa tu voglia. È ancora molto facile da spedire in classe, infatti la maggior parte delle volte questo è come è stato fatto. Se vuoi qualcos'altro, puoi scrivere a il tuo supervisore. La funzione incorporata derive per creare una gerarchia basata su tutto ciò che si desidera e quindi inviare su isa. più

bontà a: http://clojure.org/multimethods

5

Tenete a mente che le cose come sono iseq Java.

In Clojure l'astrazione seq è in realtà solo "qualcosa" che è possibile fornire alle funzioni first, rest e nth (nota che non si chiama prima su un seq, si chiama prima con un argomento seq). Le funzioni principali del linguaggio Clojure operano tutte su raccolte, seq o tipi primitivi. Non ci sono dati in bundle con i metodi nelle interfacce esposte. Quindi l'implementazione di Clojure è in Java e tutto ciò che intercorre con JVM coinvolgerà Classi/Oggetti, ma Clojure non lo stesso linguaggio.

I metodi di raggruppamento con strutture dati sono ciò che Clojure scoraggia.

Detto tutto questo ... la realtà è che le funzioni hanno limitazioni su quali argomenti con cui lavoreranno. il primo riposo e l'ennesimo funzionano solo su qualcosa che può essere un seq. Da questo punto di vista non c'è molta differenza se le strutture di dati sono raggruppate con metodi o meno - devi ancora abbinarle correttamente. Le grandi vittorie derivano dalla flessibilità. Le funzioni possono essere scritti a prendere qualsiasi argomento e quindi composti con funzioni di ordine superiore senza definire classi ecc:

(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 
Problemi correlati