* Qualsiasi * attività del programma può essere espressa senza stato?


13

Questa è una domanda teorica, ma dopo molti anni di programmazione in quella che ora realizzo è una tecnica imperativa "normale", usando principalmente C ++, ho scoperto questo altro mondo di programmazione funzionale, sul quale mi sono imbattuto accidentalmente mentre apprendevo casualmente JavaScript.

Questo mi ha portato a chiedermi se potresti tecnicamente sostituire qualsiasi programma completo orientato allo stato con un'implementazione diversa che sia puramente funzionale e senza stato?

È un'idea intrigante e devo ammettere che c'è una chiarezza ed eleganza nella programmazione funzionale che mi ha davvero fatto impazzire.


1
Una risposta StackOverflow rilevanti: stackoverflow.com/questions/3722084/...
jfriend00

La presenza o meno di uno stato che persiste da un momento all'altro non dipende da quale paradigma di programmazione usi, ma da quale problema o compito stai codificando. Se si sta contando il numero di volte in cui si fa clic su un pulsante, è chiaro che esiste uno stato per registrare quel contatore e non importa quale sia la tecnica di codifica utilizzata, sarà necessario che lo stato tenga traccia del conteggio durante il processo. Quindi, quel particolare compito non può essere completato senza stato lungo il percorso, indipendentemente da come lo codifichi.
jfriend00

6
Se vuoi discutere di stato; chiaramente è richiesto lo stato, se non altro per il programma stesso. Sembra però che tu stia pensando allo stato mutevole vs. immutabile - potresti voler indicare quale intendi nella domanda.
Billy ONeal,

1
È come chiedere se tutti i programmi possono essere convertiti in vere macchine Turing. Tecnicamente sì, anche i programmi che salvano e caricano da un database, tuttavia, diventa molto più difficile simulare questo comportamento in una macchina Turing. Allo stesso modo, potresti avere un programma il cui lato controller nell'architettura MVC è stato rimosso e fai tutte le chiamate, anche se ancora una volta diventa molto più difficile gestire le dimensioni (essenzialmente diventi il ​​controller per rendere il programma senza stato).
Neil,

Risposte:


17

Risposta breve: si. Secondo Wikipedia, l'equivalenza del calcolo lambda con le macchine di Turing come modello universale di calcolo fu mostrata nel 1937 da Alan Turing. Il modello computazionale di una macchina di Turing è ciò che in genere hai in mente quando parli di programmazione imperativa o con stato, e il calcolo lambda è una formalizzazione matematica della "pura programmazione funzionale".

Si ipotizza che ogni modello di calcolo efficace sia in grado di eseguire gli stessi calcoli di una macchina di Turing e viceversa. Questa si chiama tesi di Church-Turing . Questa congettura, tuttavia, non può essere dimostrata, a causa del termine più o meno intuitivo "modello di calcolo efficace" (forse qualcuno inventerà un nuovo modello in futuro?)


2
Il tuo stesso argomento può essere ripristinato dicendo che essendo il calcolo della lamba equivalente alle macchine da turismo, ogni calcolo deve avere uno stato (più o meno nascosto). Che sia rappresentato come esterno al codice (mediante variabili) o interno al flusso (mediante chiamata di funzione basata su stack) lo è sempre "stato".
Emilio Garavaglia,

3
Il calcolo lambda ha stato; il suo vincolo è che lo stato è immutabile. Lo stato immutabile è ancora stato. I parametri delle funzioni, inclusi i lambda, sono ancora stati; presumibilmente si desidera che una funzione abbia un comportamento diverso dati parametri diversi.
Billy ONeal,

@emilio Affermare che esiste una soluzione basata sullo stato equivalente a un problema (come descritto) non è la prova che non esiste una versione senza stato di tale soluzione.
Billy ONeal,

2
@EmilioGaravaglia ti riferisci quindi allo stato di un interprete lambda-calcolo. Quando si ragiona nel calcolo lambda, non è necessario ragionare sullo stato. Anche l'aspetto di "mutabilità" è diverso.
Wirrbel,

1
@EmilioGaravglia: lo stato nella programmazione imperativa è la configurazione della memoria alla volta, qui lo spazio dei parametri è dato da tutti i possibili valori di memoria e lo stato è una configurazione alla volta (banda della macchina turing). Quando si scrive un programma nel calcolo lambda, non esiste un'entità diretta come un campo di memoria. L'esecuzione del programma è l'applicazione delle trasformate lambda. I passaggi intermedi potrebbero assomigliare a "stato", ma sono solo espressioni equivalenti dello stesso valore. Nulla cambia durante la valutazione, le espressioni vengono semplicemente riscritte ed elaborate in una forma "più semplice".
Wirrbel,

14

In qualunque sistema dinamico, lo "stato" è ciò che rende il tuo presente influenzato dal tuo passato o futuro (la freccia del tempo non è un problema matematico, solo un vincolo fisico).

Che tu abbia qualcosa da "ricordare" o che dipenda da quello che hai fatto, hai uno stato.

Un sistema senza stato non è "dinamico": è solo una funzione combinatoria. Potrebbe non avere uno stato, ma - per produrre risultati diversi - è necessario che sia fornito uno stato.

Ora, a seconda del modello computazionale a cui si fa riferimento, uno stato può essere rappresentato in modo esplicito (sotto forma di variabile) o implicitamente (sotto forma di "indirizzi di ritorno").

quando lo fai fna(fnb(x))stai dando uno stato a fnb che a sua volta produrrà uno stato per fna. Ciò è dovuto al fatto che xesiste prima che venga chiamato fnb (quindi, deriva dal suo "passato").

Non è una questione di "stato esistente" o "stato non esiste". È una questione di "I care" o "I don't".


0

Stato significa la capacità di rispondere a uno stimolo presente in un modo che dipende da stimoli passati, non solo basato sullo stimolo presente.

I programmi puramente funzionali sono solo funzioni. Quindi, per applicazioni pratiche, il programma puramente funzionale inserisce una coppia (old_state * present_stimulus) e genera una coppia (new_state * present_response). È necessario un "looper" esterno, con stato, per attendere lo stimolo successivo e propagare lo stato.

Un programma puramente funzionale non ha intrinsecamente stato e non può essere utilizzato direttamente per applicazioni pratiche.

Pertanto, nessun programma orientato allo stato può essere sostituito con una diversa implementazione puramente funzionale e senza stato.


0

È possibile evitare lo stato mutabile esplicito purché non si debba interagire con il mondo esterno.

In JavaScript per far sì che il tuo programma abbia effettivamente un effetto oltre a prendere i cicli del processore, devi modificare l'oggetto Dom o Window e queste API sono stateful. Ma suppongo che tu possa creare un wrapper che ha passato gli oggetti Dom e Window come parametri al codice JavaScript e quindi ha ricevuto un nuovo Dom / Window come output. Ciò isolerebbe il codice JavaScript dallo stato mutabile.

Ovviamente continui a fare affidamento sullo stato, poiché la finestra del browser e DOM sono di natura stateful. Qualsiasi applicazione interattiva è intrinsecamente con stato, ma è comunque possibile strutturare il codice in modo tale da ridurre al minimo lo stato esplicito.

Una domanda diversa è se è una buona idea. Anche Haskell, che è un linguaggio funzionale puro di progettazione, include la monade "stato", che consente di simulare lo stato mutabile. Ciò dimostra che lo stato mutabile esplicito a volte è davvero un modello desiderabile.


0

Pensa a come implementeresti una "macchina a stati" in un linguaggio di programmazione senza stato.

Probabilmente potresti effettivamente farlo, ma finiresti per usare i nomi delle funzioni come memoria. Finendo con gobblyday gook come:

if (sm.atBegining()) sm.start() else if (sm.done()) sm.stop() ) else sm.progress()
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.