Common Lisp, 58 znaków
#1=(let((*print-circle* t))(print'(write '#1# :circle t)))
... lub 24 znaki, jeśli nie masz nic przeciwko zakładaniu *print-circle*
globalnie jest ustawione na T
:
#1=(print '(write '#1#))
Wydrukowana reprezentacja kodu jest odczytywana jako struktura cykliczna, gdzie #1#
wskazuje na następną komórkę przeciw #1=
. Przytaczamy programy, aby nie były wykonywane. Ponieważ *print-circle*
jest to T, REPL stara się emitować takie zmienne czytnika podczas drukowania; oto, co drukuje powyższy kod i zwraca:
#1=(write '(print '#1#))
Kiedy oceniamy powyższy kod, drukuje:
#1=(print '(write '#1#))
Jeśli chcesz pozostać przy wartości domyślnej dla *print-circle*
NIL w implementacji zgodnej, musisz tymczasowo ponownie powiązać zmienną:
#1=(let((*print-circle* t))(print'(write '#1# :circle t)))
W treści LET drukujemy różne rzeczy *print-circle*
jako T. Więc otrzymujemy:
#1=(write
'(let ((*print-circle* t))
(print '#1#))
:circle t)
Jak widać, nowy program nie łączy się ponownie *print-circle*
, ale ponieważ używamy write
, czyli wywoływanej funkcji niskiego poziomu print
, możemy przekazać dodatkowe argumenty, takie jak:circle
. Kod działa wtedy zgodnie z oczekiwaniami:
#1=(let ((*print-circle* t))
(print '(write '#1# :circle t)))
Jednak trzeba wykonać powyższe programy jako skrypt, a nie wewnątrz REPL, ponieważ nawet jeśli wydrukować rzeczy dbając kolistych struktur, zarówno write
a print
także zwraca wartość drukowanego; i w domyślnej REPL wartość jest również drukowana, ale poza kontekstem dynamicznym, gdzie *print-circle*
jest T.