Können Sie die verzögerte Auswertung in R-Funktionsoperatoren deutlicher erklären?

Wenn ich eine Funktion wie folgt erstelle:

what_is_love <- function(f) {
  function(...) {
    cat('f is', f, '\n')
  }
}

Und nenne es mitlapply: funs <- lapply(c('love', 'cherry'), what_is_love)

Ich erhalte eine unerwartete Ausgabe:

> funs[[1]]()
f is cherry
> funs[[2]]()
f is cherry

Beachten Sie jedoch, dass dies nicht der Fall ist, wenn Sie @ nicht verwendelapply:

> f1 <- what_is_love('love')
> f2 <- what_is_love('cherry')
> f1()
f is love
> f2()
f is cherry

Was gibt

Ich weiß dasfuns <- lapply(c('love', 'cherry'), what_is_love) kann vollständiger ausgeschrieben werden:

params <- c('love', 'cherry')
out <- vector('list', length(params))
for (i in seq_along(params)) {
  out[[i]] <- what_is_love(params[[i]])
}
out

Aber beim Durchsuchen stelle ich fest, dass beide Funktionen eine eigene Umgebung haben:

Browse[1]> out[[1]]
function(...) {
    cat('f is', f, '\n')
  }
<environment: 0x109508478>
Browse[1]> out[[2]]
function(...) {
    cat('f is', f, '\n')
  }
<environment: 0x1094ff750>

Aber in jeder dieser Umgebungen,f ist dasselbe..

Browse[1]> environment(out[[1]])$f
[1] "cherry"
Browse[1]> environment(out[[2]])$f
[1] "cherry"

Ich weiß, die Antwort ist "faule Bewertung", aber ich suche ein bisschen mehr Tiefe ... wie funktioniertf wird in beiden Umgebungen neu zugewiesen? Woher kommtf komme aus? Wie funktioniert R Lazy Evaluation in diesem Beispiel unter der Haube?

-

BEARBEITEN Ich bin mir bewusst überdie andere Frage auf Lazy Evaluation und Functionals, aber es heißt nur, die Antwort ist "Lazy Evaluation", ohne zu erklären, wie die Lazy Evaluation tatsächlich funktioniert. Ich suche mehr Tiefe.