Je travaille actuellement à travers SICP en utilisant Guile comme langue principale pour les exercices. J'ai trouvé un comportement étrange lors de la mise en place des exercices au chapitre 3.5. J'ai reproduit ce comportement en utilisant Guile 1.4, Guile 1.8.6 et Guile 1.8.7 sur une variété de plateformes et je suis certain qu'il n'est pas spécifique à ma configuration.Problème avec la définition circulaire dans le schéma
Ce code fonctionne très bien (et calcule e):
(define y (integral (delay dy) 1 0.001))
(define dy (stream-map (lambda (x) x) y))
(stream-ref y 1000)
Le code suivant devrait donner un résultat identique:
(define (solve f y0 dt)
(define y (integral (delay dy) y0 dt))
(define dy (stream-map f y))
y)
(stream-ref (solve (lambda (x) x) 1 0.001) 1000)
Mais il donne le message d'erreur:
standard input:7:14: While evaluating arguments to stream-map in expression (stream-map f y):
standard input:7:14: Unbound variable:
y ABORT: (unbound-variable)
Ainsi, lorsqu'ils sont intégrés dans une définition de procédure, le y ...) ne fonctionne pas, alors qu'en dehors de la procédure dans l'environnement global au REPL cela fonctionne bien.
Qu'est-ce que je fais mal ici? Je peux également afficher le code auxiliaire (c'est-à-dire les définitions de l'intégrale, de la carte de flux, etc.) si nécessaire. À l'exception du code dépendant du système pour contre-flux, ils sont tous dans le livre. Ma propre mise en œuvre de contre-courant pour Guile est la suivante:
(define-macro (cons-stream a b)
`(cons ,a (delay ,b)))
Je me souviens d'avertissements sévères de la part d'un instructeur du genre NEVER USE INTERNE DEFINE, alors peut-être que cela cause le problème. –
Selon R5RS chapitre 5.2: "Ils [définitions] sont valables uniquement au niveau supérieur d'un et au début d'un ." Donc, selon la norme linguistique, le code que j'ai posté est autorisé. Encore plus: Au chapitre 5.2.2, ils donnent explicitement un exemple de l'équivalence syntaxique entre letrec et internal defined. Cela dit, la version syntaxiquement équivalente du code ci-dessus utilisant letrec résultera également dans le même message d'erreur. Le seul moyen que j'ai trouvé jusqu'ici pour que le code fonctionne correctement est de définir y et dy dans l'environnement global du REPL. –
user8472