Modelli mentali o metafore del mondo reale per la programmazione funzionale


16

Qualcuno ha un buon modello mentale o metafora per la programmazione funzionale che fa riferimento a qualcosa nel mondo reale?

La programmazione orientata agli oggetti ha un senso intuitivo per me. Ci sono cose che hanno proprietà e talvolta possono anche fare cose o eseguire calcoli sulle loro proprietà (metodi). (Es: auto, forma, gatto).

Non sopporto alcuna programmazione funzionale e non mi interessa un dibattito sulle virtù dei due. Ho solo bisogno di una metafora o di un modello mentale con cui lavorare come ho fatto con la programmazione orientata agli oggetti.

Quali sono alcuni buoni modelli mentali o metafore del mondo reale per la programmazione in un paradigma funzionale? C'è qualcosa nelle funzioni composte da funzioni che elaborano funzioni che lasciano uno senza un posto fermo dove stare e cogitare.


A quale significato concreto di "programmazione funzionale" ti riferisci, "nessun effetto collaterale / dichiarativo" o "funzioni / composizione di funzioni di prima classe"? O entrambi?
acelent,

Domanda interessante. Con la mia attuale piccola conoscenza e la scarsa esperienza di programmazione in "programmazione funzionale", non posso rispondere in modo significativo a questa domanda. Se dovessi indovinare un'ipotesi, direi entrambe le cose.
Guido Anselmi,

13
Il modello "mondo reale" viene spesso indicato come motivazione per la programmazione orientata agli oggetti. Penso che sia un approccio che alla fine dovresti superare, perché gli oggetti in OOP non devono sempre corrispondere agli oggetti del mondo reale e, anche quando lo fanno, la corrispondenza è spesso incompleta; ad esempio, le relazioni "is-a" non sono sempre le stesse. D'altra parte, una volta che dici di volere un modello o una metafora per un linguaggio di programmazione basato su qualcosa nel "mondo reale", penso che ti sia essenzialmente limitato a questa forma limitata di OOP.
David K,

Un modello mentale davvero valido, se si ha esperienza nell'uso di sistemi unix-like (o PowerShell nella moderna Windows) è la shell one-liners. Non sono esattamente gli stessi dal momento che shell pipe è tecnicamente una programmazione basata sul flusso anziché funzionale ma hanno la stessa "sensazione" di un programmatore.
Slebetman,

1
Inoltre, mentre apprendi i linguaggi funzionali, nella programmazione funzionale orientata agli oggetti viene trattata come uno strumento, come ad esempio le espressioni regolari. Qualcosa che puoi usare se vuoi ma non devi. In alcune lingue come lisp e tcl e avanti OO non è una funzionalità integrata nella lingua ma una libreria che puoi usare (o puoi anche scrivere la tua OO se ti senti coraggioso). Quindi i problemi che hanno naturalmente una soluzione OO possono essere risolti usando OO nella maggior parte dei linguaggi funzionali. Le persone semplicemente non trattano l'OO come una religione.
Slebetman,

Risposte:


32

La programmazione funzionale consiste nell'incollare insieme funzioni più piccole per ottenere i risultati. Un modello mentale decente (almeno per me) è una catena di montaggio. Ogni funzione che viene composta costituisce un ulteriore passo nel processo di assemblaggio. Considera questa funzione qui:

smallest  = head . sort

In Haskell, questa funzione restituirà l'elemento più piccolo in un elenco. La catena di montaggio ordina prima l'input, quindi restituisce il primo elemento (supponendo che sia ordinato dal minimo al massimo). Se volessimo ottenere solo il valore pari più piccolo, possiamo modificare la catena di montaggio in modo che assomigli a quanto segue:

smallestEven = head . sort . filter even

È solo un altro passo sul nastro trasportatore.

In poche parole, le funzioni descrivono semplicemente i passaggi intrapresi per convertire l'input non elaborato (le parti) nel bene elaborato (output).


2
In un linguaggio funzionale puro senza variabili globali, quindi una linea di assemblaggio non può influire sull'altra (a meno che non stia alimentando l'altro input di linea.) Teoricamente qualsiasi linea di assemblaggio che non dipende l'una dall'altra può essere eseguita in parallelo, ma non lo sono certo se qualche compilatore lo fa.
bstamour,

3
@GuidoAnselmi Un modo per pensarci è che la catena di montaggio nella programmazione funzionale costruisce nuovi output lasciando intatti gli input, mentre la catena di montaggio in OOP tradizionale trasforma l'input.
Doval,

2
Questa metafora ha senso solo nel significato di "funzioni / composizione di funzioni di prima classe" della "programmazione delle funzioni", non nel "nessun effetto collaterale / dichiarativo". Inoltre, la programmazione orientata agli oggetti non ha necessariamente effetti collaterali, quindi è possibile implementare una catena di montaggio distruttiva o costruttiva con OOP o questo significato di FP. OOP riguarda più l'incapsulamento, il passaggio di messaggi e il polimorfismo che non gli effetti collaterali, dipende da come modellare le cose. Ad esempio, hai bisogno dell'identità referenziale dall'inizio alla fine?
acelent,

3
@bstamour: Per essere precisi, si dovrebbe scrivere che (f . g) (x)significa f(g(x))o f . gsignifica \x -> f (g (x)).
Giorgio

3
@MarjanVenema Le cose scorrono in questo esempio solo perché è così che .viene definito; non è così che Haskell funziona in generale . Si potrebbe anche definire l'operatore forward pipe di F # ( |>) in Haskell e scrivere smallest x = (sort x) |> heade i dati scorreranno correttamente. Ho pensato di segnalarlo.
Doval,

18

Qualcuno ha un buon modello mentale per la programmazione funzionale?

Matematica. La programmazione funzionale è ispirata e modellata sulla matematica. Le funzioni matematiche non hanno stato, non hanno effetti collaterali, ecc., E così è con FP. Se pensi a FP in termini di funzioni matematiche piuttosto che usare un approccio "come posso fare a questo" approccio, sarai in buona forma. Se provi a portare la sensibilità OO a FP, però, nuoterai contro corrente.


1
Grazie. Tuttavia, ho bisogno di una metafora dal mondo reale (ad es. Non da computer o matematica).
Guido Anselmi,

3
@GuidoAnselmi: una funzione è una scatola nera. Metti qualcosa da una parte e poi dall'altra parte esce qualcosa di nuovo. Se inserisci le stesse cose, ottieni sempre le stesse cose. Puoi prendere molte di queste piccole scatole e combinarle in diversi ordini per costruire una fabbrica che potrebbe contenere metalli grezzi e produrre un'auto. All'interno il processo è suddiviso in molti pezzi, ma dall'esterno è solo un'altra funzione.
Daenyth,

16

Che ne dici di un libro a fogli mobili ?

In un libro a fogli mobili ogni pagina rappresenta il mondo come esiste in un momento nel tempo. Nel nostro programma il mondo è rappresentato come una struttura di dati composti (ad esempio abbiamo una banana che è nella mano di un gorilla che si trova in un albero che si trova in una giungla). Ogni pagina successiva fa avanzare la storia modificando leggermente la rappresentazione precedente. In FP, le strutture di dati persistenti sono state progettate per riutilizzare in modo efficiente le strutture precedenti in modo che una modifica fornisca solo un delta e non una rappresentazione completamente nuova.

Ciò che potrebbe non essere ovvio è che una pagina del nostro libro a fogli mobili rappresenterebbe anche intangibili. Ad esempio, se il gorilla lascia cadere la banana, potremmo iniziare ad applicare gli effetti della gravità sul suo decente e accelerazione verso il pavimento della giungla. Per ovviare a questo, aggiungeremmo attributi come velocità e traiettoria alla nostra banana.

Nel nostro programma ci sarebbe una funzione che accetta una pagina di libro a fogli mobili (aka lo stato del mondo) come argomento e produce una nuova pagina . In questo modo la nostra storia viene raccontata senza mai cambiare lo stato degli oggetti esistenti. Sostituiamo semplicemente ogni pagina con una nuova usando quello che è effettivamente un calcolo.


3

Rapporti.

Amico: date due persone, una relazione di amicizia segue queste leggi generali

  1. Abbi buona volontà l'uno verso l'altro
  2. Si pensano che siano loro amici (quindi le leggi devono essere rispettate da entrambi i membri in questa relazione)
  3. Gode ​​di trascorrere del tempo l'uno con l'altro

Monoid: dati più elementi e una funzione che accetta 2 degli articoli e restituisce 1, una relazione monoidale segue queste leggi generali

  1. C'è uno di quegli elementi (solo uno, chiamato identità) che è passato alla funzione con qualsiasi altro elemento assicurerà che la funzione restituisca sempre l' altro elemento (0 + 1 = 1, quindi 0 è l'identità quando gli elementi sono numeri e il la funzione è aggiunta)
  2. La funzione non può operare su o restituire elementi non nel set con cui ha una relazione monoidale
  3. La funzione è associativa e può essere usata con gli oggetti in un modo un po 'indipendente dall'ordine, questo significa a * (b * c) = (a * b) * c che dice che puoi moltiplicare a per il risultato di b * c o c dal risultato di a * b e il risultato sarà lo stesso di qualunque cosa tu faccia per prima.

La programmazione funzionale si basa su generalizzazioni, amico è una relazione molto generale che può essere vista in numerosi scenari, ma in tutti i vari formati generalmente segue le leggi sopra.

Riconoscendo le leggi che regolano le relazioni tra le cose, puoi creare implementazioni generali che funzionano su qualsiasi formato di cose che ha quel tipo di relazione. Nella programmazione funzionale si tenta di identificare le relazioni tra le cose in modo che possano essere classificate e trattate in generale.

Vuoi una metafora dal mondo reale? Guarda come sono correlate le cose e cerca di identificare le leggi generali (come applicabile a più scenari in cui le cose diverse dalle leggi possono variare). Esiste una relazione tra un impiegato del registro e un acquirente in un negozio, ha alcune leggi generali, il software è stato sviluppato per facilitare gli obiettivi delle persone in quella relazione generale nel modo dei sistemi POS. Allo stesso modo quando inizi a vedere queste leggi generali che dettano come le cose sono correlate, puoi iniziare a fare affidamento sulle leggi di quelle relazioni nello scrivere il tuo software piuttosto che sui dettagli specifici di un'istanza di una relazione.


2

Tutto è un valore e si applicano funzioni ai valori (che possono essere funzioni) per produrre nuovi valori, preferibilmente senza produrre effetti collaterali.


Grazie. Sfortunatamente, sembra più una descrizione che un modello mentale o una metafora. Ho bisogno di una metafora dal mondo reale (non dai computer).
Guido Anselmi,

1
Come sottolinea Caleb , la programmazione funzionale modella la matematica, non il mondo reale. Può modellare il mondo reale attraverso la lente della matematica, ma probabilmente non troverai una metafora che ti soddisfi, perché FP evita il concetto di cose con un'identità persistente e uno stato mutevole. Se vuoi, posso sottolineare come OOP costruisce la mappa su FP, ma questa non sarà ancora la risposta che desideri.
Doval,

Ma la matematica si basa sul mondo reale. 1 sole, 9 pianeti. 2 mele più 2 mele producono quattro mele.
Guido Anselmi,

E nella programmazione funzionale puoi anche avere un tipo per soli, pianeti e mele, quindi creare un valore di tipo sole, 9 valori di tipo pianeta e definire l'aggiunta per il tipo di mela.
Doval,

3
@GuidoAnselmi ce l'hai completamente all'indietro, le persone analizzano il mondo reale con la matematica, non ha basi sul mondo reale. La matematica è usata per analizzare e definire relazioni tra ogni sorta di cose, reali e non. 9 pianeti stai applicando un costrutto matematico (l'insieme dei numeri naturali) a un costrutto del mondo reale (pianeti) con una funzione di analisi matematica (conteggio). Il mondo reale non ha 9 pianeti, ha quello che ha, la matematica parla semplicemente di rappresentazioni simboliche di cose in cui i simboli hanno relazioni reciproche.
Jimmy Hoffa,

1

La cosa fondamentale da capire sulla programmazione funzionale è che tutto è un valore, anche il codice stesso è "valori".

Il miglior esempio di un semplice ambiente di programmazione funzionale è quello dello strumento di business preferito di tutti: il foglio di calcolo. Ogni cella nel foglio di calcolo è costituita da dati o dal risultato di una funzione. Inoltre, questa funzione non può essere disattivata e modificare un'altra cella.

Quando si passa a una lingua funzionale, anziché a una griglia cartesiana di A1e B42, le funzioni hanno nomi. Questo è tutto.

Ci sono altri aspetti che si possono aggiungere oltre a questo ... ma questa è la programmazione funzionale al suo interno. Non è necessario preoccuparsi della struttura delle liste o del raggruppamento delle cose. La programmazione funzionale riguarda il passaggio di un valore in una funzione e il recupero di un valore senza avere confusione in altre parti della memoria.

Questo è tutto. La programmazione funzionale è un foglio di calcolo con nomi anziché una griglia.


0

Puoi pensare alla programmazione funzionale come ai comportamenti . Un programma è una descrizione del comportamento che si desidera che il computer esegua. Le funzioni sono l'unità base del comportamento e la composizione delle funzioni è un modo per costruire comportamenti più grandi da quelli più piccoli.

In OOP, un oggetto codice deve essere lo stato di un oggetto nel dominio problematico; cambia nel tempo per riflettere i cambiamenti nell'oggetto dominio. In FP, un valore rappresenta lo stato di un oggetto dominio; non cambia mai, semplicemente crei valori diversi per rappresentare stati diversi.

Trovo il modello funzionale un po 'più onesto su ciò che i computer stanno effettivamente facendo, rappresentando. Dopotutto, non posso solo evocare un nulla new Tesla(). :)


-5

Le frasi sono più funzionali che orientate agli oggetti, supponendo che le abbassi più o meno come le seguenti ...

The brown cow is in the meadow across the deep river.

Quindi dobbiamo trovare le frasi di testa e poi il resto:

The cow (brown)
the meadow (across)
the river (deep)

In un colpo solo:

sentence: The cow ((the meadow (the river (deep)) (across)) brown)

Albero di legno:

|                     sentence
|                      /         
|                  The cow
|                 /       \
|            the meadow   brown
|            /         \
|      the river      across
|              \
|              deep

La parsimonia infetta il pensiero funzionale;

Tanto di cappello a Gottlieb Frege 1890s, Alan Turing (entschiedungsprobleme) 1930s, Noam Chomsky (1960s).


4
Questa è una spiegazione confusa, e ho familiarità con FP per cominciare.
Daenyth,

Sembra imitare la forma di Lisp senza capirne il significato
Izkata,
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.