Common Lisp, 58 символов
#1=(let((*print-circle* t))(print'(write '#1# :circle t)))
... или 24 символа, если вы не возражаете, предполагая, *print-circle*
что глобально установлено T
:
#1=(print '(write '#1#))
Печатное представление кода читается как циклическая структура, где #1#
указатель на обратную ячейку минует следующую #1=
. Мы цитируем программы так, чтобы они не выполнялись. Поскольку *print-circle*
это T, REPL заботится о том, чтобы выдавать такие переменные считывателя во время печати; это то, что печатает и возвращает приведенный выше код:
#1=(write '(print '#1#))
Когда мы оцениваем приведенный выше код, он печатает:
#1=(print '(write '#1#))
Если вы хотите придерживаться значения по умолчанию для *print-circle*
- NIL в соответствующей реализации, то вам придется временно перепривязать переменную:
#1=(let((*print-circle* t))(print'(write '#1# :circle t)))
Внутри тела LET мы печатаем вещи *print-circle*
как T. Таким образом, мы получаем:
#1=(write
'(let ((*print-circle* t))
(print '#1#))
:circle t)
Как видите, новая программа не перепривязывается *print-circle*
, но, поскольку мы используем write
функцию низкоуровневого вызова print
, мы можем передавать дополнительные аргументы, такие как :circle
. Затем код работает как положено:
#1=(let ((*print-circle* t))
(print '(write '#1# :circle t)))
Тем не менее, вы должны выполнить вышеупомянутые программы в качестве сценария, а не внутри РЕПЛ, потому что даже если вы печатаете вещи, заботясь о кольцевых структур, так write
и print
также возвращает значение , которое печатается; и в REPL по умолчанию значение также печатается, но вне динамического контекста, где *print-circle*
T.