J'ai trouvé cette déclaration tout en étudiant Fonctionnel Réactif de Programmation, de "Branchement d'un Espace de Fuite avec une Flèche" par Hai Liu et Paul Hudak ( page 5) :
Suppose we wish to define a function that repeats its argument indefinitely: repeat x = x : repeat x or, in lambdas: repeat = λx → x : repeat x This requires O(n) space. But we can achieve O(1) space by writing instead: repeat = λx → let xs = x : xs in xs
La différence ici, elle semble petite, mais extrêmement invite l'optimisation de l'espace. Pourquoi et comment ça se passe ? La meilleure proposition que j'ai faite est d'évaluer à la main:
r = \x -> x: r x
r 3
-> 3: r 3
-> 3: 3: 3: ........
-> [3,3,3,......]
Comme ci-dessus, nous aurons besoin de créer une infinité de nouvelles thunks de ces récursivité. Ensuite, j'essaie d'évaluer la seconde:
r = \x -> let xs = x:xs in xs
r 3
-> let xs = 3:xs in xs
-> xs, according to the definition above:
-> 3:xs, where xs = 3:xs
-> 3:xs:xs, where xs = 3:xs
Dans la deuxième forme de l' xs
s'affiche et peut être partagée entre tous les endroits qu'il se produise, donc je suppose que c'est pourquoi, nous ne pouvons exiger O(1)
espaces plutôt que d' O(n)
. Mais je ne suis pas sûr de savoir si j'ai raison ou pas.
BTW: Le mot-clé "partagé" vient de la même document de la page 4:
Le problème ici est que le standard d'appel-par-besoin de règles d'évaluation sont incapables de reconnaître que la fonction:
f = λdt → integralC (1 + dt) (f dt)
est le même que:
f = λdt → let x = integralC (1 + dt) x in x
L'ancienne définition de causes travailler à être répétée dans l'appel récursif pour f, alors que dans le second cas, le calcul est partagé.