Czytam książkę Hadley Wickhams o Github, w szczególności this part on lazy evaluation. Podaje on przykład konsekwencji leniwej oceny w części z funkcjami add/adders
. Zacytuję że nieco:Wyjaśnij leniwe zdanie oceny
Ten [leniwa ewaluacja] jest ważne przy tworzeniu zamknięć z lapply lub pętlę:
add <- function(x) { function(y) x + y } adders <- lapply(1:10, add) adders[[1]](10) adders[[10]](10)
x jest leniwie oceniany po raz pierwszy, że nazywasz jeden z sumatora Funkcje. W tym momencie pętla jest kompletna, a końcowa wartość x wynosi 10. Dlatego wszystkie funkcje sumatora dodają 10 na ich wejście , prawdopodobnie nie to, co chciałeś! Ręczne wymuszenie poprawki oceny problem:
add <- function(x) { force(x) function(y) x + y } adders2 <- lapply(1:10, add) adders2[[1]](10) adders2[[10]](10)
I nie wydają się zrozumieć ten kawałek, a wyjaśnienie jest minimalne. Czy ktoś mógłby rozwinąć ten konkretny przykład i wyjaśnić, co się tam dzieje? Jestem szczególnie zaskoczony zdaniem "w tym momencie pętla jest kompletna, a ostateczna wartość x wynosi 10". Jaka pętla? Jaką ostateczną wartość, gdzie? Muszę być czymś prostym, którego mi brakuje, ale po prostu tego nie widzę. Z góry dziękuję.
Należy zauważyć, że odpowiedź na to pytanie nie zmieniło jak R 3.2.0, patrz poniżej moją odpowiedź. – jhin
Uzupełnienie komentarza @ jhina: Podczas gdy 'lapply()' zmieniło się w ostatnim R, funkcja 'purrr :: map()', która ma być używana wszędzie tam, gdzie jest 'lapply()', nadal zachowuje się jak stary ' lapply() "w stosunku do wspólnych środowisk zamknięć. Nie liczyłbym jednak na ten "anachronizm" "purrr :: map()", który zostanie prawdopodobnie usunięty w przyszłych wersjach. – egnha
@jhin Właściwie, tutorial hadley'a jest zbudowany bezpośrednio z github, więc czytanie go po R 3.2.0 jest teraz dość dziwne, ponieważ to wydanie stworzyło całą sekcję o leniwej ocenie w tym tutorialowym sporze: nie ma więcej różnicy z 'adders' i 'wyjścia adders2'! –