But the result I see is
(#1=(2) #1#)((2) (2))
Why are the two printed representations of toto different?
I think you are seeing: 1) the side-effect result of `prin1' printing,
followed by 2) the returned value, printed normally. (#1=(2) #1#) is the
former; ((2) (2)) is the latter.
But it is the output of (prin1 (list toto toto)), isn't it?
I'm not sure what you mean (by "it" and by "the output", for instance).
During the invocation of `prin1', the `print-circle' binding is in effect,
so (#1=(2) #1#) is what is printed (by the side effect of `prin1').
The binding is finished after the expression evaluation, and that is when
the command loop prints the value that is returned by the expression.
Printing of this value is thus done using the default value of
`print-circle', nil, so you see ((2) (2)).