Convenzione di denominazione per le funzioni che hanno effetti collaterali? [chiuso]

8

Ho sentito qualcuno dire che la loro lingua ha una convenzione in cui i nomi delle funzioni che mutano stato devono terminare con un punto esclamativo. Sto cercando di scrivere un codice più funzionale e mi piace l'idea di contrassegnare in qualche modo le funzioni in base al loro stato dell'effetto collaterale, ovvero nessuno, effetti collaterali interni, effetti collaterali esterni (sono ignorante della terminologia fp corretta ma tu hai l'idea I spero).

Ovviamente è facile per me inventare il mio schema di denominazione, ma mi chiedevo se tali schemi / convenzioni esistessero già prima di andare a casa mia.

modifica: Grazie per tutte le risposte, era esattamente quello che stavo cercando e le ho trovate davvero utili. Probabilmente avrei dovuto menzionare che sto rifattorizzando alcuni vecchi javascript quindi, mentre i linguaggi tipizzati staticamente potrebbero essere in grado di forzare una differenza tra codice con e senza effetti collaterali, dovrò fare affidamento su una convenzione di denominazione autoimposta.

edit2: Per quanto riguarda le mod che chiudono questo fatto principalmente come opinioni, non sono d'accordo. Stavo chiedendo quali, se del caso, le convenzioni erano di uso comune - questo è per definizione di chiunque una questione di fatto non opinione!

    
posta technicalbloke 04.10.2016 - 17:55
fonte

3 risposte

8

Segui separazione query-comando . Le funzioni che restituiscono valori non hanno effetti collaterali, le funzioni con effetti collaterali non restituiscono valori.

Aiuta anche a nominare funzioni che restituiscono valori dopo la cosa che restituiscono, cioè un nome o un aggettivo. Mentre le funzioni che hanno effetti collaterali dovrebbero essere nominate dopo l'effetto che eseguono, cioè un verbo.

Quindi, ad esempio, myArray.sort() ha un effetto collaterale, ordina l'array. Pertanto non restituisce nulla e prende il nome da un verbo. Nel frattempo, myArray.sorted() restituisce una copia ordinata di myArray . Pertanto non ha effetti collaterali e prende il nome dalla cosa che restituisce.

FYI, l'idea di cui sopra (nomi / aggettivi per le funzioni pure e i verbi per le funzioni che producono effetti collaterali) è uno standard in Swift 3.

Name functions and methods according to their side-effects

  • Those without side-effects should read as noun phrases.
  • Those with side-effects should read as imperative verb phrases.

( link )

    
risposta data 04.10.2016 - 19:28
fonte
4

Il problema fondamentale è che gli effetti collaterali non vengono catturati nel sistema di tipi. L'utilizzo di una convenzione di denominazione delle funzioni è un sostituto insoddisfacente per la verifica statica. Ci sono alcuni modi per aggirare questo.

Haskell usa le monadi per catturare gli effetti collaterali in un contesto. L'operazione monadica bind compone funzioni impure tanto quanto il normale operatore di composizione di funzioni compone funzioni pure. Le leggi monadi garantiscono che questo operatore agisca in modo analogo alla composizione regolare.

Un altro percorso è separare puro da impuro separando espressioni dai comandi interamente . Queste sono due categorie sintattiche completamente diverse che non possono essere mescolate. Le espressioni hanno tipi che ci permettono di comporre termini. Un'espressione, per definizione, non può dipendere da alcun assegnabile (non ha accesso allo negozio ). I comandi non hanno un tipo nel senso tradizionale e non possono restituire un valore. Possono solo interagire con il programma mutando il negozio.

Si noti che convenzionalmente le lingue "funzionali" e sicure dal tipo potrebbero non seguire nessuno dei due paradigmi. Ad esempio, OCaml e SML non differenziano correttamente le pure dalle funzioni impure.

Nessuna di queste soluzioni è perfetta, e questa è ancora un'area di ricerca attiva.

    
risposta data 04.10.2016 - 18:27
fonte
3

Richiamare metodi o funzioni sembra un'idea fantastica perché potrebbe aiutare a eliminare i tempi in cui il codice introduce un livello di non sicurezza. Joel Spolsky approfondisce questa idea un po 'nel suo articolo Making Wrong Code Look Wrong ( link ) dove consiglia di utilizzare una versione meno conosciuta della notazione ungherese per rendere certe idee più trasparenti all'interno del sistema.

La lingua a cui ti stai riferendo è quasi certamente Scheme (vedi link per un semplice esempio). Non sono a conoscenza di nulla di globale.

Java precede i metodi di proprietà con get e set per adempiere parzialmente a questo scopo, ma non sono realmente a conoscenza di alcuna convenzione comune del tipo che si cita al di fuori del mondo Lisp che non lo è (come sottolineato da @gardenhead) incorporato nel sistema di tipi.

Penso che, nel complesso, tu sia piuttosto sicuro di creare una linea guida di stile per il tuo team, specialmente se ti occupi di qualcosa con molta concorrenza in cui gli effetti collaterali sono ancora più pericolosi del solito.

Per quel che vale, posso pensare ad un paio di modi per implementarlo in linguaggi ALGOL-esque. Uno semplice potrebbe essere un prefisso, come quasi suggerito da Spolsky - diciamo s_ per le operazioni con stato e l_ per le operazioni senza stato.

Un'idea più moderna potrebbe essere quella di mettere le parole come prefissi o suffissi. Forse calculate è una funzione pura ma mutateCalculation è impura.

Infine, c'è un grado in cui gran parte di ciò dovrebbe essere gestito dalla separazione delle preoccupazioni: solo il livello che aggiorna il database dovrebbe essere in grado di aggiornare il database, ad esempio. In tal caso, è abbastanza ovvio che devi preoccuparti degli effetti collaterali nei livelli stateful.

    
risposta data 04.10.2016 - 20:58
fonte