Qual è la differenza tra parametri espliciti e chiusure

5

In F #, una funzione ricorsiva di List.filter può essere implementata come:

let filter f =
    let rec filterImpl f acc = function
        | [] -> List.rev acc
        | h :: t -> filterImpl f (if f h then h :: acc else acc) t
    filterImpl f []

Ma può anche essere implementato da una chiusura (cioè senza passare f esplicitamente in filterImpl )

let filter f =
    let rec filterImpl acc = function
        | [] -> List.rev acc
        | h :: t -> filterImpl (if f h then h :: acc else acc) t
    filterImpl []

Qual è la differenza e quale è preferito in F # o in generale nella programmazione funzionale?

    
posta rexcfnghk 05.04.2016 - 16:33
fonte

2 risposte

3

Dal punto di vista del compilatore, c'è pochissima differenza tra una variabile chiusa e un argomento di funzione. Vengono semplicemente assegnati alla tabella dei simboli della funzione in momenti diversi.

In generale preferiresti la versione di chiusura, perché è più semplice, ma se fosse una funzione più lunga, o condivisa da altre funzioni, potresti voler estrarla e accettare solo il parametro extra.

    
risposta data 05.04.2016 - 20:36
fonte
2

Afaic, almeno in C #, almeno a volte dietro le quinte viene generata una classe per memorizzare le variabili catturate nei suoi campi. Si tratta di un overhead significativo rispetto all'assegnazione dello stack per passare direttamente il parametro.

A partire da C #, Raymond Chen ha un'ottima spiegazione delle chiusure :

When faced with this “hard” type of anonymous method, wherein variables are shared with the lexically-enclosing method, the compiler generates a helper class

    
risposta data 06.04.2016 - 06:49
fonte

Leggi altre domande sui tag