Lisp commun, 58 caractères
#1=(let((*print-circle* t))(print'(write '#1# :circle t)))
... ou 24 caractères si cela ne vous dérange pas de supposer que la valeur *print-circle*
globale est définie sur T
:
#1=(print '(write '#1#))
La représentation imprimée du code est lue comme une structure cyclique, où #1#
pointe vers la cellule suivante #1=
. Nous citons des programmes pour qu'ils ne soient pas exécutés. Puisque *print-circle*
c'est T, le REPL prend soin d'émettre de telles variables de lecteur lors de l'impression; voici ce que le code ci-dessus imprime et renvoie:
#1=(write '(print '#1#))
Lorsque nous évaluons le code ci-dessus, il imprime:
#1=(print '(write '#1#))
Si vous souhaitez vous en tenir à la valeur par défaut de *print-circle*
, qui est NIL dans une implémentation conforme, vous devrez alors lier temporairement la variable:
#1=(let((*print-circle* t))(print'(write '#1# :circle t)))
À l'intérieur du corps du LET, nous imprimons les choses avec *print-circle*
T. Nous obtenons donc:
#1=(write
'(let ((*print-circle* t))
(print '#1#))
:circle t)
Comme vous pouvez le voir, le nouveau programme ne se lie pas à nouveau *print-circle*
, mais puisque nous utilisons write
, qui est la fonction de bas niveau appelée par print
, nous pouvons passer des arguments supplémentaires tels que :circle
. Le code fonctionne alors comme prévu:
#1=(let ((*print-circle* t))
(print '(write '#1# :circle t)))
Cependant, vous devez exécuter les programmes ci - dessus comme un script, pas à l' intérieur d' un REPL, parce que même si vous imprimez des choses tout en prenant soin des structures circulaires, à la fois write
et print
renvoie également la valeur en cours d' impression; et dans un REPL par défaut, la valeur est également en cours d'impression, mais en dehors du contexte dynamique où *print-circle*
est T.