2012-05-19 10 views
6

"Introduction to Caml" mówiDlaczego wolisz curry do krotki argumentów w OCaml?

Uwaga, w Caml lepiej jest użyć definicji funkcji curry dla funkcji wielu argumentów, a nie krotki.

przy porównywaniu 'a -> 'b -> 'c konwencje powołanie do 'a * 'b -> 'c.

Podczas pracy z SML/NJ przyzwyczaiłem się do używania typów krotek dla wejścia i wyjścia: ('a * 'b) -> ('c * 'd), więc używanie krotek do wyrażania wielu wejść wydaje się symetryczne ze sposobem wyrażania wielu wyników.

Dlaczego zalecane są curry dla deklaracji funkcji OCaml w argumentach krotkowych? Czy jest to po prostu większa elastyczność, która umożliwia wycinanie/częściową ocenę, czy też jest jakaś inna korzyść, wynikająca z szczegółów implementacji kompilatora OCaml?

+2

Wybór curry większości funkcji w świetle Caml i kolejnych wersjach wyjaśniono w raporcie "Eksperyment ZINC: ekonomiczna implementacja języka ML". Jedną rzeczą, którą pamiętam jest to, że przy odpowiednim schemacie oceny (opisanym w raporcie) funkcja curried nie wymaga przydziału, aby można ją było wywołać. http://caml.inria.fr/pub/papers/xleroy-zinc.ps.gz –

+0

@PascalCuoq, podczas gdy krotka musi zostać przydzielona, ​​rozpakowana, a następnie GCed? –

+0

Tak, jeśli funkcja ma być również wywołana z istniejącymi krotkami ('ft'), nie ma możliwości obejścia krótkiej tymczasowej krotki' (x, y) 'do zastosowania' f' to, kiedy to, co masz, to tylko 'x' i' y'. –

Odpowiedz

2

Tak, jest to głównie wygoda notacji i elastyczność w wykonywaniu częściowego zastosowania. Funkcje curried są idiomatyczne w OCaml, a kompilator prawdopodobnie zoptymalizuje je nieco lepiej niż funkcje krotkowane (podczas gdy kompilatory SML zwykle optymalizują pod kątem krotek).

Zalety tuplingu to symetria argumentu/wyniku, o której wspomniałeś (co jest szczególnie przydatne przy komponowaniu funkcji) i być może notacjonalna znajomość (przynajmniej dla osób wywodzących się z niefunkcjonalnego świata).

1

Kilka uwag na temat optymalizacji w OCaml.

W OCaml zauważyłem, że krotki są zawsze przydzielane podczas przekazywania ich jako argumentu. Nawet jeśli przydzielanie w sterty głównej jest szybkie w ocaml, jest to oczywiście dłuższe niż bezczynność. Tak więc za każdym razem, gdy przekazujesz krotkę jako argument, jest trochę czasu na przydzielenie i wypełnienie krotki.

Oczekiwalem, że kompilator ocaml będzie optymalizował przypadki, w których nie jest konieczne budowanie krotki. Na przykład, gdy wbudujesz wywoływaną funkcję, możesz używać tylko składników krotki, a nie samej krotki. Tak więc krotka może być po prostu ignorowana. Niestety w tym przypadku OCaml nie usuwa niepotrzebnej krotki i nadal wykonuje alokację. Z tego powodu może nie być dobrym pomysłem użycie krotek w krytycznych sekcjach kodu.

+0

Myślę, że to już nie jest prawda. ["OCaml jest mądrzejszy, niż myślałem"] (https://blogs.janestreet.com/ocaml-is-smarter-than-i-thought/) mówi: "uniemożliwiłem wpisywanie, ale wciąż nie było przydziału! Dlaczego? Cóż, okazuje się, że OCaml może zoptymalizować funkcję krotki, aby uzyskać elementy krotki przekazywane przez rejestry, co jest dokładnie tym, co się wydarzyło i ponownie, kompilator zdał sobie sprawę, że nie było potrzeby przydzielania. " –

5

Myślę, że wiele z nich to konwencja - standardowe funkcje biblioteki w OCaml są wybierane, podczas gdy w standardowym ML zazwyczaj nie są one wyjątkiem niektórych funkcji wyższego rzędu. Jednakże istnieje jedna różnica wypalana w tym języku: operatory (na przykład (*)) są konwertowane w OCaml (na przykład int -> int -> int); podczas gdy są one niespokojne w Standardzie ML (np. op* może być (int * int) -> int). Z tego powodu wbudowane funkcje wyższego rzędu (np. Fold) również przyjmują funkcję, która jest przekształcana w OCaml i nieskrócona w standardzie ML; Oznacza to, że aby Twoja funkcja działała z tym, musisz postępować zgodnie z odpowiednią konwencją, a to z tego wynika.

+1

Dobra uwaga. Jest jeszcze jeden przypadek, w którym wybór jest zapiekany w: konstruktorach typów danych. W SML są one doczepione, w Haskell są curry. O dziwo, w OCaml są one doczepione, co jest pewnym niedopasowaniem z resztą języka. –

+1

Głębszym znaczeniem dławionych konstruktorów typów danych jest to, że krotka jest anonimowym konstruktorem danych specjalnych. –