En Common Lisp, si je veux deux fonctions à partager l'état, j'exécuterait un let sur lambda comme suit:let-over-lambda dans le régime?
(let ((state 1))
(defun inc-state()
(incf state))
(defun print-state()
(format t "~a~%" state))
Ces fonctions ne sont pas locales au let
- ce sont des fonctions globales qui maintiennent un référence à un état partagé variable, qui elle-même n'est pas visible de l'extérieur. Par exemple, je pouvais faire ce qui suit ailleurs dans mon code:
(print-state) => 1
(inc-state) => 2
(print-state) => 2
Dans le schéma, cependant, une telle construction déclare fonctions locales, qui ne sont pas visibles de l'extérieur:
(let ((state 1))
(define (print-state)
(print state))
(print-state)) => 1
(print-state) => error, no such variable print-state
La seule comme je peux penser pour réaliser ce genre de fonctionnalité (en dehors de l'utilisation de globals non exportés à l'intérieur d'un module), serait quelque chose comme ceci:
(define print-state #f)
(define inc-state #f)
(let ((state 1))
(set! print-state (lambda() (print state)))
(set! inc-state (lambda() (inc! state))))
Existe-t-il un moyen dans Scheme d'écrire la forme let-over-lambda sans avoir recours à de telles solutions de contournement? Ou aurais-je besoin d'écrire une macro pour envelopper cette laideur? (Par ailleurs, je connais environ letrec
, et ce n'est pas une solution à ce problème.)
Incidemment, j'utilise Chicken Scheme, mais ma question devrait être pertinente pour tous les schémas.
Merci. 'define-values' est moins laid que ma solution. Je vais probablement écrire une macro pour l'envelopper quand même. –
'define-values' est spécifié dans la section 5.3.3 de R7RS. –