2017-03-09 1 views
6

J'essaie de comprendre à quel point l'évaluation paresseuse dans R fonctionne. Cela s'applique-t-il seulement à l'évaluation des arguments de fonction? Parce que je comprends, par ex.Comprendre l'évaluation paresseuse dans R

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

f(2) 
[1] 2 4 

Mais dans d'autres langages, par ex. Haskell, évaluation paresseuse signifie qu'un appel de fonction n'est évalué que s'il est réellement utilisé. Donc, je me attends quelque chose comme ça à courir en un instant:

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

g(4) 

Mais il évalue clairement l'appel sample même si le résultat ne soit pas utilisé.

Est-ce que quelqu'un pourrait expliquer exactement comment cela fonctionne, ou me diriger dans la direction de l'endroit où il est expliqué en détail?

des questions similaires:

Question with similar wording, but different problem

Répondre

7

Comme vous l'avez déjà découvert, R n'utilise pas l'évaluation paresseuse dans le sens général. Mais R ne fournit cette fonctionnalité, si vous en avez besoin, par la fonction delayedAssign() comme indiqué ci-dessous:

> 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 

Comme vous pouvez le voir, y est évaluée immédiatement, afin de déterminer la longueur de y ne prend pas de temps. D'autre part, n'est pas évalué quand il est créé, seulement une promesse d'évaluer x est retournée par delayedAssign(), et seulement quand nous avons réellement besoin d'une valeur de x, dans ce cas pour déterminer sa longueur, x est évaluée. Cela n'a pas d'importance si l'expression est placée dans une fonction ou exécutée dans l'environnement global, donc l'encapsulation de l'expression dans une fonction que vous avez faite dans votre exemple n'ajoute vraiment rien, c'est pourquoi j'ai exclu il. Mais si vous voulez être sûr, essayez:

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

Je me réfère au livre de Hadley Wickham, où il mentionne: « Par défaut, les arguments de la fonction R sont paresseux, ils ne sont évaluées, si elles sont utilisées en fait ». N'est-ce pas vrai avec les dernières versions alors? – Sarang

+0

Notez que la question comprenait cette phrase "Est-ce que cela s'applique uniquement à l'évaluation des arguments de fonction?" Ma réponse ne contredit pas la déclaration de Wickham. –