関数型言語の世界はLispの世界から多くを引き継いでいるけど、
Lispのprint関数はそういうのに対する配慮が厚い。

Common Lispの場合は、
・*print-circle*がnil以外で、再帰のチェックをして、
#n=, #n#を使って、再帰構造を再構築可能な印字表現を出力する。
;;; 確か共有構造再現の処理もやったはず。
・*print-level*, *print-length*で深さ、長さの上限指定

環境のdump/restoreを昔からやっていたからだと思う。
*print-readably*は、read可能な印字表現の強制を行う。

シリアライゼーション考えると、
まともな言語/ライブラリは当然持っていていい機能だと思う。