2011-10-27 16 views
7

Rileggendo parte del mio codice Scala, ho notato che è funzionale o orientato agli oggetti.Come combinare paradigmi apparentemente incompatibili: OOP e FP?

In effetti, non ho idea di come conciliare la regola degli effetti secondari implicita da tipi immutabili e funzioni pure e la premessa di OO, dove i metodi modificano lo stato dell'istanza sul posto, che è ovviamente effetti collaterali.

Una soluzione che sto studiando è di rendere tutti i metodi restituire un clone dell'istanza corrente con le modifiche di stato appropriate. Sembra desideroso, ma potrebbe aiutare quando deciderò di paralizzare il codice, giusto?

Quali sono le migliori pratiche sul mix di quei 2 paradigmi? Qual è il bilancio?

Grazie.

+2

Lettura interessante e altamente correlata: [Sono FP e OO ortogonali?] (Http://stackoverflow.com/q/3949618/395760) – delnan

+4

È questa la premessa di OO? Perché, allora, Effective Java raccomanda oggetti immutabili? Penso che dovresti iniziare a conciliare la tua visione di OO con quello che gli esperti hanno effettivamente detto ... –

risposta

2

penso realmente in disaccordo con il modo in cui si sta inquadrando questo:

Anzi, non ho idea su come conciliare l'effetti regola del non-lato implicita tipi immutabili e funzioni puri e il premessa di OO, dove i metodi modificano lo stato dell'istanza sul posto, che è ovviamente effetti collaterali.

Non direi che le operazioni mutative sui campi oggetto sono una "premessa fondamentale di OO". Assolutamente no (anche se al contrario io do penso che l'immutabilità sia una premessa fondamentale di FP). Per me, OO è un modo di pensare al programma modularità più che altro.

Nella mia (forse contorta) mentalità, anche Haskell - un linguaggio i cui sostenitori spesso si arrovellano al pensiero stile OO - tuttavia incarna alcuni concetti OO, nel senso che ha un sistema modulare, vari modi di incapsulare l'implementazione dettagli di tipi di dati, ecc. E sul rovescio della medaglia, anche se è eccezionalmente goffo e aggravante, il mio codice Java tende a fare un uso pesante di concetti funzionali di base come il currying.

In altre parole, penso che i due approcci siano complementari in un certo senso.

Ora, ad un livello meno teorica e più dadi e bulloni ... Diciamo che hai qualcosa di simile:

class Foo(val a : A, val b : B, val c : C) { 
    def setB(newb : B) : Foo = new Foo(a, newb, c) 
} 

... così si può dire newFoo = foo.setB(b) come lei ha suggerito nel post originale . Direi che questo è uno stile assolutamente eccellente, e non è motivo di preoccupazione (in termini di prestazioni, leggibilità o altro). Ne vedrai un sacco con le immutabili classi di raccolta nella libreria Scala.

+0

Se dici che OO è connesso a Modularità, potresti descrivere come si realizza? Quali caratteristiche utilizza OO per modularità schuss? Mi sto chiedendo perché sono curioso e penso di essere semplice e raggiungere la modularità Non posso pensare a utili (esclusive) funzionalità OO che lo realizzano. Forse Polymorphism 'a la carte' vedi qui: http://www.infoq.com/presentations/Simple-Made-Easy? – AndreasScheinert

0

Si potrebbe voler controllare il Functional Programming chapter di Programmazione Scala (è available free online) per ottenere alcuni suggerimenti.

FP non si tratta solo di threading. Le funzioni di ordine elevato possono aiutarti a ripulire e asciugare il codice, rendendolo più elegante.

+0

Grazie per la tua risposta. Sono pienamente convinto dei vantaggi della FP, e li ho già applicati, ma mi chiedo sulla frontiera della dualità espressa nella top post. –

+0

FP non intende "rendere elegante il tuo codice", ma riguarda la componibilità e la modularità attraverso la riusabilità. – AndreasScheinert

+0

qualunque cosa tu dica –

7

Le classi immutabili sono un ottimo modo per collegare OO e FP. Scala Collection Library è un ottimo esempio di unione di OO, oggetti immutabili e programmazione funzionale.

Nel proprio codice, Scala case classes aiuta davvero l'implementazione di oggetti non modificabili, poiché hanno un metodo copy che può essere utilizzato come sostituzione per il modello di builder.

// begin cheesy example 
case class Circle(center: (Double, Double), radius: Double) { 
    def move(c: (Double, Double)) = copy(center = c) 
    def resize(r: Double) = copy(radius = r) 
    def area = math.Pi * radius * radius 
} 

Si può anche beneficiare guardare i colloqui di Rich Hickey Persistent Data Structures and Managed References, e Are We There Yet? Entrambi fanno un ottimo lavoro spiegando il bisogno di immutabilità e come ci aiuta a ragionare sullo stato. Parla di tutto rispetto a Clojure, ma i suoi punti si applicano altrettanto bene a Scala.

0

make tutti i metodi restituiscono un clone dell'istanza corrente

se controlli come jQuery fa, utilizza una tecnica chiamata metodo di concatenamento ogni metodo che altrimenti sarebbe tornato rendimenti nulli $ questo, in modo puoi continuare a chiamare i metodi uno sull'altro. Ecco perché l'oggettività jQuery non infrange il codice utente procedurale tradizionale in javascript.