Lisp comune, 58 caratteri
#1=(let((*print-circle* t))(print'(write '#1# :circle t)))
... o 24 caratteri se non ti dispiace supporre che *print-circle*
sia globalmente impostato su T
:
#1=(print '(write '#1#))
La rappresentazione stampata del codice viene letta come una struttura ciclica, in cui #1#
punta di nuovo alla cella contro #1=
. Citiamo i programmi in modo che non vengano eseguiti. Poiché *print-circle*
è T, REPL si occupa di emettere tali variabili di lettore durante la stampa; questo è ciò che stampa il codice sopra e restituisce:
#1=(write '(print '#1#))
Quando valutiamo il codice sopra, stampa:
#1=(print '(write '#1#))
Se si desidera mantenere il valore predefinito per *print-circle*
, che è NIL in un'implementazione conforme, sarà necessario ricollegare temporaneamente la variabile:
#1=(let((*print-circle* t))(print'(write '#1# :circle t)))
All'interno del corpo della LET, stampiamo le cose con l' *print-circle*
essere T. Quindi otteniamo:
#1=(write
'(let ((*print-circle* t))
(print '#1#))
:circle t)
Come puoi vedere, il nuovo programma non si ricollega *print-circle*
, ma poiché stiamo usando write
, che è la funzione di basso livello chiamata da print
, possiamo passare argomenti aggiuntivi come :circle
. Il codice funziona quindi come previsto:
#1=(let ((*print-circle* t))
(print '(write '#1# :circle t)))
Tuttavia, è necessario eseguire i programmi sopra indicati come script, non all'interno di un REPL, perché anche se si stampano cose mentre si prendono cura delle strutture circolari, entrambi write
e print
restituiscono anche il valore in fase di stampa; e in una REPL predefinita, viene anche stampato il valore, ma al di fuori del contesto dinamico in cui *print-circle*
è T.