La programmazione funzionale ignora i vantaggi ottenuti da "Sui criteri da utilizzare per la decomposizione dei sistemi in moduli" (nascondere i dati)?


27

C'è un articolo classico chiamato On the Criteria To Be Use in Decomposing Systems in Modules che ho appena letto per la prima volta. Ha perfettamente senso per me ed è probabilmente uno di quegli articoli su cui si basava OOP. La sua conclusione:

Abbiamo provato a dimostrare con questi esempi che è quasi sempre errato iniziare la decomposizione di un sistema in moduli sulla base di un diagramma di flusso. ... Ogni modulo è quindi progettato per nascondere tale decisione agli altri

Secondo la mia opinione non istruita e inesperta, la programmazione funzionale prende esattamente il contrario di questo articolo. La mia comprensione è che la programmazione funzionale rende idiomatico il flusso di dati. I dati vengono passati da una funzione all'altra, ogni funzione essendo intimamente consapevole dei dati e "cambiandoli" lungo il percorso. E penso di aver visto un Rich Hickey parlare in cui parla di come il nascondere i dati sia sopravvalutato o superfluo o qualcosa del genere, ma non ricordo di sicuro.

  1. Innanzitutto voglio sapere se la mia valutazione è corretta. Il paradigma FP e questo articolo sono filosoficamente in disaccordo?
  2. Supponendo che non siano d'accordo, in che modo FP "compensa" la mancanza di dati nascosti? Forse sacrificano il nascondere i dati ma ottengono X, Y e Z. Mi piacerebbe conoscere il ragionamento per cui X, Y e Z sono considerati più vantaggiosi del nascondere i dati.
  3. Oppure, supponendo che non siano d'accordo, forse FP ritiene che nascondere i dati sia negativo. In tal caso, perché ritiene che nascondere i dati sia negativo?
  4. Supponendo che siano d'accordo, mi piacerebbe sapere quale sia l'attuazione del programma quadro per nascondere i dati. È ovvio vederlo in OOP. Puoi avere un privatecampo a cui nessuno al di fuori della classe può accedere. Non esiste un'analogia ovvia per me in FP.
  5. Sento che ci sono altre domande che dovrei porre, ma non so che dovrei fare. Sentiti libero di rispondere anche a quelli.

Aggiornare

Ho trovato questo discorso di Neal Ford che ha una diapositiva molto rilevante. Incorporerò lo screenshot qui:

inserisci qui la descrizione dell'immagine


1
Non posso rispondere alla domanda completa, ma per quanto riguarda (4), ci sono sistemi di moduli in alcuni linguaggi FP che possono fornire incapsulamento.
Andres F.

@AndresF. ah sì è vero. Ho dimenticato che Haskell ha moduli e puoi nascondere tipi di dati e funzioni al loro interno. Forse quando dico FP sto davvero dicendo Clojure. Puoi avere funzioni e "campi" privati ​​in Clojure, ma mi sembra idiomatico rendere i tuoi dati visibili a qualsiasi cosa e passarli ovunque.
Daniel Kaplan,

6
Quello che fai spesso è rendere visibili i tuoi tipi, ma nascondere i tuoi costruttori. Questi tipi astratti sono fatti particolarmente bene dal sistema di moduli OCaml
Daniel Gratzer,

6
In un linguaggio simile a ML, non avere accesso ai costruttori significa che non è possibile modellare la corrispondenza su un valore di quel tipo per decostruirlo. L'unica cosa che puoi fare con questi valori è passarlo a qualunque funzione sia stata resa disponibile. È lo stesso tipo di astrazione di dati che si fa, diciamo, in C, che non ha neanche le nozioni di prima classe di ciò che è pubblico o privato.
Luc Danton,

1
@ SK-logic: dal punto di vista del "problema dell'espressione", rivelare che i dati sono utili quando si desidera estenderli con una nuova funzione in futuro (e che sono OK nel mantenere i dati fissi) e nascondere i dati è buono quando si desidera estendersi con nuovi tipi di dati in futuro (a costo di mantenere fissa l'interfaccia funzionale)
hugomg

Risposte:


23

L'articolo di cui parli riguarda la modularità in generale e si applicherebbe allo stesso modo a programmi strutturati, funzionali e orientati agli oggetti. Ho già sentito parlare di quell'articolo da qualcuno che era un grande ragazzo di OOP, ma l'ho letto come un articolo sulla programmazione in generale, non qualcosa di OOP specifico. C'è un famoso articolo sulla programmazione funzionale, Perché la programmazione funzionale conta , e la prima frase della conclusione afferma "In questo documento, abbiamo sostenuto che la modularità è la chiave per una programmazione di successo". Quindi la risposta a (1) è no.

Le funzioni ben progettate non assumono più sui loro dati di quanto non debbano, quindi la parte relativa alla "conoscenza intima dei dati" è errata. (O almeno sbagliato come sarebbe di OOP. Non è possibile programmare rigorosamente a un livello elevato di astrazione e ignorare tutti i dettagli per sempre in qualsiasi paradigma. Alla fine, alcune parti del programma devono effettivamente conoscere il dettagli specifici dei dati.)

Nascondere i dati è un termine specifico di OOP e non è esattamente lo stesso dei nascondigli di informazioni discussi nell'articolo. Le informazioni nascoste nell'articolo riguardano decisioni di progettazione difficili da prendere o che potrebbero cambiare. Non tutte le decisioni di progettazione relative a un formato di dati sono difficili o suscettibili di modifica, e non tutte le decisioni che sono difficili o suscettibili di modifica riguardano un formato di dati. Personalmente, non riesco a capire perché i programmatori OO vogliono che tutto sia un oggetto. A volte basta una semplice struttura di dati.

Modifica: ho trovato una citazione pertinente da un'intervista a Rich Hickey .

Fogus: seguendo questa idea, alcune persone sono sorprese dal fatto che Clojure non si cimenta nell'incapsulamento di dati nascosti sui suoi tipi. Perché hai deciso di rinunciare a nascondere i dati?

Hickey: chiariamo che Clojure enfatizza fortemente la programmazione alle astrazioni. Ad un certo punto, però, qualcuno dovrà avere accesso ai dati. E se hai una nozione di "privato", hai bisogno delle corrispondenti nozioni di privilegio e fiducia. E ciò aggiunge una tonnellata di complessità e poco valore, crea rigidità in un sistema e spesso costringe le cose a vivere in posti dove non dovrebbero. Ciò si aggiunge alle altre perdite che si verificano quando le informazioni semplici vengono inserite in classi. Nella misura in cui i dati sono immutabili, c'è poco danno che può derivare dal fornire accesso, a parte il fatto che qualcuno potrebbe arrivare a dipendere da qualcosa che potrebbe cambiare. Bene, va bene, le persone lo fanno sempre nella vita reale e quando le cose cambiano si adattano. E se sono razionali, sanno quando prendono una decisione sulla base di qualcosa che può cambiare e che in futuro potrebbero aver bisogno di adattarsi. Quindi, è una decisione di gestione del rischio, una che penso che i programmatori dovrebbero essere liberi di prendere. Se le persone non hanno la sensibilità per desiderare di programmare le astrazioni e diffidare dal sposare i dettagli dell'implementazione, allora non saranno mai buoni programmatori.


2
I programmatori OO non vogliono che tutto sia un oggetto. Ma alcune cose (molte cose) beneficiano dell'incapsulamento. Ho difficoltà a capire come o dove la tua risposta affronta davvero la domanda. Sembra solo affermare che il concetto non è specifico di OOP e che OOP ha altri problemi e così via e così via - puoi forse fornire un chiaro esempio, anche se si tratta solo di poche righe di pseudocodice? O una descrizione sulla lavagna di un disegno che ne tenga conto? O qualcosa che confermerebbe le affermazioni qui?
Aaronaught,

2
@Aaronaught: ho affrontato molti (sebbene non tutti) i punti sollevati nella domanda e ho fatto riferimento a un documento sulla programmazione funzionale che guarda alla modularità in modo simile al documento nella domanda. In larga misura, il fatto che il concetto non sia specifico di OOP è la risposta alla sua domanda (a meno che non abbia frainteso completamente la domanda). Non ho davvero parlato di OOP che ha altri problemi qui. Hai un buon punto a fornire un esempio; Vedrò se riesco a trovarne uno buono.
Michael Shaw,

2
"A volte basta una semplice struttura di dati". +1. Qualcosa di OOP ha un senso, a volte è FP.
Laurent Bourgault-Roy,

1
@Aaronaught Questa risposta sottolinea che la modularità (che è sia incapsulamento che riutilizzo) è uno degli obiettivi di FP (come discusso in "Perché la programmazione funzionale conta"), rendendo quindi la risposta al punto (1) della domanda a " no".
Andres F.

2
@JimmyHoffa nascondere le informazioni è un principio sano anche al di fuori di OO. In haskell, voglio ancora che gli utenti possano lavorare con una quantità minima di conoscenza su qualsiasi struttura di dati. Certo, avere accesso agli interni è meno pericoloso perché nulla è mutevole. Ma meno un utente vede su un modulo / struttura dati / qualsiasi concetto astratto, più opportunità di refactoring ottieni. Non mi interessa se una mappa è un albero binario bilanciato o un mouse in una piccola scatola del mio computer. Questa è la principale motivazione alla base del nascondere i dati ed è valida al di fuori di OO.
Simon Bergot,

12

... ed è probabilmente uno di quegli articoli su cui si basava OOP.

Non proprio, ma si è aggiunto alla discussione, specialmente per i professionisti che, all'epoca, erano addestrati a scomporre i sistemi usando i primi criteri che descrive nel documento.

Innanzitutto voglio sapere se la mia valutazione è corretta. Il paradigma FP e questo articolo sono filosoficamente in disaccordo?

No. Inoltre, ai miei occhi, la tua descrizione di come appare un programma FP non è diversa da qualsiasi altra che usi procedure o funzioni:

I dati vengono passati da una funzione all'altra, ogni funzione essendo intimamente consapevole dei dati e "cambiandoli" lungo il percorso.

... ad eccezione della parte "intimità", poiché è possibile (e spesso lo fanno) avere funzioni che operano su dati astratti, proprio per evitare l'intimità. Quindi, hai un certo controllo su quella "intimità" e puoi regolarla come preferisci, impostando interfacce (cioè funzioni) per ciò che vuoi nascondere.

Quindi, non vedo alcun motivo per cui non saremmo in grado di seguire i criteri di Parnas per nascondere le informazioni utilizzando la programmazione funzionale e finire con l'implementazione di un indice KWIC con vantaggi simili simili alla sua seconda implementazione.

Supponendo che siano d'accordo, mi piacerebbe sapere quale sia l'attuazione del programma quadro per nascondere i dati. È ovvio vederlo in OOP. Puoi avere un campo privato a cui nessuno al di fuori della classe può accedere. Non esiste un'analogia ovvia per me in FP.

Per quanto riguarda i dati, è possibile elaborare astrazioni di dati e astrazioni di tipi di dati utilizzando FP. Ognuna di queste nasconde strutture concrete e manipolazioni di queste strutture concrete usando funzioni come astrazioni.

MODIFICARE

C'è un numero crescente di affermazioni qui che affermano che "nascondere i dati" nel contesto di FP non è così utile (o OOP-ish (?)). Quindi, lasciatemi timbrare qui un esempio molto semplice e chiaro di SICP:

Supponiamo che il tuo sistema debba lavorare con numeri razionali. Un modo in cui potresti volerli rappresentare è come una coppia o un elenco di due numeri interi: il numeratore e il denominatore. Così:

(define my-rat (cons 1 2)) ; here is my 1/2 

Se ignori l'astrazione dei dati, molto probabilmente otterrai il numeratore e il denominatore utilizzando care cdr:

(... (car my-rat)) ; do something with the numerator

Seguendo questo approccio, tutte le parti del sistema che manipolano i numeri razionali sapranno che un numero razionale è un cons- saranno consnumeri per creare razionali ed estrarli usando operatori di lista.

Un problema che potresti dover affrontare è quando devi avere una forma ridotta dei numeri razionali: saranno necessari cambiamenti nell'intero sistema. Inoltre, se decidi di ridurre al momento della creazione, potresti scoprire in seguito che è meglio ridurre quando si accede a uno dei termini razionali, producendo un altro cambiamento su vasta scala.

Un altro problema è se, ipoteticamente, si preferisce una rappresentazione alternativa per loro e si decide di abbandonare la consrappresentazione - di nuovo il cambiamento di fondo scala.

Qualsiasi sforzo sensato nel gestire queste situazioni probabilmente inizierà a nascondere la rappresentazione di razionali dietro le interfacce. Alla fine, potresti finire con qualcosa del genere:

  • (make-rat <n> <d>)restituisce il numero razionale il cui numeratore è il numero intero <n>e il cui denominatore è il numero intero <d>.

  • (numer <x>)restituisce il numeratore del numero razionale <x>.

  • (denom <x>)restituisce il denominatore del numero razionale <x>.

e il sistema non saprà più (e non dovrebbe più) sapere di cosa sono fatte le razionali. Questo perché cons, care cdrnon sono intrinseci ai razionali, ma make-rat, numere lo denom sono . Naturalmente, questo potrebbe facilmente essere un sistema FP. Quindi, "nascondere i dati" (in questo caso, meglio noto come astrazione dei dati, o lo sforzo di incapsulare rappresentazioni e strutture concrete) viene come un concetto pertinente e una tecnica ampiamente usata ed esplorata, sia nel contesto di OO, programmazione funzionale o qualunque cosa.

E il punto è ... sebbene si possa provare a fare distinzioni tra quale "tipo di nascondersi" o incapsulamento stanno facendo (se nascondono una decisione di progettazione, o strutture di dati o algoritmi - nel caso di astrazioni procedurali), tutti hanno lo stesso tema: sono motivati ​​da uno o più punti resi espliciti da Parnas. Questo è:

  • Modificabilità: se le modifiche richieste possono essere apportate localmente o se vengono diffuse nel sistema.
  • Sviluppo indipendente: fino a che punto due parti del sistema possono essere sviluppate in parallelo.
  • Comprensibilità: quanto del sistema è necessario per essere conosciuto per comprendere una delle sue parti.

L'esempio sopra è stato preso dal libro SICP, quindi, per la discussione completa e la presentazione di questi concetti nel libro, consiglio vivamente di dare un'occhiata al capitolo 2 . Raccomando anche di acquisire familiarità con i tipi di dati astratti nel contesto di FP, il che mette in discussione altri problemi.


Concordo sul fatto che nascondere i dati è rilevante in FP. E, come dici tu, ci sono modi per raggiungere questo obiettivo.
Andres F.

2
Hai appena fatto il mio punto magnificamente: hai queste funzioni che non nascondono i dati, sono espressioni che descrivono come ottenere i dati, quindi avendo l'astrazione in un'espressione piuttosto che in un campo di dati non devi preoccuparti di nascondere i dati creando un oggetto complesso con membri privati ​​o rendendo inaccessibili i valori negativi, vengono espresse le attività di generazione, recupero e interazione con dati razionali, pertanto i dati razionali effettivi non devono essere nascosti perché la modifica dei dati non lo farà cambia le tue espressioni.
Jimmy Hoffa,

8

La tua convinzione che la programmazione funzionale manchi di nascondere i dati è sbagliata. Ci vuole solo un approccio diverso per nascondere i dati. Uno dei modi più comuni per nascondere i dati nella programmazione funzionale è attraverso l'uso di funzioni polimorfiche che prendono una funzione come argomento. Ad esempio, questa funzione

map :: (a -> b) -> [a] -> [b]
map _ [] = []
map f (x:xs) = f x : map f xs

può vedere solo la struttura più esterna dei dati (ovvero che è un elenco) non può vedere nulla dei dati che contiene l'elenco e può operare sui dati solo attraverso la singola funzione che gli viene passata.

La funzione che viene passata come argomento è analoga a un metodo pubblico sul tipo di dati che contiene l'elenco. Fornisce un modo limitato di operare sui dati, ma non espone il funzionamento interno del tipo di dati.


5

Sto andando a colpire un arto qui e dire che il concetto non è rilevante in FP come è in OO.

tl; dr; Il punto di nascondere i dati è garantire che le responsabilità siano mantenute dove dovrebbero essere e che non ci siano attori esterni che si divertono con i dati per i quali non sono a conoscenza. In FP i dati sono generati da espressioni, e in questo modo non puoi fare confusione con i dati perché non sono proprietà mutabili tanto quanto i calcoli compostabili che cambiano completamente le regole del gioco.


Nelle mie esperienze con FP; che sono certamente insignificanti, tendo a trovare un netto contrasto con OO in ciò che denota una buona / comune modellizzazione dei dati.

Questo contrasto è che in OO in generale modellate cose per rappresentare i vostri dati. Analogia obbligatoria con l'auto:

OO

  • Hai un oggetto auto, che nasconde correttamente i dettagli sull'auto come l'implementazione CA (è a cinghia o azionato dalla pressione dell'aria? I consumatori non dovrebbero sapere, quindi nascondilo).
  • Questo oggetto auto ha molte proprietà e metodi che delineano tutti i fatti sull'auto, nonché i modi in cui puoi lavorare con un'auto.
  • Questo oggetto auto ha proprietà che sono componenti di un'auto che nascondono ulteriormente dall'auto generale le loro particolari implementazioni e i loro dati relativi ai dati che consentono ai componenti dell'auto di essere intercambiabili.

La cosa da notare qui è quando si modellano le cose in un formato OO, si tratta di rappresentare le cose come dati. Hai oggetti con proprietà, molte di queste proprietà sono oggetti con più proprietà. Hai un paio di metodi qua e là collegati a quegli oggetti, ma tutto ciò che fanno realmente è di solito jigger le proprietà degli oggetti in questo modo e che, di nuovo, è una modellazione molto incentrata sui dati; cioè modellizzi i tuoi dati per interagire focalizzandoti sulla strutturazione in modo da rendere disponibili tutti i punti dei tuoi dati in modo che i consumatori possano cambiare i dati in questo modo.

FP

  • Hai molti calcoli che ti consentono di descrivere i comportamenti
  • Queste espressioni di comportamento sono correlate in un modo che può essere tradotto nel modo in cui i comportamenti di un'auto sono correlati tra loro, come un'auto che ha accelerazione / decelerazione, ci sono due comportamenti che si oppongono l'un l'altro in modo simile.

La grande differenza tra OO e FP che mi colpisce costantemente è come ho detto sopra nel modo in cui modellate i dati. In OO, come menzionato sopra, si modellano i dati come dati, in FP si modellano i dati come calcoli, espressioni, algoritmi, si tratta più di modellare le attività dei dati che i fatti. Pensa alla modellazione di dati di base in matematica, si tratta sempre di ottenere un'equazione in grado di generare i tuoi dati, che modella i tuoi dati come l'attività che li provoca, al contrario di OO che la modellazione sta inventando un modo per rappresentare i dati che hai. Questa è molta distinzione tra FP e OO.

Ricorda, per molto tempo, LISP, uno dei linguaggi FP fondamentali, ha vissuto con una quantità molto piccola di tipi di dati primitivi. Questo funziona perché l'approccio non riguarda la modellazione di rappresentazioni complesse dei dati, ma i calcoli che generano ed esprimono i comportamenti del sistema.

Quando inizio a scrivere del codice in FP, inizio scrivendo codice che fa qualcosa, dove come quando inizio a scrivere codice in OO, inizio scrivendo modelli che descrivono qualcosa. Il fare delle cose è nascosto in FP essendo espressioni, il fare delle cose è esposto in OO essendo descritto con dati, nascondendo questi dati limita detta esposizione.


Tornando alla domanda a portata di mano, cosa dice FP in merito al nascondere i dati, lo apprezza o non è d'accordo con esso o cosa no?

Dico che non importa, in OO i tuoi dati sono le viscere e le parti importanti del tuo programma che dovrebbero essere nascoste dalla loro ingerenza. In FP l'intestino e la conoscenza del tuo sistema sono tutti nascosti negli algoritmi e nei calcoli che esprimono il sistema. Questi sono per definizione più o meno immutabili, l'unico modo per mutare le espressioni di calcolo sono cose come le macro, ma anche in questo caso le definizioni di mutazioni sono espressioni stesse che non possono essere ulteriormente intralciate.


è geniale, mi è davvero piaciuto leggerlo. Grazie per il tuo contributo
Chris McCall,

5

C'è un po 'di paradosso qui. Sebbene la programmazione funzionale si concentri su, beh, funzioni e spesso abbia funzioni che lavorano direttamente su tipi di dati primitivi, tende a nascondere più dati rispetto alla programmazione orientata agli oggetti.

Come va? Pensa a una bella interfaccia OO che nasconde i dati sottostanti - forse le raccolte (sto cercando di scegliere qualcosa di quasi onnipresente). Potrebbe non essere necessario conoscere il tipo di oggetto sottostante nella raccolta o il tipo di oggetto che implementa la raccolta, purché si sappia che la raccolta implementa, diciamo, IEnumerable. Quindi hai nascosto i dati.

Nella programmazione funzionale, è possibile scrivere una funzione che funzioni efficacemente con un'interfaccia IEnumerable, ma che opera su un tipo di dati primitivo (o su qualsiasi tipo di dati). E se il tipo non avesse mai implementato i metodi IEnumerable? Ecco la chiave, puoi sempre avere i "metodi" che formano i pezzi necessari dell '"interfaccia" come parametri passati alla tua funzione. Oppure puoi mettere insieme le funzioni con i dati e fare le cose in modo simile a OO.

Nota che in entrambi i casi non hai meno dati nascosti di quelli che hai in OO. La mia funzione generale che funziona su qualsiasi tipo chiaramente non accede ai dati in quel tipo - ciò accade all'interno delle funzioni passate come parametri alla funzione generale, ma la funzione generale non fa mai capolino all'interno di quelle funzioni per vedere i dati.

Quindi, per quanto riguarda il punto 1, non credo che FP e l'articolo siano davvero in disaccordo. Non penso che la tua caratterizzazione di FP che non nasconda i dati sia corretta. Uno potrebbe attuare il disegno che l'autore ha preferito in FP, certamente.

Per quanto riguarda il punto 4 (2 e 3 non ha senso rispondere dato quello che ho detto per il punto 1) varia. Inoltre varia nelle lingue OO e in molti campi privati ​​sono privati ​​per convenzione piuttosto che applicati dalla lingua.


In altre parole: nella programmazione funzionale, molto di più è "nascosto" per impostazione predefinita, semplicemente perché non esiste nemmeno! Solo le cose che si esplicitamente mettono in campo sono "non nascoste".
lasciato circa il

3

Innanzitutto, grazie per il link a questo fantastico articolo, non lo sapevo fino ad ora, e mi ha dato un grande input su alcune cose di cui stavo discutendo con alcuni altri progettisti di software della community negli ultimi anni. Ecco la mia opinione al riguardo:

Innanzitutto voglio sapere se la mia valutazione è corretta. Il paradigma FP e questo articolo sono filosoficamente in disaccordo?

Il design di FP si concentra molto sul flusso di dati (che non è così male come potrebbe implicare l'articolo). Se questo è un completo "disaccordo" è discutibile.

Supponendo che non siano d'accordo, in che modo FP "compensa" la mancanza di dati nascosti? Forse sacrificano il nascondere i dati ma ottengono X, Y e Z. Mi piacerebbe conoscere il ragionamento per cui X, Y e Z sono considerati più vantaggiosi del nascondere i dati.

IMHO non compensa. Vedi sotto.

Oppure, supponendo che non siano d'accordo, forse FP ritiene che nascondere i dati sia negativo. In tal caso, perché ritiene che nascondere i dati sia negativo?

Non penso che la maggior parte degli utenti o dei progettisti di FP si senta o pensi in questo modo, vedi sotto.

Supponendo che siano d'accordo, mi piacerebbe sapere quale sia l'attuazione del programma quadro per nascondere i dati. È ovvio vederlo in OOP. Puoi avere un campo privato a cui nessuno al di fuori della classe può accedere. Non esiste un'analogia ovvia per me in FP.

Ecco il punto: probabilmente hai visto così tanti sistemi OOP implementati in modo non funzionale che ritieni che OOP sia non funzionale. E questo è un errore, IMHO OOP e FP sono per lo più concetti ortogonali e puoi perfettamente costruire sistemi OO funzionali, che ti danno una risposta ovvia alla tua domanda. L'implementazione classica di "oggetti" in FP viene effettuata utilizzando chiusure e se si desidera che gli oggetti vengano utilizzati in un sistema funzionale, il punto chiave è progettarli immutabili.

Quindi, per creare sistemi più grandi, IMHO è possibile creare moduli, classi e oggetti usando i concetti OO, esattamente come descritto in "Modularizzazione 2" nell'articolo senza lasciare il "percorso FP". Utilizzerai il concetto di modulo del tuo linguaggio FP preferito, renderai immutabili tutti i tuoi oggetti e utilizzerai il "meglio di entrambi i mondi".


3

TL; DR : No

Il paradigma FP e questo articolo sono filosoficamente in disaccordo ?.

No non lo fa. La programmazione funzionale è dichiarativa che è "uno stile di costruzione della struttura e degli elementi dei programmi per computer, che esprime la logica di un calcolo senza descriverne il flusso di controllo". Si tratta meno di seguire il diagramma di flusso e piuttosto di creare le regole che consentono al flusso di emergere da solo.

La programmazione procedurale è molto più vicina alla codifica di un diagramma di flusso che alla programmazione funzionale. Ne consegue che le trasformazioni che si verificano e codifica di tali trasformazioni in procedure eseguite in ordine, esattamente come descrive il flusso in un diagramma di flusso.

Mentre i linguaggi procedurali modellano l'esecuzione del programma come una sequenza di comandi imperativi che possono alterare implicitamente lo stato condiviso, i linguaggi di programmazione funzionale modellano l'esecuzione come valutazione di espressioni complesse che dipendono l'una dall'altra solo in termini di argomenti e valori di ritorno. Per questo motivo, i programmi funzionali possono avere un ordine più libero di esecuzione del codice e le lingue possono offrire uno scarso controllo sull'ordine in cui vengono eseguite varie parti del programma. (Ad esempio, gli argomenti per un'invocazione di procedura in Scheme vengono eseguiti in un ordine arbitrario.)

Nascondere i dati

  • La programmazione funzionale ha i suoi metodi per nascondere i dati, ad esempio pensare alle chiusure . Ciò significa che i dati si nascondono per incapsulamento in una chiusura. È difficile che i campi siano altri dati privati ​​che sono stati chiusi poiché solo la chiusura ha un riferimento ai dati e non è possibile fare riferimento ad essi esterni alla chiusura.
  • Uno dei motivi per nascondere i dati è stabilizzare l'interfaccia di programmazione nascondendo i dati mutanti. La programmazione funzionale non ha dati mutanti, quindi non ha bisogno di nascondere tanto i dati.

3
"La programmazione funzionale non ha dati mutanti, quindi non ha bisogno di tanto nascondersi i dati." - questa è un'affermazione molto fuorviante. Hai detto tu stesso (e sono d'accordo) che uno dei motivi dell'incapsulamento del comportamento è avere il controllo sulla mutazione dei dati. Ma concludere che la mancanza di mutazione rende quasi inutile l'incapsulamento è un enorme sforzo. Gli ADT e l'astrazione dei dati in generale sono pervasivi nella letteratura e nei sistemi FP.
Thiago Silva,

Non l'ho mai detto "rende quasi inutile l'incapsulamento". Questi sono i tuoi pensieri e solo i tuoi. Ho detto che non è necessario fare tutti i dati nascosti a causa della mancanza di variabili mutanti. Questo non rende inutili l'incapsulamento o il nascondimento dei dati, ne riduce solo l'uso perché quei casi non esistono. Tutti gli altri casi in cui nascondere e incapsulare i dati sono utili sono ancora validi.
dietbuddha,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.