Esiste un insieme comune di best practice per il passaggio di funzioni anonime come argomenti?

1

Questa è una domanda generica sull'uso di funzioni anonime come argomenti ad altre funzioni. Do un esempio in Python, ma la domanda non riguarda Python (e sono particolarmente interessato a sapere se le risposte potrebbero essere diverse per i linguaggi funzionali rispetto ad altri paradigmi).

In Python è comune passare una funzione anonima come argomento ad un'altra funzione, ad esempio:

sorted(my_data_structure, key=lambda x: x[0].foo)

dove lambda x: x[0].foo è una funzione anonima per restituire l'attributo foo dell'elemento 0 di ogni cosa in my_data_structure (supponendo che qualsiasi cosa viva in my_data_structure avrà un elemento 0th e che l'elemento 0th sarà avere un attributo foo ).

A mio parere, in tutti i casi tranne i più semplici, questo presenta un problema per l'incapsulamento e l'estensibilità: cosa succede se my_data_structure cambia? Cosa succede se l'attributo da ordinare diventa bar in un successivo refactoring del codice? Ora devi scendere nell'effettivo lambda per gestirlo.

In alternativa, questo potrebbe essere stato scritto come:

def my_helper(some_data_thing):
    """My intentions are ____ !
    """
    return some_data_thing[0].foo

#Elsewhere in the code:
sorted(my_data_structure, key=my_helper)

Mentre questo aggiunge 4 linee di codice, è più leggibile. Non devi analizzare ciò che lambda sta cercando di fare nel momento in cui leggi la chiamata a sorted . Fornisce l'opportunità per l'annotazione del tipo, la documentazione o anche il test dell'unità per la funzione di supporto.

Se qualcosa cambia, ma vuoi comunque che il codice locale intorno all'uso di sorted rimanga lo stesso, questo incapsula piacevolmente per te nella funzione di aiuto. E se più di un posto è necessario per ordinare, o raggruppare, o qualsiasi altra cosa, con la stessa chiave, ottieni il riutilizzo del codice meglio di quello che riproducendo il lambda è molte posizioni.

Tuttavia, altri potrebbero anche dire che ti stai piegando all'indietro per dare un nome, my_helper , ad una piccola funzione che è in realtà più chiara per vederlo direttamente nel codice.

Posso essere d'accordo con questo, in particolare quando il lambda coinvolto è molto piccolo, ma cosa succede se deve essere un multi-line lambda che si imbatte in molti problemi di indentazione, o coinvolge un po ' comprensione dell'elenco offuscata o qualche altro dispositivo?

La mia domanda è: quali approcci esistono per determinare dove tracciare la linea tra un'utile funzione anonima in linea che è "autosufficiente" abbastanza da rendere più efficace la scrittura diretta rispetto a una funzione in linea che è troppo complesso e dovrebbe essere avvolto in una funzione di supporto. Ci sono altre considerazioni che non sto prendendo in considerazione?

Ad esempio: questo post su questo problema in JavaScript afferma e afferma molte delle preoccupazioni che ho elencati. È codificato per la programmazione in generale? È un linguaggio o un paradigma specifico? E che dire dell'altra faccia del dibattito?

    
posta ely 15.12.2014 - 16:06
fonte

1 risposta

2

Disegna la linea in base alla lunghezza e alla ripetizione. Una lambda va bene se è corta e non si ripete. Una volta entrati in più righe o ripetendole più volte, dovresti davvero dargli un nome. Se la struttura dei dati cambia, non è un grosso problema cambiare uno o due brevi lambda, specialmente in un linguaggio strongmente tipizzato in modo statico. Per qualche ragione, però, i lambda danno alle persone un punto cieco alla ripetizione.

JavaScript è davvero l'unica lingua che ho visto dove le funzioni anonime multi-linea sono comunemente accettate. Non sono sicuro di cosa sia il linguaggio che lo rende così. Potrebbe essere più una cosa culturale. Ciò non lo rende una pratica migliore , tuttavia, solo una comune. Inoltre, si applicano le stesse regole sulla ripetizione. Inoltre, poiché la ripetizione di funzioni più lunghe è peggiore.

    
risposta data 15.12.2014 - 18:04
fonte

Leggi altre domande sui tag