Haltepunkte im Argument-Passing-Schema von OCaml

8

Heute ging ich durch den Quellcode von Jane Street % Core_kernel Modul und ich stieß auf die Funktion compose :

%Vor%

Ich hätte die Funktion compose folgendermaßen definiert:

%Vor%

Der Grund für die Definition von compose ist wie folgt: "Weil compose eine Funktion ist, die die Funktionen f und g als Argumente akzeptiert und als Ergebnis die Funktion fun x -> f (g x) zurückgibt, haben sie definiert compose so wie sie es getan haben, um dem Compiler mitzuteilen, dass er nach f und g , aber vor x im Argumentübergabeschema einen Haltepunkt einfügen soll. "

Ich habe also zwei Fragen:

  1. Warum brauchen wir Haltepunkte im Argument-Passing-Schema?
  2. Welchen Unterschied würde es machen, wenn wir compose auf die normale Art und Weise definieren würden?

Von Haskell kommend macht diese Konvention für mich keinen Sinn.

    
Aadit M Shah 22.03.2015, 05:55
quelle

2 Antworten

3

Dies ist ein Effizienz-Hack, um die Kosten einer Teilanwendung im erwarteten Anwendungsfall, der im Kommentar angegeben ist, zu vermeiden.

OCaml kompiliert Curry-Funktionen in Fixed-Arity-Konstrukte und verwendet einen Abschluss, um sie bei Bedarf teilweise anzuwenden. Dies bedeutet, dass Aufrufe dieser Art effizient sind - es gibt keine Abschlusskonstruktion, nur einen Funktionsaufruf.

There wird eine Abschlusskonstruktion innerhalb von compose für fun x -> f (g x) sein, aber dies ist effizienter als die partielle Anwendung. Verschlüsse, die durch partielle Anwendung erzeugt werden, durchlaufen einen Wrapper caml_curryN , der vorhanden ist, um sicherzustellen, dass Effekte zum richtigen Zeitpunkt auftreten (wenn dieser Verschnitt teilweise selbst angewendet wird).

Die feste Wahl, die der Compiler wählt, basiert auf einer einfachen syntaktischen Analyse - im Wesentlichen, wie viele Argumente in einer Zeile ohne etwas dazwischen genommen werden. Die Jane St.-Programmierer haben dies verwendet, um die gewünschte Eigenschaft auszuwählen, indem sie () "zwischen" -Argumente injizieren.

Kurz gesagt, let compose f g x = f (g x) ist eine weniger wünschenswerte Definition, da dies dazu führen würde, dass der gemeinsame zweistellige Fall von compose f g eine teurere Teilapplikation wäre.

Natürlich gibt es in der Semantik überhaupt keinen Unterschied.

    
gsg 22.03.2015, 06:43
quelle
2

Es ist erwähnenswert, dass die Kompilierung von partiellen Anwendungen in OCaml verbessert wurde, und dieser Performance-Hack ist nicht mehr notwendig.

    
yzzlr 22.03.2015 23:07
quelle

Tags und Links