2012-05-19 9 views
6

"Introduction to Caml" dicePerché preferire la conversione in tuple in OCaml?

nota, in Caml è meglio usare definizioni di funzioni al curry per le funzioni a più argomenti, non tuple.

quando si confrontano le convenzioni di chiamata 'a -> 'b -> 'c con 'a * 'b -> 'c.

Quando si lavora con SML/NJ mi sono abituato usando tipi tuple sia per l'input e l'output: ('a * 'b) -> ('c * 'd) così usando tuple esprimere più ingressi sembra simmetrica con il modo esprimo uscite multiple.

Perché è consigliabile il currying per le dichiarazioni di funzione OCaml rispetto agli argomenti di tupla? È solo la maggiore flessibilità che deriva dal permettere la valutazione curry/parziale, o c'è qualche altro vantaggio che deriva dai dettagli di implementazione del compilatore OCaml?

+2

La scelta di eseguire la maggior parte delle funzioni in modalità Caml-light e versioni successive è spiegata nel rapporto "L'esperimento ZINC: un'implementazione economica del linguaggio ML". Una cosa che ricordo è che con lo schema di valutazione appropriato (descritto nel report), una funzione al curry non richiede allocazione per essere chiamata. http://caml.inria.fr/pub/papers/xleroy-zinc.ps.gz –

+0

@PascalCuoq, mentre una tupla deve essere allocata, decompressa e poi GCed? –

+0

Sì, se la funzione deve essere chiamata anche con tuple preesistenti ('ft'), non c'è modo di aggirare il fatto che una tuple temporanea di breve durata' (x, y) 'deve essere allocata per applicare' f' a quando ciò che si ha è solo 'x' e' y'. –

risposta

2

Sì, è principalmente la comodità notazionale e la flessibilità a fare un'applicazione parziale. Le funzioni al curry sono idiomatiche in OCaml e il compilatore è in grado di ottimizzarle un po 'meglio delle funzioni tuplate (mentre i compilatori SML tipicamente ottimizzano per le tuple).

I pro del tupling sono la simmetria argomento/risultato che si menziona (che è particolarmente utile quando si compongono le funzioni) e forse la familiarità notazionale (almeno per le persone che provengono dal mondo non funzionale).

1

Alcuni commenti sull'ottimizzazione in OCaml.

In OCaml, ho notato che le tuple sono sempre assegnate quando le passano come argomento. Anche se l'allocazione nell'heap primario è veloce in ocaml, è ovviamente più lungo del non fare nulla. Così ogni volta che passi una tupla come argomento, c'è un po 'di tempo dedicato all'assegnazione e al riempimento della tupla.

Mi aspettavo che il compilatore ocaml ottimizzasse i casi in cui non è necessario costruire la tupla. Ad esempio, quando si esegue la funzione chiamata in linea, è possibile utilizzare solo i componenti della tupla e non la stessa tupla. Quindi la tupla potrebbe essere ignorata. Sfortunatamente in questo caso OCaml non rimuove la tupla inutile e continua a eseguire l'allocazione. Per questo motivo, potrebbe non essere una buona idea usare le tuple nelle sezioni critiche del codice.

+0

Penso che questo non sia più vero. ["OCaml è più intelligente di quanto pensassi"] (https://blogs.janestreet.com/ocaml-is-smarter-than-i-thought/) dice "Avevo impedito l'inlining, ma non c'era ancora alcuna allocazione! Perché, a quanto pare, OCaml può ottimizzare una funzione tuple per far passare gli elementi della tupla attraverso i registri, che è esattamente quello che è successo e, ancora una volta, il compilatore si è reso conto che non era necessaria alcuna allocazione. " –

5

Penso che molte siano convenzionali - le funzioni di libreria standard in OCaml sono al curry, mentre in Standard ML in genere non sono ad eccezione di alcune funzioni di ordine superiore. Tuttavia, c'è una differenza nella lingua: gli operatori (ad esempio (*)) sono sottoposti a trattamento di routine in OCaml (ad esempio int -> int -> int); mentre non sono corretti nella norma ML (ad esempio op* può essere (int * int) -> int). Per questo motivo, le funzioni di ordine superiore integrate (ad esempio, piega) assumono anche una funzione che viene curried in OCaml e non affrettata in Standard ML; questo significa che per far funzionare la tua funzione, devi seguire la rispettiva convenzione, e da lì segue.

+1

Buon punto. C'è un'altra istanza in cui viene eseguita la scelta in: costruttori di datatype. In SML sono tupled, in Haskell sono al curry. Stranamente, in OCaml sono tuplati, il che è un po 'di discrepanza con il resto della lingua. –

+1

Il significato più profondo dietro il fatto che i costruttori di datatype siano tupletti è che una tupla è un costruttore di dati anonimi di casi speciali. –