Lisp comum, 58 caracteres
#1=(let((*print-circle* t))(print'(write '#1# :circle t)))
... ou 24 caracteres, se você não se importa em assumir que *print-circle*
está globalmente definido como T
:
#1=(print '(write '#1#))
A representação impressa do código é lida como uma estrutura cíclica, onde #1#
aponta para a célula de contras a seguir #1=
. Citamos programas para que não sejam executados. Como *print-circle*
é T, o REPL cuida de emitir essas variáveis do leitor durante a impressão; é isso que o código acima imprime e retorna:
#1=(write '(print '#1#))
Quando avaliamos o código acima, ele imprime:
#1=(print '(write '#1#))
Se você deseja manter o valor padrão para *print-circle*
, que é NIL em uma implementação em conformidade, será necessário religar a variável temporariamente:
#1=(let((*print-circle* t))(print'(write '#1# :circle t)))
Dentro do corpo do LET, imprimimos as coisas como *print-circle*
sendo T. Portanto, obtemos:
#1=(write
'(let ((*print-circle* t))
(print '#1#))
:circle t)
Como você pode ver, o novo programa não é religado *print-circle*
, mas como estamos usando write
, que é a função de baixo nível chamada por print
, podemos passar argumentos adicionais, como :circle
. O código funciona como esperado:
#1=(let ((*print-circle* t))
(print '(write '#1# :circle t)))
No entanto, você precisa executar os programas acima como um script, não dentro de um REPL, porque, embora você imprima coisas enquanto cuida de estruturas circulares, ambos write
e print
também retorna o valor que está sendo impresso; e em um REPL padrão, o valor também está sendo impresso, mas fora do contexto dinâmico em que *print-circle*
é T.