Lisp común, 58 caracteres
#1=(let((*print-circle* t))(print'(write '#1# :circle t)))
... o 24 caracteres si no le importa suponer que *print-circle*
está configurado globalmente en T
:
#1=(print '(write '#1#))
La representación impresa del código se lee como una estructura cíclica, donde #1#
apunta de nuevo a la siguiente celda de contras #1=
. Cotizamos programas para que no se ejecuten. Como *print-circle*
es T, el REPL se encarga de emitir tales variables de lectura durante la impresión; esto es lo que imprime el código anterior y devuelve:
#1=(write '(print '#1#))
Cuando evaluamos el código anterior, imprime:
#1=(print '(write '#1#))
Si desea mantener el valor predeterminado para *print-circle*
, que es NIL en una implementación conforme, deberá volver a vincular la variable temporalmente:
#1=(let((*print-circle* t))(print'(write '#1# :circle t)))
Dentro del cuerpo del LET, imprimimos cosas con *print-circle*
ser T. Entonces obtenemos:
#1=(write
'(let ((*print-circle* t))
(print '#1#))
:circle t)
Como puede ver, el nuevo programa no se vuelve a unir *print-circle*
, pero como estamos utilizando write
, que es la función de bajo nivel llamada por print
, podemos pasar argumentos adicionales como :circle
. El código entonces funciona como se esperaba:
#1=(let ((*print-circle* t))
(print '(write '#1# :circle t)))
Sin embargo, debe ejecutar los programas anteriores como un script, no dentro de un REPL, porque a pesar de que imprime las cosas mientras se ocupa de las estructuras circulares, ambas write
y print
también devuelve el valor que se está imprimiendo; y en un REPL predeterminado, el valor también se imprime, pero fuera del contexto dinámico donde *print-circle*
está T.