Questo esempio di programmazione funzionale e cosa significa

4

Ho letto Out of the Tar Pit di Ben Moseley e Peter Marks e nella sezione 5.2.3 discutono lo stato in lingue funzionali rispetto ai linguaggi procedurali. L'esempio procedurale è il seguente:

procedure int getNextCounter()
  // 'counter' is declared and initialized elsewhere in the code
  counter := counter + 1
  return counter

Posso vedere che c'è uno stato interno, quindi va bene. L'esempio funzionale è tuttavia il seguente:

function (int,int) getNextCounter(int oldCounter)
  let int result = oldCounter + 1
  let int newCounter = oldCounter + 1
  return (newCounter, result)

Posso capire che si evita lo stato interno passando in oldCounter , ma perché i due output uguali?

Questo è solo per passare il state e il result ed essere entrambi uguali è semplicemente dovuto ad un esempio troppo semplicistico?

Non viene restituito più valori considerati non buoni per un'idea?

Non sono abbastanza esperto nella programmazione funzionale?

    
posta Karl Uibo 04.04.2018 - 14:25
fonte

2 risposte

8

L'esempio di codice fornito da quell'autore ha lo scopo di illustrare che, invece di mantenere una variabile contatore globale al di fuori della funzione, è sufficiente passare una copia locale del contatore dall'invocazione della funzione alla funzione invocazione come parametro aggiuntivo.

Inoltre tenta di illustrare (forse male) che il valore del risultato della funzione opera indipendentemente dalla variabile contatore.

Ovviamente, non hai davvero bisogno di tutti questi passaggi extra:

function int getNextCounter(int oldCounter)
  return oldCounter + 1

Le istruzioni let sono probabilmente lì per illustrare la creazione di un nuovo oggetto contatore, piuttosto che la modifica di uno esistente. Nella maggior parte dei linguaggi di programmazione questo è semplicemente ridondante, poiché gli argomenti di funzione passati per valore (tipici di primitive come int ) sono già copiati localmente comunque.

Quindi sì, l'esempio di codice fornito nel documento è un po 'troppo semplicistico per catturare adeguatamente tutte le funzionalità del codice che l'autore sta tentando di descrivere.

Un esempio migliore avrebbe illustrato più chiaramente la distinzione tra il valore del risultato e l'oggetto contatore:

procedure int getNextCounterDoubled()
  // 'counter' is declared and initialized elsewhere in the code
  counter := counter + 1
  let int result = counter * 2
  return result

function (int, int) getNextCounterDoubled(int oldCounter)
  let int newCounter = oldCounter + 1
  let int result = newCounter * 2
  return (newCounter, result)
    
risposta data 04.04.2018 - 17:27
fonte
0

Direi che la tua affermazione sul fatto che entrambi siano uguali a causa di un esempio semplicistico è vera. La sequenza della funzione è spesso diversa dal suo stato interno.

Un altro motivo potrebbe essere che potrebbe esserci una funzione di ordine superiore, che accetta un valore "seme" e una funzione della stessa firma di getNextCounter funzionale e quindi genera una sequenza di secondi elementi nella tupla.

    
risposta data 04.04.2018 - 15:02
fonte

Leggi altre domande sui tag