2017-03-09 7 views
6

Ich versuche zu verstehen, wie faul Bewertung in R funktioniert. Gilt es nur für die Auswertung von Funktionsargumenten? Weil ich das verstehe, z.B.Understanding faule Bewertung in R

f <- function(x = x, y = x*2) { 
    c(x, y) 
} 

f(2) 
[1] 2 4 

Aber in anderen Sprachen, z.B. Haskell, faule Auswertung bedeutet, dass ein Funktionsaufruf nur ausgewertet wird, wenn er jemals tatsächlich verwendet wird. So würde ich erwarten, so etwas wie dies in einem Augenblick laufen:

g <- function(x) { 
    y <- sample(1:100000000) 
    return(x) 
} 

g(4) 

Aber es wertet deutlich den sample Aufruf obwohl ihr Ergebnis gewöhnt nicht.

Konnte jemand genau erklären, wie das funktioniert, oder mich in die Richtung zeigen, wo es im Detail erklärt wird?

ähnliche Fragen:

Question with similar wording, but different problem

Antwort

7

Wie Sie bereits herausgefunden haben, ist R nicht faul Auswertung im allgemeinen Sinne verwendet werden. Aber R tut bietet diese Funktionalität, wenn Sie es brauchen, durch die Funktion delayedAssign() wie unten dargestellt:

> system.time(y <- sample(1E8)) 
    user system elapsed 
    7.636 0.128 7.766 
> system.time(length(y)) 
    user system elapsed 
     0  0  0 
system.time(delayedAssign("x", sample(1E8))) 
    user system elapsed 
    0.000 0.000 0.001 
> system.time(length(x)) 
    user system elapsed 
    7.680 0.096 7.777 

Wie Sie sehen können, ist y sofort ausgewertet, so zu bestimmen, die Länge von y überhaupt keine Zeit in Anspruch nimmt. x auf der anderen Seite, wird nicht ausgewertet, wenn es erstellt wird, nur ein Versprechen zur Auswertung x wird von delayedAssign() zurückgegeben, und nur wenn wir tatsächlich einen Wert von x benötigen, in diesem Fall zur Bestimmung seiner Länge wird x ausgewertet.

Es spielt keine Rolle, ob der Ausdruck in einer Funktion platziert oder in der globalen Umgebung ausgeführt wird, also fügt die Kapselung des Ausdrucks innerhalb einer Funktion, die Sie in Ihrem Beispiel gemacht haben, nichts hinzu, weshalb ich ausgeschlossen habe es. Aber wenn Sie sicher sein wollen, versuchen Sie:

a.f <- function(z) { delayedAssign("x", sample(1E8)); return(z+1) } 
system.time(a.f(0)) 
    user system elapsed 
     0  0  0 
+0

Ich beziehe mich auf Hadley Wickham Buch, in dem er erwähnt: „standardmäßig R Funktionsargumente faul sind, werden sie nur dann ausgewertet, verwendet werden, wenn tatsächlich“. Stimmt das nicht mit den neuesten Versionen? – Sarang

+0

Beachten Sie, dass die Frage diesen Satz "Gilt es nur für die Auswertung von Funktionsargumenten?" Meine Antwort widerspricht Wickhams Aussage nicht. –

Verwandte Themen