Je lis souvent que paresseux n'est pas la même chose que non stricte mais je trouve difficile de comprendre la différence. Ils semblent pour être utilisés de manière interchangeable mais je comprends qu'ils ont des significations différentes. J'apprécierais que l'on m'aide à comprendre la différence.
J'ai quelques questions qui sont éparpillées dans ce post. Je résumerai ces questions à la fin de ce billet. J'ai quelques exemples de snippets, je ne les ai pas testés, je les ai seulement présentés comme des concepts. J'ai ajouté des citations pour vous éviter de les chercher. Peut-être que cela aidera quelqu'un qui se posera la même question plus tard.
Défense non stricte :
Une fonction f est dite stricte si, lorsqu'elle est appliquée à une expression non terminante non terminale, elle ne se termine pas non plus. En d'autres termes, f est stricte si la valeur de f bot est | . Pour la plupart des langages de programmation, toutes les fonctions sont strictes. Mais ce n'est pas le cas en Haskell. Un exemple simple exemple simple, considérons const1, la fonction constante 1, définie par :
const1 x = 1
La valeur de const1 bot en Haskell est 1. D'un point de vue opérationnel, puisque const1 n'a pas "besoin" de la valeur de son argument, il ne tente jamais de de l'évaluer, et donc n'est jamais pris dans un calcul non terminant. nonterminant. Pour cette raison, les fonctions non strictes sont également appelées "fonctions paresseuses". "fonctions paresseuses", et on dit qu'elles évaluent leurs arguments "paresseusement", ou "par besoin".
- Une introduction douce à Haskell : Fonctions
J'aime beaucoup cette définition. Elle semble être la meilleure que j'ai pu trouver pour comprendre le terme "strict". Est-ce que const1 x = 1
paresseux aussi ?
La non-striction signifie que la réduction (le terme mathématique pour évaluation) se fait de l'extérieur vers l'intérieur,
donc si vous avez (a+(b c)) alors vous réduisez d'abord le +, puis vous réduisez l'intérieur (b c).
- Haskell Wiki : Lazy vs non-strict
Le Haskell Wiki m'embrouille vraiment. Je comprends ce qu'ils disent à propos de l'ordre mais je ne vois pas comment (a+(b*c))
serait évalué de manière non stricte s'il s'agissait d'un pass _|_
?
En évaluation non stricte, les arguments d'une fonction ne sont pas évalués sauf s'ils sont effectivement utilisés dans l'évaluation du corps de la fonction.
Sous le codage de Church, l'évaluation paresseuse des opérateurs correspond à l'évaluation non stricte l'évaluation non stricte des fonctions ; pour cette raison, l'évaluation non stricte est souvent qualifiée de "paresseuse". Les expressions booléennes de nombreux langages utilisent une forme d'évaluation non stricte appelée évaluation en court-circuit, dans laquelle l'évaluation revient dès qu'il est possible de déterminer qu'un booléen non ambigu en résultera. booléen non ambigu - par exemple, dans une expression disjonctive où true est rencontré, ou dans une expression conjonctive où false est rencontré, et ainsi de suite. Les expressions conditionnelles utilisent aussi généralement l'évaluation paresseuse, où l'évaluation revient dès qu'une branche non ambiguë non ambiguë.
- Wikipedia : Stratégie d'évaluation
Défense paresseuse :
L'évaluation paresseuse, en revanche, consiste à n'évaluer une expression que lorsque ses résultats sont nécessaires. expression que lorsque ses résultats sont nécessaires (notez le passage de la "réduction" à "évaluation"). Ainsi, lorsque le moteur d'évaluation voit une expression une expression, il construit une structure de données thunk contenant les valeurs nécessaires à l'évaluation de l'expression, ainsi qu'une structure de données thunk. nécessaires à l'évaluation de l'expression, plus un pointeur vers l'expression elle-même. l'expression elle-même. Lorsque le résultat est réellement nécessaire, le moteur d'évaluation appelle l'expression et remplace ensuite le thunk avec le résultat résultat pour référence future. ...
De toute évidence, il y a une forte correspondance entre un thunk et une expression partiellement évaluée. Par conséquent, dans la plupart des cas, les termes "paresseux" et "non-strict" sont des synonymes. Mais pas tout à fait.
- Haskell Wiki : Lazy vs non-strict
Cela semble être une réponse spécifique à Haskell. Je suppose que paresseux signifie des bruits sourds et non stricte signifie une évaluation partielle. Cette comparaison n'est-elle pas trop simplifiée ? Est-ce que paresseux signifie toujours des bruits sourds et non stricte signifie toujours une évaluation partielle.
Dans la théorie des langages de programmation, l'évaluation paresseuse ou le call-by-need 1 est une stratégie d'évaluation qui retarde l'évaluation d'une expression jusqu'à ce que sa valeur soit réellement requise (évaluation non stricte) et également d'éviter les évaluations répétées (partage).
- Wikipédia : Évaluation paresseuse
Exemples d'impératifs
Je sais que la plupart des gens disent d'oublier la programmation impérative lorsqu'on apprend un langage fonctionnel. Cependant, j'aimerais savoir si ceux-ci sont qualifiés de non impératifs, de paresseux, des deux ou d'aucun des deux ? Cela permettrait au moins d'avoir quelque chose de familier.
Court-circuitage
f1() || f2()
C#, Python et autres langages avec "yield" (rendement)
public static IEnumerable Power(int number, int exponent)
{
int counter = 0;
int result = 1;
while (counter++ < exponent)
{
result = result * number;
yield return result;
}
}
Rappels
int f1() { return 1;}
int f2() { return 2;}
int lazy(int (*cb1)(), int (*cb2)() , int x) {
if (x == 0)
return cb1();
else
return cb2();
}
int eager(int e1, int e2, int x) {
if (x == 0)
return e1;
else
return e2;
}
lazy(f1, f2, x);
eager(f1(), f2(), x);
Questions
Je sais que la réponse est juste devant moi avec toutes ces ressources, mais je n'arrive pas à la saisir. Tout semble indiquer que la définition est trop facilement rejetée comme étant implicite ou évidente.
Je sais que j'ai beaucoup de questions. N'hésitez pas à répondre aux questions qui vous semblent pertinentes. J'ai ajouté ces questions pour la discussion.
- Est
const1 x = 1
aussi paresseux ? - Comment l'évaluation de "l'intérieur" peut-elle être non stricte ? Est-ce parce que "inward" permet de réduire les expressions inutiles, comme en
const1 x = 1
? Les réductions semblent correspondre à la définition de la paresse. - Fait paresseux signifie toujours thunks et non stricte signifie toujours évaluation partielle ? S'agit-il d'une simple généralisation ?
- Les concepts impératifs suivants sont-ils paresseux, non stricts, les deux ou aucun ?
- Court-circuitage
- Utilisation du rendement
- Passage de Callbacks pour retarder ou éviter l'exécution
- Est paresseux un sous-ensemble de non stricte ou vice versa, ou sont-ils mutuellement exclusifs. Par exemple, est-il possible d'être non stricte sans être paresseux ou paresseux sans être non stricte ?
- Le manque de rigueur de Haskell est-il dû à la paresse ?
Merci beaucoup !