2014-07-24 13 views
5

In Core List.find viene definito mediante una funzione ausiliaria, come segue:In OCaml, perché c'è una funzione ausiliaria in Core's List.find?

let find l ~f = 
    let rec find_aux = function 
    | []  -> None 
    | hd :: tl -> if f hd then Some hd else find_aux tl 
    in 
    find_aux l 

ma può essere stabilita direttamente. Per esempio:

let rec find l ~f = 
    match l with 
    | []  -> None 
    | hd :: tl -> if f hd then Some hd else find tl f 

C'è qualche vantaggio nell'usare una funzione ausiliaria per definire una funzione come List.find?

+0

In Haskell le opportunità di inlining aggiuntive che ottieni facendo questo genere di cose sono un grosso problema. Non so se OCaml è lo stesso. Termini di ricerca: trasformazione argomento statico, trasformazione worker-wrapper –

risposta

5

In questo caso, non cambia molto, perché entrambe le funzioni sono ricorsiva in coda, ma ancora, la risposta alla tua domanda è:

chiamando find richiede passando due argomenti. Per chiamare find_aux è necessario passare un argomento. Passare argomenti non è gratuito: occupa spazio in pila, limitando la massima profondità di ricorsione se la funzione non è ricorsiva in coda e richiede tempo per la configurazione.

È un trade-off: nella versione Core, è necessario assegnare una chiusura per associare il nome f al suo valore permanente (locale). Se la lista è breve, l'allocazione della chiusura può essere più costosa rispetto al passare alcuni argomenti aggiuntivi (specialmente perché la funzione è ricorsiva in coda).

Fondamentalmente, non dovresti preoccuparti. Probabilmente non è necessario in questo caso, e anche quando non è necessario, non fa una grande differenza.

+0

risposta molto concisa ma completa. buono a sapersi –